diff --git a/.env.dev b/.env.dev
index 39f64d03fd5aa335668f7c58e936e3d7dfcc663d..40774610bb72e98787d8ee831551c4a64148fda6 100644
--- a/.env.dev
+++ b/.env.dev
@@ -12,6 +12,7 @@ MUSIC_DIRECTORY_PATH=/music
 BROWSABLE_API_ENABLED=True
 FORWARDED_PROTO=http
 LDAP_ENABLED=False
+FUNKWHALE_SPA_HTML_ROOT=http://nginx/front/
 
 # Uncomment this if you're using traefik/https
 # FORCE_HTTPS_URLS=True
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bbe1bd02f201ab915520d5125316084bed48ad16..8bab09fdbf630fe6fcc822d10c98ebfd93ee6452 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -114,7 +114,7 @@ black:
   before_script:
     - pip install black
   script:
-    - black --exclude "/(\.git|\.hg|\.mypy_cache|\.tox|\.venv|_build|buck-out|build|dist|migrations)/" --check --diff api/
+    - black --check --diff api/
 
 flake8:
   image: python:3.6
@@ -281,6 +281,7 @@ build_api:
     paths:
       - api
   script:
+    - rm -rf api/tests
     - (if [ "$CI_COMMIT_REF_NAME" == "develop" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi);
     - chmod -R 750 api
     - echo Done!
diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md
index aa8893527488c342268623718bca5189b30102e7..1570482a6645ac0f3db22588b37b55424ca8d9e5 100644
--- a/.gitlab/issue_templates/Bug.md
+++ b/.gitlab/issue_templates/Bug.md
@@ -1,6 +1,9 @@
 <!--
 Hi there! You are reporting a bug on this project, and we want to thank you!
 
+If it's the first time you post here, please take a moment to read our Code of Conduct
+(https://funkwhale.audio/code-of-conduct/) and ensure your issue respect our guidelines.
+
 To ensure your bug report is as useful as possible, please try to stick
 to the following structure. You can leave the parts text between `<!- ->`
 markers untouched, they won't be displayed in your final message.
diff --git a/.gitlab/issue_templates/Feature request.md b/.gitlab/issue_templates/Feature request.md
index 404f9c9defa4118bbf445ce899f08ce7066e96ce..355f9a19c8e0b83fc8fbafa9adff5d6f49a191c4 100644
--- a/.gitlab/issue_templates/Feature request.md	
+++ b/.gitlab/issue_templates/Feature request.md	
@@ -1,6 +1,10 @@
 <!--
 Hi there! You are about to share feature request or an idea, and we want to thank you!
 
+
+If it's the first time you post here, please take a moment to read our Code of Conduct
+(https://funkwhale.audio/code-of-conduct/) and ensure your issue respect our guidelines.
+
 To ensure we can deal with your idea or request, please try to stick
 to the following structure. You can leave the parts text between `<!- ->`
 markers untouched, they won't be displayed in your final message.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 2beb658c2c30bd2c1d2d13f49c9573faf6d2148a..2722502c094c3982ea988b0f987544fc25e1a0de 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -172,6 +172,10 @@ and metadata.
 Launch all services
 ^^^^^^^^^^^^^^^^^^^
 
+Before the first Funkwhale launch, it is required to run this::
+
+    docker-compose -f dev.yml run --rm front yarn run i18n-compile
+
 Then you can run everything with::
 
     docker-compose -f dev.yml up front api nginx celeryworker
@@ -276,7 +280,8 @@ When working on federation with traefik, ensure you have this in your ``env``::
     EXTERNAL_REQUESTS_VERIFY_SSL=false
     # this ensure you don't have incorrect urls pointing to http resources
     FUNKWHALE_PROTOCOL=https
-
+    # Disable host ports binding for the nginx container, as traefik is serving everything
+    NGINX_PORTS_MAPPING=80
 
 Typical workflow for a contribution
 -----------------------------------
@@ -513,13 +518,15 @@ It's possible to nest multiple component parts to reach a higher level of detail
 - ``Content/*/Form.Help text``
 
 Collecting translatable strings
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 If you want to ensure your translatable strings are correctly marked for translation,
 you can try to extract them.
 
 Extraction is done by calling ``yarn run i18n-extract``, which
-will pull all the strings from source files and put them in a PO file.
+will pull all the strings from source files and put them in a PO files.
+
+You can then inspect the PO files to ensure everything is fine (but don't commit them, it's not needed).
 
 Contributing to the API
 -----------------------
diff --git a/README.rst b/README.rst
index 093a4773cdb39a218845b16d701a370d569855c3..12fe29175b30e430c6e0752bca74fac88c649e66 100644
--- a/README.rst
+++ b/README.rst
@@ -31,4 +31,9 @@ are outlined in `CONTRIBUTING <CONTRIBUTING.rst>`_.
 Translate
 ^^^^^^^^^
 
-Translators willing to help can refer to `TRANSLATORS <TRANSLATORS>`_ for instructions.
+Translators willing to help can refer to `TRANSLATORS <TRANSLATORS.rst>`_ for instructions.
+
+Code of Conduct
+---------------
+
+`Our Code of Conduct <https://funkwhale.audio/code-of-conduct/>`_ applies to all the community spaces, including our GitLab instance. Please, take a moment to read it.
diff --git a/api/compose/django/entrypoint.sh b/api/compose/django/entrypoint.sh
index 3fc06a4165676ccdeafcf0d7b09769c8a27df9f0..5259f49f81c88268ea9ea6c1288c38e8d9343a1e 100755
--- a/api/compose/django/entrypoint.sh
+++ b/api/compose/django/entrypoint.sh
@@ -22,5 +22,6 @@ fi
 if [ -d "frontend" ]; then
   mkdir -p /frontend
   cp -r frontend/* /frontend/
+  export FUNKWHALE_SPA_HTML_ROOT=/frontend/index.html
 fi
 exec "$@"
diff --git a/api/config/api_urls.py b/api/config/api_urls.py
index 3cb7ec36daf2b7b9f564c7c3d33df1dd58e7303a..a40ff3047a33b3b66dc8ef1bf2342c7c082cfc0e 100644
--- a/api/config/api_urls.py
+++ b/api/config/api_urls.py
@@ -5,6 +5,7 @@ from rest_framework.urlpatterns import format_suffix_patterns
 from rest_framework_jwt import views as jwt_views
 
 from funkwhale_api.activity import views as activity_views
+from funkwhale_api.common import views as common_views
 from funkwhale_api.music import views
 from funkwhale_api.playlists import views as playlists_views
 from funkwhale_api.subsonic.views import SubsonicViewSet
@@ -24,6 +25,7 @@ router.register(r"playlists", playlists_views.PlaylistViewSet, "playlists")
 router.register(
     r"playlist-tracks", playlists_views.PlaylistTrackViewSet, "playlist-tracks"
 )
+router.register(r"mutations", common_views.MutationViewSet, "mutations")
 v1_patterns = router.urls
 
 subsonic_router = routers.SimpleRouter(trailing_slash=False)
@@ -40,6 +42,12 @@ v1_patterns += [
         r"^manage/",
         include(("funkwhale_api.manage.urls", "manage"), namespace="manage"),
     ),
+    url(
+        r"^moderation/",
+        include(
+            ("funkwhale_api.moderation.urls", "moderation"), namespace="moderation"
+        ),
+    ),
     url(
         r"^federation/",
         include(
@@ -67,6 +75,10 @@ v1_patterns += [
         r"^users/",
         include(("funkwhale_api.users.api_urls", "users"), namespace="users"),
     ),
+    url(
+        r"^oauth/",
+        include(("funkwhale_api.users.oauth.urls", "oauth"), namespace="oauth"),
+    ),
     url(r"^token/$", jwt_views.obtain_jwt_token, name="token"),
     url(r"^token/refresh/$", jwt_views.refresh_jwt_token, name="token_refresh"),
 ]
diff --git a/api/config/asgi.py b/api/config/asgi.py
index 886178cc28ab9640bfdfa6efca1289402c2cbcf7..b4a8105de7117efe9820da558bc10f019e8eb960 100644
--- a/api/config/asgi.py
+++ b/api/config/asgi.py
@@ -1,9 +1,9 @@
 import os
 
-import django
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
+
+import django  # noqa
 
 django.setup()
 
 from .routing import application  # noqa
-
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index 45480c9ea356f861c972a2867340099ffce60e91..5d65366864470578c353d67ca1f96b7ec348c8c9 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -29,7 +29,6 @@ env_file = env("ENV_FILE", default=None)
 if env_file:
     # we have an explicitely specified env file
     # so we try to load and it fail loudly if it does not exist
-    print("ENV_FILE", env_file)
     env.read_env(env_file)
 else:
     # we try to load from .env and config/.env
@@ -79,7 +78,7 @@ FUNKWHALE_SPA_HTML_CACHE_DURATION = env.int(
     "FUNKWHALE_SPA_HTML_CACHE_DURATION", default=60 * 15
 )
 FUNKWHALE_EMBED_URL = env(
-    "FUNKWHALE_EMBED_URL", default=FUNKWHALE_SPA_HTML_ROOT + "embed.html"
+    "FUNKWHALE_EMBED_URL", default=FUNKWHALE_URL + "/front/embed.html"
 )
 APP_NAME = "Funkwhale"
 
@@ -94,6 +93,9 @@ FEDERATION_MUSIC_NEEDS_APPROVAL = env.bool(
 )
 # XXX: deprecated, see #186
 FEDERATION_ACTOR_FETCH_DELAY = env.int("FEDERATION_ACTOR_FETCH_DELAY", default=60 * 12)
+FEDERATION_SERVICE_ACTOR_USERNAME = env(
+    "FEDERATION_SERVICE_ACTOR_USERNAME", default="service"
+)
 ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=[]) + [FUNKWHALE_HOSTNAME]
 
 # APP CONFIGURATION
@@ -119,6 +121,7 @@ THIRD_PARTY_APPS = (
     "allauth.account",  # registration
     "allauth.socialaccount",  # registration
     "corsheaders",
+    "oauth2_provider",
     "rest_framework",
     "rest_framework.authtoken",
     "taggit",
@@ -147,9 +150,10 @@ if RAVEN_ENABLED:
 
 # Apps specific for this project go here.
 LOCAL_APPS = (
-    "funkwhale_api.common",
+    "funkwhale_api.common.apps.CommonConfig",
     "funkwhale_api.activity.apps.ActivityConfig",
     "funkwhale_api.users",  # custom users app
+    "funkwhale_api.users.oauth",
     # Your stuff: custom apps go here
     "funkwhale_api.instance",
     "funkwhale_api.music",
@@ -181,10 +185,6 @@ MIDDLEWARE = (
     "funkwhale_api.users.middleware.RecordActivityMiddleware",
 )
 
-# MIGRATIONS CONFIGURATION
-# ------------------------------------------------------------------------------
-MIGRATION_MODULES = {"sites": "funkwhale_api.contrib.sites.migrations"}
-
 # DEBUG
 # ------------------------------------------------------------------------------
 # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
@@ -220,6 +220,16 @@ DATABASES = {
     "default": env.db("DATABASE_URL")
 }
 DATABASES["default"]["ATOMIC_REQUESTS"] = True
+DATABASES["default"]["CONN_MAX_AGE"] = env("DB_CONN_MAX_AGE", default=60 * 60)
+
+MIGRATION_MODULES = {
+    # see https://github.com/jazzband/django-oauth-toolkit/issues/634
+    # swappable models are badly designed in oauth2_provider
+    # ignore migrations and provide our own models.
+    "oauth2_provider": None,
+    "sites": "funkwhale_api.contrib.sites.migrations",
+}
+
 #
 # DATABASES = {
 #     'default': {
@@ -296,6 +306,25 @@ STATIC_ROOT = env("STATIC_ROOT", default=str(ROOT_DIR("staticfiles")))
 STATIC_URL = env("STATIC_URL", default="/staticfiles/")
 DEFAULT_FILE_STORAGE = "funkwhale_api.common.storage.ASCIIFileSystemStorage"
 
+PROXY_MEDIA = env.bool("PROXY_MEDIA", default=True)
+AWS_DEFAULT_ACL = None
+AWS_QUERYSTRING_AUTH = env.bool("AWS_QUERYSTRING_AUTH", default=not PROXY_MEDIA)
+AWS_S3_MAX_MEMORY_SIZE = env.int(
+    "AWS_S3_MAX_MEMORY_SIZE", default=1000 * 1000 * 1000 * 20
+)
+AWS_QUERYSTRING_EXPIRE = env.int("AWS_QUERYSTRING_EXPIRE", default=3600)
+AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID", default=None)
+
+if AWS_ACCESS_KEY_ID:
+    AWS_ACCESS_KEY_ID = AWS_ACCESS_KEY_ID
+    AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY")
+    AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME")
+    AWS_S3_ENDPOINT_URL = env("AWS_S3_ENDPOINT_URL", default=None)
+    AWS_S3_REGION_NAME = env("AWS_S3_REGION_NAME", default=None)
+    AWS_S3_SIGNATURE_VERSION = "s3v4"
+    AWS_LOCATION = env("AWS_LOCATION", default="")
+    DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
+
 # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
 STATICFILES_DIRS = (str(APPS_DIR.path("static")),)
 
@@ -341,6 +370,23 @@ AUTH_USER_MODEL = "users.User"
 LOGIN_REDIRECT_URL = "users:redirect"
 LOGIN_URL = "account_login"
 
+# OAuth configuration
+from funkwhale_api.users.oauth import scopes  # noqa
+
+OAUTH2_PROVIDER = {
+    "SCOPES": {s.id: s.label for s in scopes.SCOPES_BY_ID.values()},
+    "ALLOWED_REDIRECT_URI_SCHEMES": ["http", "https", "urn"],
+    # we keep expired tokens for 15 days, for tracability
+    "REFRESH_TOKEN_EXPIRE_SECONDS": 3600 * 24 * 15,
+    "AUTHORIZATION_CODE_EXPIRE_SECONDS": 5 * 60,
+    "ACCESS_TOKEN_EXPIRE_SECONDS": 60 * 60 * 10,
+    "OAUTH2_SERVER_CLASS": "funkwhale_api.users.oauth.server.OAuth2Server",
+}
+OAUTH2_PROVIDER_APPLICATION_MODEL = "users.Application"
+OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = "users.AccessToken"
+OAUTH2_PROVIDER_GRANT_MODEL = "users.Grant"
+OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = "users.RefreshToken"
+
 # LDAP AUTHENTICATION CONFIGURATION
 # ------------------------------------------------------------------------------
 AUTH_LDAP_ENABLED = env.bool("LDAP_ENABLED", default=False)
@@ -448,16 +494,28 @@ CELERY_TASK_TIME_LIMIT = 300
 CELERY_BEAT_SCHEDULE = {
     "federation.clean_music_cache": {
         "task": "federation.clean_music_cache",
-        "schedule": crontab(hour="*/2"),
+        "schedule": crontab(minute="0", hour="*/2"),
         "options": {"expires": 60 * 2},
     },
     "music.clean_transcoding_cache": {
         "task": "music.clean_transcoding_cache",
-        "schedule": crontab(hour="*"),
+        "schedule": crontab(minute="0", hour="*"),
         "options": {"expires": 60 * 2},
     },
+    "oauth.clear_expired_tokens": {
+        "task": "oauth.clear_expired_tokens",
+        "schedule": crontab(minute="0", hour="0"),
+        "options": {"expires": 60 * 60 * 24},
+    },
+    "federation.refresh_nodeinfo_known_nodes": {
+        "task": "federation.refresh_nodeinfo_known_nodes",
+        "schedule": crontab(minute="0", hour="*"),
+        "options": {"expires": 60 * 60},
+    },
 }
 
+NODEINFO_REFRESH_DELAY = env.int("NODEINFO_REFRESH_DELAY", default=3600 * 24)
+
 JWT_AUTH = {
     "JWT_ALLOW_REFRESH": True,
     "JWT_EXPIRATION_DELTA": datetime.timedelta(days=7),
@@ -475,7 +533,6 @@ CORS_ORIGIN_ALLOW_ALL = True
 CORS_ALLOW_CREDENTIALS = True
 
 REST_FRAMEWORK = {
-    "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
     "DEFAULT_PAGINATION_CLASS": "funkwhale_api.common.pagination.FunkwhalePagination",
     "PAGE_SIZE": 25,
     "DEFAULT_PARSER_CLASSES": (
@@ -485,11 +542,15 @@ REST_FRAMEWORK = {
         "funkwhale_api.federation.parsers.ActivityParser",
     ),
     "DEFAULT_AUTHENTICATION_CLASSES": (
+        "oauth2_provider.contrib.rest_framework.OAuth2Authentication",
         "funkwhale_api.common.authentication.JSONWebTokenAuthenticationQS",
         "funkwhale_api.common.authentication.BearerTokenHeaderAuth",
         "funkwhale_api.common.authentication.JSONWebTokenAuthentication",
-        "rest_framework.authentication.SessionAuthentication",
         "rest_framework.authentication.BasicAuthentication",
+        "rest_framework.authentication.SessionAuthentication",
+    ),
+    "DEFAULT_PERMISSION_CLASSES": (
+        "funkwhale_api.users.oauth.permissions.ScopePermission",
     ),
     "DEFAULT_FILTER_BACKENDS": (
         "rest_framework.filters.OrderingFilter",
diff --git a/api/config/settings/local.py b/api/config/settings/local.py
index d6a8ce484caf782cdd8e9ed2ea66efbdb816fc31..632eb320156901f8e24be123796d4b899a27ba8f 100644
--- a/api/config/settings/local.py
+++ b/api/config/settings/local.py
@@ -62,19 +62,6 @@ CELERY_TASK_ALWAYS_EAGER = False
 
 # Your local stuff: Below this line define 3rd party library settings
 
-LOGGING = {
-    "version": 1,
-    "handlers": {"console": {"level": "DEBUG", "class": "logging.StreamHandler"}},
-    "loggers": {
-        "django.request": {
-            "handlers": ["console"],
-            "propagate": True,
-            "level": "DEBUG",
-        },
-        "django_auth_ldap": {"handlers": ["console"], "level": "DEBUG"},
-        "": {"level": "DEBUG", "handlers": ["console"]},
-    },
-}
 CSRF_TRUSTED_ORIGINS = [o for o in ALLOWED_HOSTS]
 
 
diff --git a/api/funkwhale_api/__init__.py b/api/funkwhale_api/__init__.py
index cfadc246cf92752e860fe2e755cfa5490f13c789..0b5261daabd8e7acee055db10fd37de63fa4214f 100644
--- a/api/funkwhale_api/__init__.py
+++ b/api/funkwhale_api/__init__.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-__version__ = "0.18.3"
+__version__ = "0.19.0-rc2"
 __version_info__ = tuple(
     [
         int(num) if num.isdigit() else num
diff --git a/api/funkwhale_api/common/admin.py b/api/funkwhale_api/common/admin.py
index 4124a69b895fbdc5fe51e44d53b99810ac113a7d..3ec6f1f449cf1382e3c2677e0c2e9f8f1cba5319 100644
--- a/api/funkwhale_api/common/admin.py
+++ b/api/funkwhale_api/common/admin.py
@@ -1,6 +1,9 @@
 from django.contrib.admin import register as initial_register, site, ModelAdmin  # noqa
 from django.db.models.fields.related import RelatedField
 
+from . import models
+from . import tasks
+
 
 def register(model):
     """
@@ -17,3 +20,28 @@ def register(model):
         return initial_register(model)(modeladmin)
 
     return decorator
+
+
+def apply(modeladmin, request, queryset):
+    queryset.update(is_approved=True)
+    for id in queryset.values_list("id", flat=True):
+        tasks.apply_mutation.delay(mutation_id=id)
+
+
+apply.short_description = "Approve and apply"
+
+
+@register(models.Mutation)
+class MutationAdmin(ModelAdmin):
+    list_display = [
+        "uuid",
+        "type",
+        "created_by",
+        "creation_date",
+        "applied_date",
+        "is_approved",
+        "is_applied",
+    ]
+    search_fields = ["created_by__preferred_username"]
+    list_filter = ["type", "is_approved", "is_applied"]
+    actions = [apply]
diff --git a/api/funkwhale_api/common/apps.py b/api/funkwhale_api/common/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd671be291395b438ebd15a9caa42f53a81a51c6
--- /dev/null
+++ b/api/funkwhale_api/common/apps.py
@@ -0,0 +1,13 @@
+from django.apps import AppConfig, apps
+
+from . import mutations
+
+
+class CommonConfig(AppConfig):
+    name = "funkwhale_api.common"
+
+    def ready(self):
+        super().ready()
+
+        app_names = [app.name for app in apps.app_configs.values()]
+        mutations.registry.autodiscover(app_names)
diff --git a/api/funkwhale_api/common/decorators.py b/api/funkwhale_api/common/decorators.py
index 71992eff3f9eacfe546df84d77a8faf4924138c2..49a2fb1939cd80d72111bcbec5139734e0ecd314 100644
--- a/api/funkwhale_api/common/decorators.py
+++ b/api/funkwhale_api/common/decorators.py
@@ -1,5 +1,17 @@
-from rest_framework import response
+from django.db import transaction
+
 from rest_framework import decorators
+from rest_framework import exceptions
+from rest_framework import response
+from rest_framework import status
+
+from . import filters
+from . import models
+from . import mutations as common_mutations
+from . import serializers
+from . import signals
+from . import tasks
+from . import utils
 
 
 def action_route(serializer_class):
@@ -12,3 +24,69 @@ def action_route(serializer_class):
         return response.Response(result, status=200)
 
     return action
+
+
+def mutations_route(types):
+    """
+    Given a queryset and a list of mutation types, return a view
+    that can be included in any viewset, and serve:
+
+    GET /{id}/mutations/ - list of mutations for the given object
+    POST /{id}/mutations/ - create a mutation for the given object
+    """
+
+    @transaction.atomic
+    def mutations(self, request, *args, **kwargs):
+        obj = self.get_object()
+        if request.method == "GET":
+            queryset = models.Mutation.objects.get_for_target(obj).filter(
+                type__in=types
+            )
+            queryset = queryset.order_by("-creation_date")
+            filterset = filters.MutationFilter(request.GET, queryset=queryset)
+            page = self.paginate_queryset(filterset.qs)
+            if page is not None:
+                serializer = serializers.APIMutationSerializer(page, many=True)
+                return self.get_paginated_response(serializer.data)
+
+            serializer = serializers.APIMutationSerializer(queryset, many=True)
+            return response.Response(serializer.data)
+        if request.method == "POST":
+            if not request.user.is_authenticated:
+                raise exceptions.NotAuthenticated()
+            serializer = serializers.APIMutationSerializer(
+                data=request.data, context={"registry": common_mutations.registry}
+            )
+            serializer.is_valid(raise_exception=True)
+            if not common_mutations.registry.has_perm(
+                actor=request.user.actor,
+                type=serializer.validated_data["type"],
+                obj=obj,
+                perm="approve"
+                if serializer.validated_data.get("is_approved", False)
+                else "suggest",
+            ):
+                raise exceptions.PermissionDenied()
+
+            final_payload = common_mutations.registry.get_validated_payload(
+                type=serializer.validated_data["type"],
+                payload=serializer.validated_data["payload"],
+                obj=obj,
+            )
+            mutation = serializer.save(
+                created_by=request.user.actor,
+                target=obj,
+                payload=final_payload,
+                is_approved=serializer.validated_data.get("is_approved", None),
+            )
+            if mutation.is_approved:
+                utils.on_commit(tasks.apply_mutation.delay, mutation_id=mutation.pk)
+
+            utils.on_commit(
+                signals.mutation_created.send, sender=None, mutation=mutation
+            )
+            return response.Response(serializer.data, status=status.HTTP_201_CREATED)
+
+    return decorators.action(
+        methods=["get", "post"], detail=True, required_scope="edits"
+    )(mutations)
diff --git a/api/funkwhale_api/common/factories.py b/api/funkwhale_api/common/factories.py
new file mode 100644
index 0000000000000000000000000000000000000000..6919f9c3771ec81c9e4019cfa9e42d4d30e99494
--- /dev/null
+++ b/api/funkwhale_api/common/factories.py
@@ -0,0 +1,25 @@
+import factory
+
+from funkwhale_api.factories import registry, NoUpdateOnCreate
+
+from funkwhale_api.federation import factories as federation_factories
+
+
+@registry.register
+class MutationFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
+    fid = factory.Faker("federation_url")
+    uuid = factory.Faker("uuid4")
+    created_by = factory.SubFactory(federation_factories.ActorFactory)
+    summary = factory.Faker("paragraph")
+    type = "update"
+
+    class Meta:
+        model = "common.Mutation"
+
+    @factory.post_generation
+    def target(self, create, extracted, **kwargs):
+        if not create:
+            # Simple build, do nothing.
+            return
+        self.target = extracted
+        self.save()
diff --git a/api/funkwhale_api/common/fields.py b/api/funkwhale_api/common/fields.py
index a0f10efe3a22cb2c903336a073b905f06994e69c..b8e217ba4eca9ef0954236124a577a88cf4e72d5 100644
--- a/api/funkwhale_api/common/fields.py
+++ b/api/funkwhale_api/common/fields.py
@@ -1,4 +1,5 @@
 import django_filters
+from django import forms
 from django.db import models
 
 from . import search
@@ -46,5 +47,8 @@ class SmartSearchFilter(django_filters.CharFilter):
     def filter(self, qs, value):
         if not value:
             return qs
-        cleaned = self.config.clean(value)
+        try:
+            cleaned = self.config.clean(value)
+        except (forms.ValidationError):
+            return qs.none()
         return search.apply(qs, cleaned)
diff --git a/api/funkwhale_api/common/filters.py b/api/funkwhale_api/common/filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..364a1fba18a276cef05a34976a95749408132dc9
--- /dev/null
+++ b/api/funkwhale_api/common/filters.py
@@ -0,0 +1,152 @@
+from django import forms
+from django.db.models import Q
+
+from django_filters import widgets
+from django_filters import rest_framework as filters
+
+from . import fields
+from . import models
+from . import search
+
+
+class NoneObject(object):
+    def __eq__(self, other):
+        return other.__class__ == NoneObject
+
+
+NONE = NoneObject()
+NULL_BOOLEAN_CHOICES = [
+    (True, True),
+    ("true", True),
+    ("True", True),
+    ("1", True),
+    ("yes", True),
+    (False, False),
+    ("false", False),
+    ("False", False),
+    ("0", False),
+    ("no", False),
+    ("None", NONE),
+    ("none", NONE),
+    ("Null", NONE),
+    ("null", NONE),
+]
+
+
+class CoerceChoiceField(forms.ChoiceField):
+    """
+    Same as forms.ChoiceField but will return the second value
+    in the choices tuple instead of the user provided one
+    """
+
+    def clean(self, value):
+        if value is None:
+            return value
+        v = super().clean(value)
+        try:
+            return [b for a, b in self.choices if v == a][0]
+        except IndexError:
+            raise forms.ValidationError("Invalid value {}".format(value))
+
+
+class NullBooleanFilter(filters.ChoiceFilter):
+    field_class = CoerceChoiceField
+
+    def __init__(self, *args, **kwargs):
+        self.choices = NULL_BOOLEAN_CHOICES
+        kwargs["choices"] = self.choices
+        super().__init__(*args, **kwargs)
+
+    def filter(self, qs, value):
+        if value in ["", None]:
+            return qs
+        if value == NONE:
+            value = None
+        qs = self.get_method(qs)(
+            **{"%s__%s" % (self.field_name, self.lookup_expr): value}
+        )
+        return qs.distinct() if self.distinct else qs
+
+
+def clean_null_boolean_filter(v):
+    v = CoerceChoiceField(choices=NULL_BOOLEAN_CHOICES).clean(v)
+    if v == NONE:
+        v = None
+
+    return v
+
+
+def get_null_boolean_filter(name):
+    return {"handler": lambda v: Q(**{name: clean_null_boolean_filter(v)})}
+
+
+class DummyTypedMultipleChoiceField(forms.TypedMultipleChoiceField):
+    def valid_value(self, value):
+        return True
+
+
+class QueryArrayWidget(widgets.QueryArrayWidget):
+    """
+    Until https://github.com/carltongibson/django-filter/issues/1047 is fixed
+    """
+
+    def value_from_datadict(self, data, files, name):
+        data = data.copy()
+        return super().value_from_datadict(data, files, name)
+
+
+class MultipleQueryFilter(filters.TypedMultipleChoiceFilter):
+    field_class = DummyTypedMultipleChoiceField
+
+    def __init__(self, *args, **kwargs):
+        kwargs["widget"] = QueryArrayWidget()
+        super().__init__(*args, **kwargs)
+        self.lookup_expr = "in"
+
+
+def filter_target(value):
+
+    config = {
+        "artist": ["artist", "target_id", int],
+        "album": ["album", "target_id", int],
+        "track": ["track", "target_id", int],
+    }
+    parts = value.lower().split(" ")
+    if parts[0].strip() not in config:
+        raise forms.ValidationError("Improper target")
+
+    conf = config[parts[0].strip()]
+
+    query = Q(target_content_type__model=conf[0])
+    if len(parts) > 1:
+        _, lookup_field, validator = conf
+        try:
+            lookup_value = validator(parts[1].strip())
+        except TypeError:
+            raise forms.ValidationError("Imparsable target id")
+        return query & Q(**{lookup_field: lookup_value})
+
+    return query
+
+
+class MutationFilter(filters.FilterSet):
+    is_approved = NullBooleanFilter("is_approved")
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "summary": {"to": "summary"},
+                "fid": {"to": "fid"},
+                "type": {"to": "type"},
+            },
+            filter_fields={
+                "domain": {"to": "created_by__domain__name__iexact"},
+                "is_approved": get_null_boolean_filter("is_approved"),
+                "target": {"handler": filter_target},
+                "is_applied": {"to": "is_applied"},
+            },
+        )
+    )
+
+    class Meta:
+        model = models.Mutation
+        fields = ["is_approved", "is_applied", "type"]
diff --git a/api/funkwhale_api/common/migrations/0002_mutation.py b/api/funkwhale_api/common/migrations/0002_mutation.py
new file mode 100644
index 0000000000000000000000000000000000000000..f1f756fd3a173e462954e6760e5b73f976532061
--- /dev/null
+++ b/api/funkwhale_api/common/migrations/0002_mutation.py
@@ -0,0 +1,91 @@
+# Generated by Django 2.1.5 on 2019-01-31 15:44
+
+import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import uuid
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ("federation", "0017_auto_20190130_0926"),
+        ("contenttypes", "0002_remove_content_type_name"),
+        ("common", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Mutation",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("fid", models.URLField(db_index=True, max_length=500, unique=True)),
+                (
+                    "uuid",
+                    models.UUIDField(db_index=True, default=uuid.uuid4, unique=True),
+                ),
+                ("type", models.CharField(db_index=True, max_length=100)),
+                ("is_approved", models.NullBooleanField(default=None)),
+                ("is_applied", models.NullBooleanField(default=None)),
+                (
+                    "creation_date",
+                    models.DateTimeField(
+                        db_index=True, default=django.utils.timezone.now
+                    ),
+                ),
+                (
+                    "applied_date",
+                    models.DateTimeField(blank=True, db_index=True, null=True),
+                ),
+                ("summary", models.TextField(max_length=2000, blank=True, null=True)),
+                ("payload", django.contrib.postgres.fields.jsonb.JSONField()),
+                (
+                    "previous_state",
+                    django.contrib.postgres.fields.jsonb.JSONField(
+                        null=True, default=None
+                    ),
+                ),
+                ("target_id", models.IntegerField(null=True)),
+                (
+                    "approved_by",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="approved_mutations",
+                        to="federation.Actor",
+                    ),
+                ),
+                (
+                    "created_by",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="created_mutations",
+                        to="federation.Actor",
+                    ),
+                ),
+                (
+                    "target_content_type",
+                    models.ForeignKey(
+                        null=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="targeting_mutations",
+                        to="contenttypes.ContentType",
+                    ),
+                ),
+            ],
+        )
+    ]
diff --git a/api/funkwhale_api/common/models.py b/api/funkwhale_api/common/models.py
index 9a9d858d80abcae67c8840d101c49353ebaa5118..52a02cad9433f4e79972b6cfe858534c830cb513 100644
--- a/api/funkwhale_api/common/models.py
+++ b/api/funkwhale_api/common/models.py
@@ -1,5 +1,18 @@
+import uuid
+
+from django.contrib.postgres.fields import JSONField
+from django.contrib.contenttypes.fields import GenericForeignKey
+from django.contrib.contenttypes.models import ContentType
+from django.conf import settings
+from django.core.serializers.json import DjangoJSONEncoder
+from django.db import connections, models, transaction
 from django.db.models import Lookup
 from django.db.models.fields import Field
+from django.db.models.sql.compiler import SQLCompiler
+from django.utils import timezone
+from django.urls import reverse
+
+from funkwhale_api.federation import utils as federation_utils
 
 
 @Field.register_lookup
@@ -11,3 +24,129 @@ class NotEqual(Lookup):
         rhs, rhs_params = self.process_rhs(compiler, connection)
         params = lhs_params + rhs_params
         return "%s <> %s" % (lhs, rhs), params
+
+
+class NullsLastSQLCompiler(SQLCompiler):
+    def get_order_by(self):
+        result = super().get_order_by()
+        if result and self.connection.vendor == "postgresql":
+            return [
+                (
+                    expr,
+                    (
+                        sql + " NULLS LAST" if not sql.endswith(" NULLS LAST") else sql,
+                        params,
+                        is_ref,
+                    ),
+                )
+                for (expr, (sql, params, is_ref)) in result
+            ]
+        return result
+
+
+class NullsLastQuery(models.sql.query.Query):
+    """Use a custom compiler to inject 'NULLS LAST' (for PostgreSQL)."""
+
+    def get_compiler(self, using=None, connection=None):
+        if using is None and connection is None:
+            raise ValueError("Need either using or connection")
+        if using:
+            connection = connections[using]
+        return NullsLastSQLCompiler(self, connection, using)
+
+
+class NullsLastQuerySet(models.QuerySet):
+    def __init__(self, model=None, query=None, using=None, hints=None):
+        super().__init__(model, query, using, hints)
+        self.query = query or NullsLastQuery(self.model)
+
+
+class LocalFromFidQuerySet:
+    def local(self, include=True):
+        host = settings.FEDERATION_HOSTNAME
+        query = models.Q(fid__startswith="http://{}/".format(host)) | models.Q(
+            fid__startswith="https://{}/".format(host)
+        )
+        if include:
+            return self.filter(query)
+        else:
+            return self.filter(~query)
+
+
+class MutationQuerySet(models.QuerySet):
+    def get_for_target(self, target):
+        content_type = ContentType.objects.get_for_model(target)
+        return self.filter(target_content_type=content_type, target_id=target.pk)
+
+
+class Mutation(models.Model):
+    fid = models.URLField(unique=True, max_length=500, db_index=True)
+    uuid = models.UUIDField(unique=True, db_index=True, default=uuid.uuid4)
+    created_by = models.ForeignKey(
+        "federation.Actor",
+        related_name="created_mutations",
+        on_delete=models.SET_NULL,
+        null=True,
+        blank=True,
+    )
+    approved_by = models.ForeignKey(
+        "federation.Actor",
+        related_name="approved_mutations",
+        on_delete=models.SET_NULL,
+        null=True,
+        blank=True,
+    )
+
+    type = models.CharField(max_length=100, db_index=True)
+    # None = no choice, True = approved, False = refused
+    is_approved = models.NullBooleanField(default=None)
+
+    # None = not applied, True = applied, False = failed
+    is_applied = models.NullBooleanField(default=None)
+    creation_date = models.DateTimeField(default=timezone.now, db_index=True)
+    applied_date = models.DateTimeField(null=True, blank=True, db_index=True)
+    summary = models.TextField(max_length=2000, null=True, blank=True)
+
+    payload = JSONField(encoder=DjangoJSONEncoder)
+    previous_state = JSONField(null=True, default=None, encoder=DjangoJSONEncoder)
+
+    target_id = models.IntegerField(null=True)
+    target_content_type = models.ForeignKey(
+        ContentType,
+        null=True,
+        on_delete=models.CASCADE,
+        related_name="targeting_mutations",
+    )
+    target = GenericForeignKey("target_content_type", "target_id")
+
+    objects = MutationQuerySet.as_manager()
+
+    def get_federation_id(self):
+        if self.fid:
+            return self.fid
+
+        return federation_utils.full_url(
+            reverse("federation:edits-detail", kwargs={"uuid": self.uuid})
+        )
+
+    def save(self, **kwargs):
+        if not self.pk and not self.fid:
+            self.fid = self.get_federation_id()
+
+        return super().save(**kwargs)
+
+    @transaction.atomic
+    def apply(self):
+        from . import mutations
+
+        if self.is_applied:
+            raise ValueError("Mutation was already applied")
+
+        previous_state = mutations.registry.apply(
+            type=self.type, obj=self.target, payload=self.payload
+        )
+        self.previous_state = previous_state
+        self.is_applied = True
+        self.applied_date = timezone.now()
+        self.save(update_fields=["is_applied", "applied_date", "previous_state"])
+        return previous_state
diff --git a/api/funkwhale_api/common/mutations.py b/api/funkwhale_api/common/mutations.py
new file mode 100644
index 0000000000000000000000000000000000000000..dfc8ba85e525bcfe442739b97966c794b6fbb58f
--- /dev/null
+++ b/api/funkwhale_api/common/mutations.py
@@ -0,0 +1,164 @@
+import persisting_theory
+
+from rest_framework import serializers
+
+from django.db import models, transaction
+
+
+class ConfNotFound(KeyError):
+    pass
+
+
+class Registry(persisting_theory.Registry):
+    look_into = "mutations"
+
+    def connect(self, type, klass, perm_checkers=None):
+        def decorator(serializer_class):
+            t = self.setdefault(type, {})
+            t[klass] = {
+                "serializer_class": serializer_class,
+                "perm_checkers": perm_checkers or {},
+            }
+            return serializer_class
+
+        return decorator
+
+    @transaction.atomic
+    def apply(self, type, obj, payload):
+        conf = self.get_conf(type, obj)
+        serializer = conf["serializer_class"](obj, data=payload)
+        serializer.is_valid(raise_exception=True)
+        previous_state = serializer.get_previous_state(obj, serializer.validated_data)
+        serializer.apply(obj, serializer.validated_data)
+        return previous_state
+
+    def is_valid(self, type, obj, payload):
+        conf = self.get_conf(type, obj)
+        serializer = conf["serializer_class"](obj, data=payload)
+        return serializer.is_valid(raise_exception=True)
+
+    def get_validated_payload(self, type, obj, payload):
+        conf = self.get_conf(type, obj)
+        serializer = conf["serializer_class"](obj, data=payload)
+        serializer.is_valid(raise_exception=True)
+        return serializer.payload_serialize(serializer.validated_data)
+
+    def has_perm(self, perm, type, obj, actor):
+        if perm not in ["approve", "suggest"]:
+            raise ValueError("Invalid permission {}".format(perm))
+        conf = self.get_conf(type, obj)
+        checker = conf["perm_checkers"].get(perm)
+        if not checker:
+            return False
+        return checker(obj=obj, actor=actor)
+
+    def get_conf(self, type, obj):
+        try:
+            type_conf = self[type]
+        except KeyError:
+            raise ConfNotFound("{} is not a registered mutation".format(type))
+
+        try:
+            conf = type_conf[obj.__class__]
+        except KeyError:
+            try:
+                conf = type_conf[None]
+            except KeyError:
+                raise ConfNotFound(
+                    "No mutation configuration found for {}".format(obj.__class__)
+                )
+        return conf
+
+
+class MutationSerializer(serializers.Serializer):
+    def apply(self, obj, validated_data):
+        raise NotImplementedError()
+
+    def post_apply(self, obj, validated_data):
+        pass
+
+    def get_previous_state(self, obj, validated_data):
+        return
+
+    def payload_serialize(self, data):
+        return data
+
+
+class UpdateMutationSerializer(serializers.ModelSerializer, MutationSerializer):
+    serialized_relations = {}
+
+    def __init__(self, *args, **kwargs):
+        # we force partial mode, because update mutations are partial
+        kwargs.setdefault("partial", True)
+        super().__init__(*args, **kwargs)
+
+    @transaction.atomic
+    def apply(self, obj, validated_data):
+        r = self.update(obj, validated_data)
+        self.post_apply(r, validated_data)
+        return r
+
+    def validate(self, validated_data):
+        if not validated_data:
+            raise serializers.ValidationError("You must update at least one field")
+
+        return super().validate(validated_data)
+
+    def db_serialize(self, validated_data):
+        data = {}
+        # ensure model fields are serialized properly
+        for key, value in list(validated_data.items()):
+            if not isinstance(value, models.Model):
+                data[key] = value
+                continue
+            field = self.serialized_relations[key]
+            data[key] = getattr(value, field)
+        return data
+
+    def payload_serialize(self, data):
+        data = super().payload_serialize(data)
+        # we use our serialized_relations configuration
+        # to ensure we store ids instead of model instances in our json
+        # payload
+        for field, attr in self.serialized_relations.items():
+            try:
+                obj = data[field]
+            except KeyError:
+                continue
+            if obj is None:
+                data[field] = None
+            else:
+                data[field] = getattr(obj, attr)
+        return data
+
+    def create(self, validated_data):
+        validated_data = self.db_serialize(validated_data)
+        return super().create(validated_data)
+
+    def get_previous_state(self, obj, validated_data):
+        return get_update_previous_state(
+            obj,
+            *list(validated_data.keys()),
+            serialized_relations=self.serialized_relations
+        )
+
+
+def get_update_previous_state(obj, *fields, serialized_relations={}):
+    if not fields:
+        raise ValueError("You need to provide at least one field")
+
+    state = {}
+    for field in fields:
+        value = getattr(obj, field)
+        if isinstance(value, models.Model):
+            # we store the related object id and repr for better UX
+            id_field = serialized_relations[field]
+            related_value = getattr(value, id_field)
+            state[field] = {"value": related_value, "repr": str(value)}
+        else:
+            state[field] = {"value": value}
+
+    return state
+
+
+registry = Registry()
diff --git a/api/funkwhale_api/common/pagination.py b/api/funkwhale_api/common/pagination.py
index e5068bce209da72523077a0d1dee0b7938eba422..ec7c27dc4f9cd25fc80a02fc47a156fdb42d061b 100644
--- a/api/funkwhale_api/common/pagination.py
+++ b/api/funkwhale_api/common/pagination.py
@@ -1,6 +1,29 @@
-from rest_framework.pagination import PageNumberPagination
+from rest_framework.pagination import PageNumberPagination, _positive_int
 
 
 class FunkwhalePagination(PageNumberPagination):
     page_size_query_param = "page_size"
-    max_page_size = 50
+    default_max_page_size = 50
+    default_page_size = None
+    view = None
+
+    def paginate_queryset(self, queryset, request, view=None):
+        self.view = view
+        return super().paginate_queryset(queryset, request, view)
+
+    def get_page_size(self, request):
+        max_page_size = (
+            getattr(self.view, "max_page_size", 0) or self.default_max_page_size
+        )
+        page_size = getattr(self.view, "default_page_size", 0) or max_page_size
+        if self.page_size_query_param:
+            try:
+                return _positive_int(
+                    request.query_params[self.page_size_query_param],
+                    strict=True,
+                    cutoff=max_page_size,
+                )
+            except (KeyError, ValueError):
+                pass
+
+        return page_size
diff --git a/api/funkwhale_api/common/permissions.py b/api/funkwhale_api/common/permissions.py
index 4ab405eb47c224231c8526c7c0c025c74089999f..237fc4ae4141813e505c98df76d2b0ea165ea7cb 100644
--- a/api/funkwhale_api/common/permissions.py
+++ b/api/funkwhale_api/common/permissions.py
@@ -47,6 +47,6 @@ class OwnerPermission(BasePermission):
 
         owner_field = getattr(view, "owner_field", "user")
         owner = operator.attrgetter(owner_field)(obj)
-        if owner != request.user:
+        if not owner or not request.user.is_authenticated or owner != request.user:
             raise Http404
         return True
diff --git a/api/funkwhale_api/common/search.py b/api/funkwhale_api/common/search.py
index 70aecd632f6e77109dc3e8d51e06695acd19d6cf..4e42fd3462a1ddaa35f27a4c90f4bffd6a74f465 100644
--- a/api/funkwhale_api/common/search.py
+++ b/api/funkwhale_api/common/search.py
@@ -65,6 +65,9 @@ def apply(qs, config_data):
         q = config_data.get(k)
         if q:
             qs = qs.filter(q)
+    distinct = config_data.get("distinct", False)
+    if distinct:
+        qs = qs.distinct()
     return qs
 
 
@@ -77,13 +80,28 @@ class SearchConfig:
     def clean(self, query):
         tokens = parse_query(query)
         cleaned_data = {}
-
         cleaned_data["types"] = self.clean_types(filter_tokens(tokens, ["is"]))
         cleaned_data["search_query"] = self.clean_search_query(
-            filter_tokens(tokens, [None, "in"])
+            filter_tokens(tokens, [None, "in"] + list(self.search_fields.keys()))
+        )
+        unhandled_tokens = [
+            t
+            for t in tokens
+            if t["key"] not in [None, "is", "in"] + list(self.search_fields.keys())
+        ]
+        cleaned_data["filter_query"], matching_filters = self.clean_filter_query(
+            unhandled_tokens
         )
-        unhandled_tokens = [t for t in tokens if t["key"] not in [None, "is", "in"]]
-        cleaned_data["filter_query"] = self.clean_filter_query(unhandled_tokens)
+        if matching_filters:
+            cleaned_data["distinct"] = any(
+                [
+                    self.filter_fields[k].get("distinct", False)
+                    for k in matching_filters
+                    if k in self.filter_fields
+                ]
+            )
+        else:
+            cleaned_data["distinct"] = False
         return cleaned_data
 
     def clean_search_query(self, tokens):
@@ -95,24 +113,67 @@ class SearchConfig:
         } or set(self.search_fields.keys())
         fields_subset = set(self.search_fields.keys()) & fields_subset
         to_fields = [self.search_fields[k]["to"] for k in fields_subset]
+
+        specific_field_query = None
+        for token in tokens:
+            if token["key"] not in self.search_fields:
+                continue
+            to = self.search_fields[token["key"]]["to"]
+            try:
+                field = token["field"]
+                value = field.clean(token["value"])
+            except KeyError:
+                # no cleaning to apply
+                value = token["value"]
+            q = Q(**{"{}__icontains".format(to): value})
+            if not specific_field_query:
+                specific_field_query = q
+            else:
+                specific_field_query &= q
         query_string = " ".join([t["value"] for t in filter_tokens(tokens, [None])])
-        return get_query(query_string, sorted(to_fields))
+        unhandled_tokens_query = get_query(query_string, sorted(to_fields))
+
+        if specific_field_query and unhandled_tokens_query:
+            return unhandled_tokens_query & specific_field_query
+        elif specific_field_query:
+            return specific_field_query
+        elif unhandled_tokens_query:
+            return unhandled_tokens_query
+        return None
 
     def clean_filter_query(self, tokens):
         if not self.filter_fields or not tokens:
-            return
+            return None, []
 
         matching = [t for t in tokens if t["key"] in self.filter_fields]
-        queries = [
-            Q(**{self.filter_fields[t["key"]]["to"]: t["value"]}) for t in matching
-        ]
+        queries = [self.get_filter_query(token) for token in matching]
         query = None
         for q in queries:
             if not query:
                 query = q
             else:
                 query = query & q
-        return query
+        return query, [m["key"] for m in matching]
+
+    def get_filter_query(self, token):
+        raw_value = token["value"]
+        try:
+            field = self.filter_fields[token["key"]]["field"]
+            value = field.clean(raw_value)
+        except KeyError:
+            # no cleaning to apply
+            value = raw_value
+        try:
+            query_field = self.filter_fields[token["key"]]["to"]
+            return Q(**{query_field: value})
+        except KeyError:
+            pass
+
+        # we don't have a basic filter -> field mapping, this likely means we
+        # have a dynamic handler in the config
+        handler = self.filter_fields[token["key"]]["handler"]
+        value = handler(value)
+        return value
 
     def clean_types(self, tokens):
         if not self.types:
diff --git a/api/funkwhale_api/common/serializers.py b/api/funkwhale_api/common/serializers.py
index fafa6152d09edf95052f2346b16e3135756a6114..59b513f37aa057d843df6a4a5405381be71c2c8f 100644
--- a/api/funkwhale_api/common/serializers.py
+++ b/api/funkwhale_api/common/serializers.py
@@ -10,6 +10,8 @@ from django.core.files.uploadedfile import SimpleUploadedFile
 from django.utils.encoding import smart_text
 from django.utils.translation import ugettext_lazy as _
 
+from . import models
+
 
 class RelatedField(serializers.RelatedField):
     default_error_messages = {
@@ -216,3 +218,57 @@ class StripExifImageField(serializers.ImageField):
         return SimpleUploadedFile(
             file_obj.name, content, content_type=file_obj.content_type
         )
+
+
+from funkwhale_api.federation import serializers as federation_serializers  # noqa
+
+TARGET_ID_TYPE_MAPPING = {
+    "music.Track": ("id", "track"),
+    "music.Artist": ("id", "artist"),
+    "music.Album": ("id", "album"),
+}
+
+
+class APIMutationSerializer(serializers.ModelSerializer):
+    created_by = federation_serializers.APIActorSerializer(read_only=True)
+    target = serializers.SerializerMethodField()
+
+    class Meta:
+        model = models.Mutation
+        fields = [
+            "fid",
+            "uuid",
+            "type",
+            "creation_date",
+            "applied_date",
+            "is_approved",
+            "is_applied",
+            "created_by",
+            "approved_by",
+            "summary",
+            "payload",
+            "previous_state",
+            "target",
+        ]
+        read_only_fields = [
+            "uuid",
+            "creation_date",
+            "fid",
+            "is_applied",
+            "created_by",
+            "approved_by",
+            "previous_state",
+        ]
+
+    def get_target(self, obj):
+        target = obj.target
+        if not target:
+            return
+
+        id_field, type = TARGET_ID_TYPE_MAPPING[target._meta.label]
+        return {"type": type, "id": getattr(target, id_field), "repr": str(target)}
+
+    def validate_type(self, value):
+        if value not in self.context["registry"]:
+            raise serializers.ValidationError("Invalid mutation type {}".format(value))
+        return value
diff --git a/api/funkwhale_api/common/signals.py b/api/funkwhale_api/common/signals.py
new file mode 100644
index 0000000000000000000000000000000000000000..1d8e953ccf7fed7033579ea68ce5aeb1f047bed9
--- /dev/null
+++ b/api/funkwhale_api/common/signals.py
@@ -0,0 +1,6 @@
+import django.dispatch
+
+mutation_created = django.dispatch.Signal(providing_args=["mutation"])
+mutation_updated = django.dispatch.Signal(
+    providing_args=["mutation", "old_is_approved", "new_is_approved"]
+)
diff --git a/api/funkwhale_api/common/tasks.py b/api/funkwhale_api/common/tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..994b0bdfff13a27a5eec0e99a87c72c11b39287d
--- /dev/null
+++ b/api/funkwhale_api/common/tasks.py
@@ -0,0 +1,59 @@
+from django.db import transaction
+from django.dispatch import receiver
+
+
+from funkwhale_api.common import channels
+from funkwhale_api.taskapp import celery
+
+from . import models
+from . import serializers
+from . import signals
+
+
+@celery.app.task(name="common.apply_mutation")
+@transaction.atomic
+@celery.require_instance(
+    models.Mutation.objects.exclude(is_applied=True).select_for_update(), "mutation"
+)
+def apply_mutation(mutation):
+    mutation.apply()
+
+
+@receiver(signals.mutation_created)
+def broadcast_mutation_created(mutation, **kwargs):
+    group = "instance_activity"
+    channels.group_send(
+        group,
+        {
+            "type": "event.send",
+            "text": "",
+            "data": {
+                "type": "mutation.created",
+                "mutation": serializers.APIMutationSerializer(mutation).data,
+                "pending_review_count": models.Mutation.objects.filter(
+                    is_approved=None
+                ).count(),
+            },
+        },
+    )
+
+
+@receiver(signals.mutation_updated)
+def broadcast_mutation_update(mutation, old_is_approved, new_is_approved, **kwargs):
+    group = "instance_activity"
+    channels.group_send(
+        group,
+        {
+            "type": "event.send",
+            "text": "",
+            "data": {
+                "type": "mutation.updated",
+                "mutation": serializers.APIMutationSerializer(mutation).data,
+                "pending_review_count": models.Mutation.objects.filter(
+                    is_approved=None
+                ).count(),
+                "old_is_approved": old_is_approved,
+                "new_is_approved": new_is_approved,
+            },
+        },
+    )
diff --git a/api/funkwhale_api/common/utils.py b/api/funkwhale_api/common/utils.py
index 3a54b718af0bed70dc76dbd84b5e691691f76a13..57bcba932f89008be946ea62e429659c45a12426 100644
--- a/api/funkwhale_api/common/utils.py
+++ b/api/funkwhale_api/common/utils.py
@@ -149,6 +149,27 @@ def order_for_search(qs, field):
     return qs.annotate(__size=models.functions.Length(field)).order_by("__size")
 
 
+def recursive_getattr(obj, key, permissive=False):
+    """
+    Given a dictionary such as {'user': {'name': 'Bob'}} and
+    a dotted string such as user.name, returns 'Bob'.
+
+    If the value is not present, returns None
+    """
+    v = obj
+    for k in key.split("."):
+        try:
+            v = v.get(k)
+        except (TypeError, AttributeError):
+            if not permissive:
+                raise
+            return
+        if v is None:
+            return
+
+    return v
+
+
 def replace_prefix(queryset, field, old, new):
     """
     Given a queryset of objects and a field name, will find objects
@@ -172,3 +193,38 @@ def replace_prefix(queryset, field, old, new):
         models.functions.Substr(field, len(old) + 1, output_field=models.CharField()),
     )
     return qs.update(**{field: update})
+
+
+def concat_dicts(*dicts):
+    n = {}
+    for d in dicts:
+        n.update(d)
+
+    return n
+
+
+def get_updated_fields(conf, data, obj):
+    """
+    Given a list of fields, a dict and an object, will return the dict keys/values
+    that differ from the corresponding fields on the object.
+    """
+    final_conf = []
+    for c in conf:
+        if isinstance(c, str):
+            final_conf.append((c, c))
+        else:
+            final_conf.append(c)
+
+    final_data = {}
+
+    for data_field, obj_field in final_conf:
+        try:
+            data_value = data[data_field]
+        except KeyError:
+            continue
+
+        obj_value = getattr(obj, obj_field)
+        if obj_value != data_value:
+            final_data[obj_field] = data_value
+
+    return final_data
diff --git a/api/funkwhale_api/common/views.py b/api/funkwhale_api/common/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..db39c56d1afbb5eed7fa0ba7c89693fb32c57ab4
--- /dev/null
+++ b/api/funkwhale_api/common/views.py
@@ -0,0 +1,123 @@
+from django.db import transaction
+
+from rest_framework.decorators import action
+from rest_framework import exceptions
+from rest_framework import mixins
+from rest_framework import permissions
+from rest_framework import response
+from rest_framework import viewsets
+
+from . import filters
+from . import models
+from . import mutations
+from . import serializers
+from . import signals
+from . import tasks
+from . import utils
+
+
+class SkipFilterForGetObject:
+    def get_object(self, *args, **kwargs):
+        setattr(self.request, "_skip_filters", True)
+        return super().get_object(*args, **kwargs)
+
+    def filter_queryset(self, queryset):
+        if getattr(self.request, "_skip_filters", False):
+            return queryset
+        return super().filter_queryset(queryset)
+
+
+class MutationViewSet(
+    mixins.ListModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
+):
+    lookup_field = "uuid"
+    queryset = (
+        models.Mutation.objects.all()
+        .exclude(target_id=None)
+        .order_by("-creation_date")
+        .select_related("created_by", "approved_by")
+        .prefetch_related("target")
+    )
+    serializer_class = serializers.APIMutationSerializer
+    permission_classes = [permissions.IsAuthenticated]
+    ordering_fields = ("creation_date",)
+    filterset_class = filters.MutationFilter
+
+    def perform_destroy(self, instance):
+        if instance.is_applied:
+            raise exceptions.PermissionDenied("You cannot delete an applied mutation")
+
+        actor = self.request.user.actor
+        is_owner = actor == instance.created_by
+
+        if not any(
+            [
+                is_owner,
+                mutations.registry.has_perm(
+                    perm="approve", type=instance.type, obj=instance.target, actor=actor
+                ),
+            ]
+        ):
+            raise exceptions.PermissionDenied()
+
+        return super().perform_destroy(instance)
+
+    @action(detail=True, methods=["post"])
+    @transaction.atomic
+    def approve(self, request, *args, **kwargs):
+        instance = self.get_object()
+        if instance.is_applied:
+            return response.Response(
+                {"error": "This mutation was already applied"}, status=403
+            )
+        actor = self.request.user.actor
+        can_approve = mutations.registry.has_perm(
+            perm="approve", type=instance.type, obj=instance.target, actor=actor
+        )
+
+        if not can_approve:
+            raise exceptions.PermissionDenied()
+        previous_is_approved = instance.is_approved
+        instance.approved_by = actor
+        instance.is_approved = True
+        instance.save(update_fields=["approved_by", "is_approved"])
+        utils.on_commit(tasks.apply_mutation.delay, mutation_id=instance.id)
+        utils.on_commit(
+            signals.mutation_updated.send,
+            sender=None,
+            mutation=instance,
+            old_is_approved=previous_is_approved,
+            new_is_approved=instance.is_approved,
+        )
+        return response.Response({}, status=200)
+
+    @action(detail=True, methods=["post"])
+    @transaction.atomic
+    def reject(self, request, *args, **kwargs):
+        instance = self.get_object()
+        if instance.is_applied:
+            return response.Response(
+                {"error": "This mutation was already applied"}, status=403
+            )
+        actor = self.request.user.actor
+        can_approve = mutations.registry.has_perm(
+            perm="approve", type=instance.type, obj=instance.target, actor=actor
+        )
+
+        if not can_approve:
+            raise exceptions.PermissionDenied()
+        previous_is_approved = instance.is_approved
+        instance.approved_by = actor
+        instance.is_approved = False
+        instance.save(update_fields=["approved_by", "is_approved"])
+        utils.on_commit(
+            signals.mutation_updated.send,
+            sender=None,
+            mutation=instance,
+            old_is_approved=previous_is_approved,
+            new_is_approved=instance.is_approved,
+        )
+        return response.Response({}, status=200)
diff --git a/api/funkwhale_api/factories.py b/api/funkwhale_api/factories.py
index 5db75fd58d74756689fb48b7df072c635acc99f3..3517ea007981b4745887791a807f4bad32e30f99 100644
--- a/api/funkwhale_api/factories.py
+++ b/api/funkwhale_api/factories.py
@@ -1,6 +1,11 @@
+import uuid
 import factory
 import persisting_theory
 
+from django.conf import settings
+
+from faker.providers import internet as internet_provider
+
 
 class FactoriesRegistry(persisting_theory.Registry):
     look_into = "factories"
@@ -39,3 +44,22 @@ class NoUpdateOnCreate:
     @classmethod
     def _after_postgeneration(cls, instance, create, results=None):
         return
+
+
+class FunkwhaleProvider(internet_provider.Provider):
+    """
+    Our own faker data generator, since built-in ones are sometimes
+    not random enough
+    """
+
+    def federation_url(self, prefix="", local=False):
+        def path_generator():
+            return "{}/{}".format(prefix, uuid.uuid4())
+
+        domain = settings.FEDERATION_HOSTNAME if local else self.domain_name()
+        protocol = "https"
+        path = path_generator()
+        return "{}://{}/{}".format(protocol, domain, path)
+
+
+factory.Faker.add_provider(FunkwhaleProvider)
diff --git a/api/funkwhale_api/favorites/filters.py b/api/funkwhale_api/favorites/filters.py
index a355593d91bea643277086fe98d7e81a1653e998..cf8048b8d712d5e8da5dbab80df2093b29fbf794 100644
--- a/api/funkwhale_api/favorites/filters.py
+++ b/api/funkwhale_api/favorites/filters.py
@@ -1,11 +1,10 @@
-from django_filters import rest_framework as filters
-
 from funkwhale_api.common import fields
+from funkwhale_api.moderation import filters as moderation_filters
 
 from . import models
 
 
-class TrackFavoriteFilter(filters.FilterSet):
+class TrackFavoriteFilter(moderation_filters.HiddenContentFilterSet):
     q = fields.SearchFilter(
         search_fields=["track__title", "track__artist__name", "track__album__title"]
     )
@@ -13,3 +12,6 @@ class TrackFavoriteFilter(filters.FilterSet):
     class Meta:
         model = models.TrackFavorite
         fields = ["user", "q"]
+        hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
+            "TRACK_FAVORITE"
+        ]
diff --git a/api/funkwhale_api/favorites/views.py b/api/funkwhale_api/favorites/views.py
index d54b79cea376c6598012f707cbb50784adb6d33a..dce285d85c65061fe81a86ceaa1886a6efe35ee7 100644
--- a/api/funkwhale_api/favorites/views.py
+++ b/api/funkwhale_api/favorites/views.py
@@ -1,6 +1,5 @@
 from rest_framework import mixins, status, viewsets
 from rest_framework.decorators import action
-from rest_framework.permissions import IsAuthenticatedOrReadOnly
 from rest_framework.response import Response
 
 from django.db.models import Prefetch
@@ -9,6 +8,7 @@ from funkwhale_api.activity import record
 from funkwhale_api.common import fields, permissions
 from funkwhale_api.music.models import Track
 from funkwhale_api.music import utils as music_utils
+from funkwhale_api.users.oauth import permissions as oauth_permissions
 
 from . import filters, models, serializers
 
@@ -24,10 +24,11 @@ class TrackFavoriteViewSet(
     serializer_class = serializers.UserTrackFavoriteSerializer
     queryset = models.TrackFavorite.objects.all().select_related("user")
     permission_classes = [
-        permissions.ConditionalAuthentication,
+        oauth_permissions.ScopePermission,
         permissions.OwnerPermission,
-        IsAuthenticatedOrReadOnly,
     ]
+    required_scope = "favorites"
+    anonymous_policy = "setting"
     owner_checks = ["write"]
 
     def get_serializer_class(self):
diff --git a/api/funkwhale_api/federation/activity.py b/api/funkwhale_api/federation/activity.py
index 2436044d7ef390d7f0c41b717e3c344ee6d27330..979b8aa1befb356e1c423163d1d863de96393b30 100644
--- a/api/funkwhale_api/federation/activity.py
+++ b/api/funkwhale_api/federation/activity.py
@@ -9,9 +9,13 @@ from django.db.models import Q
 from funkwhale_api.common import channels
 from funkwhale_api.common import utils as funkwhale_utils
 
+from . import contexts
+
+recursive_getattr = funkwhale_utils.recursive_getattr
+
 
 logger = logging.getLogger(__name__)
-PUBLIC_ADDRESS = "https://www.w3.org/ns/activitystreams#Public"
+PUBLIC_ADDRESS = contexts.AS.Public
 
 ACTIVITY_TYPES = [
     "Accept",
@@ -82,16 +86,19 @@ OBJECT_TYPES = (
 BROADCAST_TO_USER_ACTIVITIES = ["Follow", "Accept"]
 
 
-def should_reject(id, actor_id=None, payload={}):
+def should_reject(fid, actor_id=None, payload={}):
+    if fid is None and actor_id is None:
+        return False
+
     from funkwhale_api.moderation import models as moderation_models
 
     policies = moderation_models.InstancePolicy.objects.active()
 
     media_types = ["Audio", "Artist", "Album", "Track", "Library", "Image"]
     relevant_values = [
-        recursive_gettattr(payload, "type", permissive=True),
-        recursive_gettattr(payload, "object.type", permissive=True),
-        recursive_gettattr(payload, "target.type", permissive=True),
+        recursive_getattr(payload, "type", permissive=True),
+        recursive_getattr(payload, "object.type", permissive=True),
+        recursive_getattr(payload, "target.type", permissive=True),
     ]
     # if one of the payload types match our internal media types, then
     # we apply policies that reject media
@@ -100,9 +107,12 @@ def should_reject(id, actor_id=None, payload={}):
     else:
         policy_type = Q(block_all=True)
 
-    query = policies.matching_url_query(id) & policy_type
-    if actor_id:
+    if fid:
+        query = policies.matching_url_query(fid) & policy_type
+    if fid and actor_id:
         query |= policies.matching_url_query(actor_id) & policy_type
+    elif actor_id:
+        query = policies.matching_url_query(actor_id) & policy_type
     return policies.filter(query).exists()
 
 
@@ -111,6 +121,7 @@ def receive(activity, on_behalf_of):
     from . import models
     from . import serializers
     from . import tasks
+    from .routes import inbox
 
     # we ensure the activity has the bare minimum structure before storing
     # it in our database
@@ -118,8 +129,12 @@ def receive(activity, on_behalf_of):
         data=activity, context={"actor": on_behalf_of, "local_recipients": True}
     )
     serializer.is_valid(raise_exception=True)
+    if not inbox.get_matching_handlers(activity):
+        # discard unhandlable activity
+        return
+
     if should_reject(
-        id=serializer.validated_data["id"],
+        fid=serializer.validated_data.get("id"),
         actor_id=serializer.validated_data["actor"].fid,
         payload=activity,
     ):
@@ -350,30 +365,9 @@ class OutboxRouter(Router):
             return activities
 
 
-def recursive_gettattr(obj, key, permissive=False):
-    """
-    Given a dictionary such as {'user': {'name': 'Bob'}} and
-    a dotted string such as user.name, returns 'Bob'.
-
-    If the value is not present, returns None
-    """
-    v = obj
-    for k in key.split("."):
-        try:
-            v = v.get(k)
-        except (TypeError, AttributeError):
-            if not permissive:
-                raise
-            return
-        if v is None:
-            return
-
-    return v
-
-
 def match_route(route, payload):
     for key, value in route.items():
-        payload_value = recursive_gettattr(payload, key)
+        payload_value = recursive_getattr(payload, key, permissive=True)
         if payload_value != value:
             return False
 
@@ -417,6 +411,27 @@ def prepare_deliveries_and_inbox_items(recipient_list, type):
                     remote_inbox_urls.add(actor.shared_inbox_url or actor.inbox_url)
             urls.append(r["target"].followers_url)
 
+        elif isinstance(r, dict) and r["type"] == "instances_with_followers":
+            # we want to broadcast the activity to other instances service actors
+            # when we have at least one follower from this instance
+            follows = (
+                models.LibraryFollow.objects.filter(approved=True)
+                .exclude(actor__domain_id=settings.FEDERATION_HOSTNAME)
+                .exclude(actor__domain=None)
+                .union(
+                    models.Follow.objects.filter(approved=True)
+                    .exclude(actor__domain_id=settings.FEDERATION_HOSTNAME)
+                    .exclude(actor__domain=None)
+                )
+            )
+            actors = models.Actor.objects.filter(
+                managed_domains__name__in=follows.values_list(
+                    "actor__domain_id", flat=True
+                )
+            )
+            values = actors.values("shared_inbox_url", "inbox_url")
+            for v in values:
+                remote_inbox_urls.add(v["shared_inbox_url"] or v["inbox_url"])
     deliveries = [models.Delivery(inbox_url=url) for url in remote_inbox_urls]
     inbox_items = [
         models.InboxItem(actor=actor, type=type) for actor in local_recipients
diff --git a/api/funkwhale_api/federation/actors.py b/api/funkwhale_api/federation/actors.py
index c7a0c7c6b61c0bdbe83253286b5cb156b0370ba0..95997f95257dfcfd59f143447373e767bb52ae6f 100644
--- a/api/funkwhale_api/federation/actors.py
+++ b/api/funkwhale_api/federation/actors.py
@@ -5,8 +5,9 @@ from django.conf import settings
 from django.utils import timezone
 
 from funkwhale_api.common import preferences, session
+from funkwhale_api.users import models as users_models
 
-from . import models, serializers
+from . import keys, models, serializers
 
 logger = logging.getLogger(__name__)
 
@@ -28,7 +29,7 @@ def get_actor_data(actor_url):
 def get_actor(fid, skip_cache=False):
     if not skip_cache:
         try:
-            actor = models.Actor.objects.get(fid=fid)
+            actor = models.Actor.objects.select_related().get(fid=fid)
         except models.Actor.DoesNotExist:
             actor = None
         fetch_delta = datetime.timedelta(
@@ -42,3 +43,23 @@ def get_actor(fid, skip_cache=False):
     serializer.is_valid(raise_exception=True)
 
     return serializer.save(last_fetch_date=timezone.now())
+
+
+def get_service_actor():
+    name, domain = (
+        settings.FEDERATION_SERVICE_ACTOR_USERNAME,
+        settings.FEDERATION_HOSTNAME,
+    )
+    try:
+        return models.Actor.objects.select_related().get(
+            preferred_username=name, domain__name=domain
+        )
+    except models.Actor.DoesNotExist:
+        pass
+
+    args = users_models.get_actor_data(name)
+    private, public = keys.get_key_pair()
+    args["private_key"] = private.decode("utf-8")
+    args["public_key"] = public.decode("utf-8")
+    args["type"] = "Service"
+    return models.Actor.objects.create(**args)
diff --git a/api/funkwhale_api/federation/admin.py b/api/funkwhale_api/federation/admin.py
index 8c9bbe31c8062bda8fd9192b14170f5289620b13..263af80cb175e1235ebfd654a3daf142c19ea927 100644
--- a/api/funkwhale_api/federation/admin.py
+++ b/api/funkwhale_api/federation/admin.py
@@ -30,6 +30,14 @@ class DomainAdmin(admin.ModelAdmin):
     search_fields = ["name"]
 
 
+@admin.register(models.Fetch)
+class FetchAdmin(admin.ModelAdmin):
+    list_display = ["url", "actor", "status", "creation_date", "fetch_date", "detail"]
+    search_fields = ["url", "actor__username"]
+    list_filter = ["status"]
+    list_select_related = True
+
+
 @admin.register(models.Activity)
 class ActivityAdmin(admin.ModelAdmin):
     list_display = ["type", "fid", "url", "actor", "creation_date"]
diff --git a/api/funkwhale_api/federation/api_serializers.py b/api/funkwhale_api/federation/api_serializers.py
index 9041ed28a40b52a49c63c44b07d845077bc309d7..dbc655a47d11c677f7b98ec1a34cbbeacc6882c0 100644
--- a/api/funkwhale_api/federation/api_serializers.py
+++ b/api/funkwhale_api/federation/api_serializers.py
@@ -144,3 +144,19 @@ class InboxItemActionSerializer(common_serializers.ActionSerializer):
 
     def handle_read(self, objects):
         return objects.update(is_read=True)
+
+
+class FetchSerializer(serializers.ModelSerializer):
+    actor = federation_serializers.APIActorSerializer()
+
+    class Meta:
+        model = models.Fetch
+        fields = [
+            "id",
+            "url",
+            "actor",
+            "status",
+            "detail",
+            "creation_date",
+            "fetch_date",
+        ]
diff --git a/api/funkwhale_api/federation/api_urls.py b/api/funkwhale_api/federation/api_urls.py
index e1e451bff957d3d6dc78f4610bbdb0e77f0069c2..bd2258de961f8d0c80f8b2a3b73d5dd6a9a8ca07 100644
--- a/api/funkwhale_api/federation/api_urls.py
+++ b/api/funkwhale_api/federation/api_urls.py
@@ -3,6 +3,7 @@ from rest_framework import routers
 from . import api_views
 
 router = routers.SimpleRouter()
+router.register(r"fetches", api_views.FetchViewSet, "fetches")
 router.register(r"follows/library", api_views.LibraryFollowViewSet, "library-follows")
 router.register(r"inbox", api_views.InboxItemViewSet, "inbox")
 router.register(r"libraries", api_views.LibraryViewSet, "libraries")
diff --git a/api/funkwhale_api/federation/api_views.py b/api/funkwhale_api/federation/api_views.py
index 549bac917f843fda93ac4b6056845c64ef6cda5b..5f6f50d8fa5e273f7b678787f324422f1f3f9211 100644
--- a/api/funkwhale_api/federation/api_views.py
+++ b/api/funkwhale_api/federation/api_views.py
@@ -10,6 +10,7 @@ from rest_framework import response
 from rest_framework import viewsets
 
 from funkwhale_api.music import models as music_models
+from funkwhale_api.users.oauth import permissions as oauth_permissions
 
 from . import activity
 from . import api_serializers
@@ -43,7 +44,8 @@ class LibraryFollowViewSet(
         .select_related("actor", "target__actor")
     )
     serializer_class = api_serializers.LibraryFollowSerializer
-    permission_classes = [permissions.IsAuthenticated]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "follows"
     filterset_class = filters.LibraryFollowFilter
     ordering_fields = ("creation_date",)
 
@@ -100,7 +102,8 @@ class LibraryViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
         .annotate(_uploads_count=Count("uploads"))
     )
     serializer_class = api_serializers.LibrarySerializer
-    permission_classes = [permissions.IsAuthenticated]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
 
     def get_queryset(self):
         qs = super().get_queryset()
@@ -132,6 +135,7 @@ class LibraryViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
         try:
             library = utils.retrieve_ap_object(
                 fid,
+                actor=request.user.actor,
                 queryset=self.queryset,
                 serializer_class=serializers.LibrarySerializer,
             )
@@ -168,7 +172,8 @@ class InboxItemViewSet(
         .order_by("-activity__creation_date")
     )
     serializer_class = api_serializers.InboxItemSerializer
-    permission_classes = [permissions.IsAuthenticated]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "notifications"
     filterset_class = filters.InboxItemFilter
     ordering_fields = ("activity__creation_date",)
 
@@ -185,3 +190,10 @@ class InboxItemViewSet(
         serializer.is_valid(raise_exception=True)
         result = serializer.save()
         return response.Response(result, status=200)
+
+
+class FetchViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
+
+    queryset = models.Fetch.objects.select_related("actor")
+    serializer_class = api_serializers.FetchSerializer
+    permission_classes = [permissions.IsAuthenticated]
diff --git a/api/funkwhale_api/federation/authentication.py b/api/funkwhale_api/federation/authentication.py
index dd7a142dfe483aa9ee51b1d50de72c4c52a3ce4c..75e0332421feb115eac1ee58acc2906b2ae06ae5 100644
--- a/api/funkwhale_api/federation/authentication.py
+++ b/api/funkwhale_api/federation/authentication.py
@@ -1,11 +1,13 @@
 import cryptography
 import logging
+import datetime
 
 from django.contrib.auth.models import AnonymousUser
-from rest_framework import authentication, exceptions as rest_exceptions
+from django.utils import timezone
 
+from rest_framework import authentication, exceptions as rest_exceptions
 from funkwhale_api.moderation import models as moderation_models
-from . import actors, exceptions, keys, signing, utils
+from . import actors, exceptions, keys, signing, tasks, utils
 
 
 logger = logging.getLogger(__name__)
@@ -57,6 +59,15 @@ class SignatureAuthentication(authentication.BaseAuthentication):
             actor = actors.get_actor(actor_url, skip_cache=True)
             signing.verify_django(request, actor.public_key.encode("utf-8"))
 
+        # we trigger a nodeinfo update on the actor's domain, if needed
+        fetch_delay = 24 * 3600
+        now = timezone.now()
+        last_fetch = actor.domain.nodeinfo_fetch_date
+        if not last_fetch or (
+            last_fetch < (now - datetime.timedelta(seconds=fetch_delay))
+        ):
+            tasks.update_domain_nodeinfo(domain_name=actor.domain.name)
+            actor.domain.refresh_from_db()
         return actor
 
     def authenticate(self, request):
diff --git a/api/funkwhale_api/federation/contexts.py b/api/funkwhale_api/federation/contexts.py
new file mode 100644
index 0000000000000000000000000000000000000000..0873bcd46b04d715e861a9244a1327187d50167d
--- /dev/null
+++ b/api/funkwhale_api/federation/contexts.py
@@ -0,0 +1,333 @@
+CONTEXTS = [
+    {
+        "shortId": "LDP",
+        "contextUrl": None,
+        "documentUrl": "http://www.w3.org/ns/ldp",
+        "document": {
+            "@context": {
+                "ldp": "http://www.w3.org/ns/ldp#",
+                "id": "@id",
+                "type": "@type",
+                "Container": "ldp:Container",
+                "BasicContainer": "ldp:BasicContainer",
+                "DirectContainer": "ldp:DirectContainer",
+                "IndirectContainer": "ldp:IndirectContainer",
+                "hasMemberRelation": {"@id": "ldp:hasMemberRelation", "@type": "@id"},
+                "isMemberOfRelation": {"@id": "ldp:isMemberOfRelation", "@type": "@id"},
+                "membershipResource": {"@id": "ldp:membershipResource", "@type": "@id"},
+                "insertedContentRelation": {
+                    "@id": "ldp:insertedContentRelation",
+                    "@type": "@id",
+                },
+                "contains": {"@id": "ldp:contains", "@type": "@id"},
+                "member": {"@id": "ldp:member", "@type": "@id"},
+                "constrainedBy": {"@id": "ldp:constrainedBy", "@type": "@id"},
+                "Resource": "ldp:Resource",
+                "RDFSource": "ldp:RDFSource",
+                "NonRDFSource": "ldp:NonRDFSource",
+                "MemberSubject": "ldp:MemberSubject",
+                "PreferContainment": "ldp:PreferContainment",
+                "PreferMembership": "ldp:PreferMembership",
+                "PreferMinimalContainer": "ldp:PreferMinimalContainer",
+                "PageSortCriterion": "ldp:PageSortCriterion",
+                "pageSortCriteria": {
+                    "@id": "ldp:pageSortCriteria",
+                    "@type": "@id",
+                    "@container": "@list",
+                },
+                "pageSortPredicate": {"@id": "ldp:pageSortPredicate", "@type": "@id"},
+                "pageSortOrder": {"@id": "ldp:pageSortOrder", "@type": "@id"},
+                "pageSortCollation": {"@id": "ldp:pageSortCollation", "@type": "@id"},
+                "Ascending": "ldp:Ascending",
+                "Descending": "ldp:Descending",
+                "Page": "ldp:Page",
+                "pageSequence": {"@id": "ldp:pageSequence", "@type": "@id"},
+                "inbox": {"@id": "ldp:inbox", "@type": "@id"},
+            }
+        },
+    },
+    {
+        "shortId": "AS",
+        "contextUrl": None,
+        "documentUrl": "https://www.w3.org/ns/activitystreams",
+        "document": {
+            "@context": {
+                "@vocab": "_:",
+                "xsd": "http://www.w3.org/2001/XMLSchema#",
+                "as": "https://www.w3.org/ns/activitystreams#",
+                "ldp": "http://www.w3.org/ns/ldp#",
+                "id": "@id",
+                "type": "@type",
+                "Accept": "as:Accept",
+                "Activity": "as:Activity",
+                "IntransitiveActivity": "as:IntransitiveActivity",
+                "Add": "as:Add",
+                "Announce": "as:Announce",
+                "Application": "as:Application",
+                "Arrive": "as:Arrive",
+                "Article": "as:Article",
+                "Audio": "as:Audio",
+                "Block": "as:Block",
+                "Collection": "as:Collection",
+                "CollectionPage": "as:CollectionPage",
+                "Relationship": "as:Relationship",
+                "Create": "as:Create",
+                "Delete": "as:Delete",
+                "Dislike": "as:Dislike",
+                "Document": "as:Document",
+                "Event": "as:Event",
+                "Follow": "as:Follow",
+                "Flag": "as:Flag",
+                "Group": "as:Group",
+                "Ignore": "as:Ignore",
+                "Image": "as:Image",
+                "Invite": "as:Invite",
+                "Join": "as:Join",
+                "Leave": "as:Leave",
+                "Like": "as:Like",
+                "Link": "as:Link",
+                "Mention": "as:Mention",
+                "Note": "as:Note",
+                "Object": "as:Object",
+                "Offer": "as:Offer",
+                "OrderedCollection": "as:OrderedCollection",
+                "OrderedCollectionPage": "as:OrderedCollectionPage",
+                "Organization": "as:Organization",
+                "Page": "as:Page",
+                "Person": "as:Person",
+                "Place": "as:Place",
+                "Profile": "as:Profile",
+                "Question": "as:Question",
+                "Reject": "as:Reject",
+                "Remove": "as:Remove",
+                "Service": "as:Service",
+                "TentativeAccept": "as:TentativeAccept",
+                "TentativeReject": "as:TentativeReject",
+                "Tombstone": "as:Tombstone",
+                "Undo": "as:Undo",
+                "Update": "as:Update",
+                "Video": "as:Video",
+                "View": "as:View",
+                "Listen": "as:Listen",
+                "Read": "as:Read",
+                "Move": "as:Move",
+                "Travel": "as:Travel",
+                "IsFollowing": "as:IsFollowing",
+                "IsFollowedBy": "as:IsFollowedBy",
+                "IsContact": "as:IsContact",
+                "IsMember": "as:IsMember",
+                "subject": {"@id": "as:subject", "@type": "@id"},
+                "relationship": {"@id": "as:relationship", "@type": "@id"},
+                "actor": {"@id": "as:actor", "@type": "@id"},
+                "attributedTo": {"@id": "as:attributedTo", "@type": "@id"},
+                "attachment": {"@id": "as:attachment", "@type": "@id"},
+                "bcc": {"@id": "as:bcc", "@type": "@id"},
+                "bto": {"@id": "as:bto", "@type": "@id"},
+                "cc": {"@id": "as:cc", "@type": "@id"},
+                "context": {"@id": "as:context", "@type": "@id"},
+                "current": {"@id": "as:current", "@type": "@id"},
+                "first": {"@id": "as:first", "@type": "@id"},
+                "generator": {"@id": "as:generator", "@type": "@id"},
+                "icon": {"@id": "as:icon", "@type": "@id"},
+                "image": {"@id": "as:image", "@type": "@id"},
+                "inReplyTo": {"@id": "as:inReplyTo", "@type": "@id"},
+                "items": {"@id": "as:items", "@type": "@id"},
+                "instrument": {"@id": "as:instrument", "@type": "@id"},
+                "orderedItems": {
+                    "@id": "as:items",
+                    "@type": "@id",
+                    "@container": "@list",
+                },
+                "last": {"@id": "as:last", "@type": "@id"},
+                "location": {"@id": "as:location", "@type": "@id"},
+                "next": {"@id": "as:next", "@type": "@id"},
+                "object": {"@id": "as:object", "@type": "@id"},
+                "oneOf": {"@id": "as:oneOf", "@type": "@id"},
+                "anyOf": {"@id": "as:anyOf", "@type": "@id"},
+                "closed": {"@id": "as:closed", "@type": "xsd:dateTime"},
+                "origin": {"@id": "as:origin", "@type": "@id"},
+                "accuracy": {"@id": "as:accuracy", "@type": "xsd:float"},
+                "prev": {"@id": "as:prev", "@type": "@id"},
+                "preview": {"@id": "as:preview", "@type": "@id"},
+                "replies": {"@id": "as:replies", "@type": "@id"},
+                "result": {"@id": "as:result", "@type": "@id"},
+                "audience": {"@id": "as:audience", "@type": "@id"},
+                "partOf": {"@id": "as:partOf", "@type": "@id"},
+                "tag": {"@id": "as:tag", "@type": "@id"},
+                "target": {"@id": "as:target", "@type": "@id"},
+                "to": {"@id": "as:to", "@type": "@id"},
+                "url": {"@id": "as:url", "@type": "@id"},
+                "altitude": {"@id": "as:altitude", "@type": "xsd:float"},
+                "content": "as:content",
+                "contentMap": {"@id": "as:content", "@container": "@language"},
+                "name": "as:name",
+                "nameMap": {"@id": "as:name", "@container": "@language"},
+                "duration": {"@id": "as:duration", "@type": "xsd:duration"},
+                "endTime": {"@id": "as:endTime", "@type": "xsd:dateTime"},
+                "height": {"@id": "as:height", "@type": "xsd:nonNegativeInteger"},
+                "href": {"@id": "as:href", "@type": "@id"},
+                "hreflang": "as:hreflang",
+                "latitude": {"@id": "as:latitude", "@type": "xsd:float"},
+                "longitude": {"@id": "as:longitude", "@type": "xsd:float"},
+                "mediaType": "as:mediaType",
+                "published": {"@id": "as:published", "@type": "xsd:dateTime"},
+                "radius": {"@id": "as:radius", "@type": "xsd:float"},
+                "rel": "as:rel",
+                "startIndex": {
+                    "@id": "as:startIndex",
+                    "@type": "xsd:nonNegativeInteger",
+                },
+                "startTime": {"@id": "as:startTime", "@type": "xsd:dateTime"},
+                "summary": "as:summary",
+                "summaryMap": {"@id": "as:summary", "@container": "@language"},
+                "totalItems": {
+                    "@id": "as:totalItems",
+                    "@type": "xsd:nonNegativeInteger",
+                },
+                "units": "as:units",
+                "updated": {"@id": "as:updated", "@type": "xsd:dateTime"},
+                "width": {"@id": "as:width", "@type": "xsd:nonNegativeInteger"},
+                "describes": {"@id": "as:describes", "@type": "@id"},
+                "formerType": {"@id": "as:formerType", "@type": "@id"},
+                "deleted": {"@id": "as:deleted", "@type": "xsd:dateTime"},
+                "inbox": {"@id": "ldp:inbox", "@type": "@id"},
+                "outbox": {"@id": "as:outbox", "@type": "@id"},
+                "following": {"@id": "as:following", "@type": "@id"},
+                "followers": {"@id": "as:followers", "@type": "@id"},
+                "streams": {"@id": "as:streams", "@type": "@id"},
+                "preferredUsername": "as:preferredUsername",
+                "endpoints": {"@id": "as:endpoints", "@type": "@id"},
+                "uploadMedia": {"@id": "as:uploadMedia", "@type": "@id"},
+                "proxyUrl": {"@id": "as:proxyUrl", "@type": "@id"},
+                "liked": {"@id": "as:liked", "@type": "@id"},
+                "oauthAuthorizationEndpoint": {
+                    "@id": "as:oauthAuthorizationEndpoint",
+                    "@type": "@id",
+                },
+                "oauthTokenEndpoint": {"@id": "as:oauthTokenEndpoint", "@type": "@id"},
+                "provideClientKey": {"@id": "as:provideClientKey", "@type": "@id"},
+                "signClientKey": {"@id": "as:signClientKey", "@type": "@id"},
+                "sharedInbox": {"@id": "as:sharedInbox", "@type": "@id"},
+                "Public": {"@id": "as:Public", "@type": "@id"},
+                "source": "as:source",
+                "likes": {"@id": "as:likes", "@type": "@id"},
+                "shares": {"@id": "as:shares", "@type": "@id"},
+                # Added manually
+                "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+            }
+        },
+    },
+    {
+        "shortId": "SEC",
+        "contextUrl": None,
+        "documentUrl": "https://w3id.org/security/v1",
+        "document": {
+            "@context": {
+                "id": "@id",
+                "type": "@type",
+                "dc": "http://purl.org/dc/terms/",
+                "sec": "https://w3id.org/security#",
+                "xsd": "http://www.w3.org/2001/XMLSchema#",
+                "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016",
+                "Ed25519Signature2018": "sec:Ed25519Signature2018",
+                "EncryptedMessage": "sec:EncryptedMessage",
+                "GraphSignature2012": "sec:GraphSignature2012",
+                "LinkedDataSignature2015": "sec:LinkedDataSignature2015",
+                "LinkedDataSignature2016": "sec:LinkedDataSignature2016",
+                "CryptographicKey": "sec:Key",
+                "authenticationTag": "sec:authenticationTag",
+                "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm",
+                "cipherAlgorithm": "sec:cipherAlgorithm",
+                "cipherData": "sec:cipherData",
+                "cipherKey": "sec:cipherKey",
+                "created": {"@id": "dc:created", "@type": "xsd:dateTime"},
+                "creator": {"@id": "dc:creator", "@type": "@id"},
+                "digestAlgorithm": "sec:digestAlgorithm",
+                "digestValue": "sec:digestValue",
+                "domain": "sec:domain",
+                "encryptionKey": "sec:encryptionKey",
+                "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
+                "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
+                "initializationVector": "sec:initializationVector",
+                "iterationCount": "sec:iterationCount",
+                "nonce": "sec:nonce",
+                "normalizationAlgorithm": "sec:normalizationAlgorithm",
+                "owner": {"@id": "sec:owner", "@type": "@id"},
+                "password": "sec:password",
+                "privateKey": {"@id": "sec:privateKey", "@type": "@id"},
+                "privateKeyPem": "sec:privateKeyPem",
+                "publicKey": {"@id": "sec:publicKey", "@type": "@id"},
+                "publicKeyBase58": "sec:publicKeyBase58",
+                "publicKeyPem": "sec:publicKeyPem",
+                "publicKeyWif": "sec:publicKeyWif",
+                "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"},
+                "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"},
+                "salt": "sec:salt",
+                "signature": "sec:signature",
+                "signatureAlgorithm": "sec:signingAlgorithm",
+                "signatureValue": "sec:signatureValue",
+            }
+        },
+    },
+    {
+        "shortId": "FW",
+        "contextUrl": None,
+        "documentUrl": "https://funkwhale.audio/ns",
+        "document": {
+            "@context": {
+                "id": "@id",
+                "type": "@type",
+                "as": "https://www.w3.org/ns/activitystreams#",
+                "fw": "https://funkwhale.audio/ns#",
+                "xsd": "http://www.w3.org/2001/XMLSchema#",
+                "Album": "fw:Album",
+                "Track": "fw:Track",
+                "Artist": "fw:Artist",
+                "Library": "fw:Library",
+                "bitrate": {"@id": "fw:bitrate", "@type": "xsd:nonNegativeInteger"},
+                "size": {"@id": "fw:size", "@type": "xsd:nonNegativeInteger"},
+                "position": {"@id": "fw:position", "@type": "xsd:nonNegativeInteger"},
+                "disc": {"@id": "fw:disc", "@type": "xsd:nonNegativeInteger"},
+                "library": {"@id": "fw:library", "@type": "@id"},
+                "track": {"@id": "fw:track", "@type": "@id"},
+                "cover": {"@id": "fw:cover", "@type": "as:Link"},
+                "album": {"@id": "fw:album", "@type": "@id"},
+                "artists": {"@id": "fw:artists", "@type": "@id", "@container": "@list"},
+                "released": {"@id": "fw:released", "@type": "xsd:date"},
+                "musicbrainzId": "fw:musicbrainzId",
+                "license": {"@id": "fw:license", "@type": "@id"},
+                "copyright": "fw:copyright",
+            }
+        },
+    },
+]
+
+CONTEXTS_BY_ID = {c["shortId"]: c for c in CONTEXTS}
+
+
+class NS:
+    def __init__(self, conf):
+        self.conf = conf
+        self.baseUrl = self.conf["document"]["@context"][self.conf["shortId"].lower()]
+
+    def __repr__(self):
+        return "<{}: {}>".format(self.conf["shortId"], self.baseUrl)
+
+    def __getattr__(self, key):
+        if key not in self.conf["document"]["@context"]:
+            raise AttributeError(
+                "{} is not a valid property of context {}".format(key, self.baseUrl)
+            )
+        return self.baseUrl + key
+
+
+class NoopContext:
+    def __getattr__(self, key):
+        return "_:{}".format(key)
+
+
+NOOP = NoopContext()
+AS = NS(CONTEXTS_BY_ID["AS"])
+LDP = NS(CONTEXTS_BY_ID["LDP"])
+SEC = NS(CONTEXTS_BY_ID["SEC"])
+FW = NS(CONTEXTS_BY_ID["FW"])
diff --git a/api/funkwhale_api/federation/decorators.py b/api/funkwhale_api/federation/decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d2d62567613f7899eea0c2a9356812150bcd160
--- /dev/null
+++ b/api/funkwhale_api/federation/decorators.py
@@ -0,0 +1,49 @@
+from django.db import transaction
+
+from rest_framework import decorators
+from rest_framework import permissions
+from rest_framework import response
+from rest_framework import status
+
+from funkwhale_api.common import utils as common_utils
+
+from . import api_serializers
+from . import filters
+from . import models
+from . import tasks
+from . import utils
+
+
+def fetches_route():
+    @transaction.atomic
+    def fetches(self, request, *args, **kwargs):
+        obj = self.get_object()
+        if request.method == "GET":
+            queryset = models.Fetch.objects.get_for_object(obj).select_related("actor")
+            queryset = queryset.order_by("-creation_date")
+            filterset = filters.FetchFilter(request.GET, queryset=queryset)
+            page = self.paginate_queryset(filterset.qs)
+            if page is not None:
+                serializer = api_serializers.FetchSerializer(page, many=True)
+                return self.get_paginated_response(serializer.data)
+
+            serializer = api_serializers.FetchSerializer(queryset, many=True)
+            return response.Response(serializer.data)
+        if request.method == "POST":
+            if utils.is_local(obj.fid):
+                return response.Response(
+                    {"detail": "Cannot fetch a local object"}, status=400
+                )
+
+            fetch = models.Fetch.objects.create(
+                url=obj.fid, actor=request.user.actor, object=obj
+            )
+            common_utils.on_commit(tasks.fetch.delay, fetch_id=fetch.pk)
+            serializer = api_serializers.FetchSerializer(fetch)
+            return response.Response(serializer.data, status=status.HTTP_201_CREATED)
+
+    return decorators.action(
+        methods=["get", "post"],
+        detail=True,
+        permission_classes=[permissions.IsAuthenticated],
+    )(fetches)
diff --git a/api/funkwhale_api/federation/factories.py b/api/funkwhale_api/federation/factories.py
index f54f6867861230e3b2bc7ffd4fcf1adbcd61fe3a..14bb4e8c96ea150a09fbf95bdbbbcb021f270a8c 100644
--- a/api/funkwhale_api/federation/factories.py
+++ b/api/funkwhale_api/federation/factories.py
@@ -69,11 +69,21 @@ def create_user(actor):
 @registry.register
 class DomainFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     name = factory.Faker("domain_name")
+    nodeinfo_fetch_date = factory.LazyFunction(lambda: timezone.now())
 
     class Meta:
         model = "federation.Domain"
         django_get_or_create = ("name",)
 
+    @factory.post_generation
+    def with_service_actor(self, create, extracted, **kwargs):
+        if not create or not extracted:
+            return
+
+        self.service_actor = ActorFactory(domain=self)
+        self.save(update_fields=["service_actor"])
+        return self.service_actor
+
 
 @registry.register
 class ActorFactory(NoUpdateOnCreate, factory.DjangoModelFactory):
@@ -156,7 +166,7 @@ class MusicLibraryFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
 
 
 @registry.register
-class LibraryScan(NoUpdateOnCreate, factory.django.DjangoModelFactory):
+class LibraryScanFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     library = factory.SubFactory(MusicLibraryFactory)
     actor = factory.SubFactory(ActorFactory)
     total_files = factory.LazyAttribute(lambda o: o.library.uploads_count)
@@ -165,6 +175,14 @@ class LibraryScan(NoUpdateOnCreate, factory.django.DjangoModelFactory):
         model = "music.LibraryScan"
 
 
+@registry.register
+class FetchFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
+    actor = factory.SubFactory(ActorFactory)
+
+    class Meta:
+        model = "federation.Fetch"
+
+
 @registry.register
 class ActivityFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     actor = factory.SubFactory(ActorFactory)
diff --git a/api/funkwhale_api/federation/fields.py b/api/funkwhale_api/federation/fields.py
index 3523396dbceb86a2aa8c84c1767cad9b6f767db1..8a8a1eb2de2059a2b6edeeec629c81147c84381b 100644
--- a/api/funkwhale_api/federation/fields.py
+++ b/api/funkwhale_api/federation/fields.py
@@ -1,6 +1,9 @@
+import django_filters
+
 from rest_framework import serializers
 
 from . import models
+from . import utils
 
 
 class ActorRelatedField(serializers.EmailField):
@@ -16,3 +19,15 @@ class ActorRelatedField(serializers.EmailField):
             )
         except models.Actor.DoesNotExist:
             raise serializers.ValidationError("Invalid actor name")
+
+
+class DomainFromURLFilter(django_filters.CharFilter):
+    def __init__(self, *args, **kwargs):
+        self.url_field = kwargs.pop("url_field", "fid")
+        super().__init__(*args, **kwargs)
+
+    def filter(self, qs, value):
+        if not value:
+            return qs
+        query = utils.get_domain_query_from_url(value, self.url_field)
+        return qs.filter(query)
diff --git a/api/funkwhale_api/federation/filters.py b/api/funkwhale_api/federation/filters.py
index 3a8b76ceee9e706b806fddef3f82076f89077979..bfc48bcfbfcc6f9c4d3b33794523a5e4b833abc4 100644
--- a/api/funkwhale_api/federation/filters.py
+++ b/api/funkwhale_api/federation/filters.py
@@ -46,3 +46,14 @@ class InboxItemFilter(django_filters.FilterSet):
 
     def filter_before(self, queryset, field_name, value):
         return queryset.filter(pk__lte=value)
+
+
+class FetchFilter(django_filters.FilterSet):
+    ordering = django_filters.OrderingFilter(
+        # tuple-mapping retains order
+        fields=(("creation_date", "creation_date"), ("fetch_date", "fetch_date"))
+    )
+
+    class Meta:
+        model = models.Fetch
+        fields = ["status", "object_id", "url"]
diff --git a/api/funkwhale_api/federation/jsonld.py b/api/funkwhale_api/federation/jsonld.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad67323f239bb7be2fb42be90a75091915971eba
--- /dev/null
+++ b/api/funkwhale_api/federation/jsonld.py
@@ -0,0 +1,287 @@
+import aiohttp
+import asyncio
+import functools
+
+import pyld.jsonld
+from django.conf import settings
+import pyld.documentloader.requests
+from rest_framework import serializers
+from rest_framework.fields import empty
+from . import contexts
+
+
+def cached_contexts(loader):
+    functools.wraps(loader)
+
+    def load(url, *args, **kwargs):
+        for cached in contexts.CONTEXTS:
+            if url == cached["documentUrl"]:
+                return cached
+        return loader(url, *args, **kwargs)
+
+    return load
+
+
+def get_document_loader():
+    loader = pyld.documentloader.requests.requests_document_loader(
+        verify=settings.EXTERNAL_REQUESTS_VERIFY_SSL
+    )
+    return cached_contexts(loader)
+
+
+def expand(doc, options=None, insert_fw_context=True):
+    options = options or {}
+    options.setdefault("documentLoader", get_document_loader())
+    if isinstance(doc, str):
+        doc = options["documentLoader"](doc)["document"]
+    if insert_fw_context:
+        fw = contexts.CONTEXTS_BY_ID["FW"]["documentUrl"]
+        try:
+            insert_context(fw, doc)
+        except KeyError:
+            # probably an already expanded document
+            pass
+    result = pyld.jsonld.expand(doc, options=options)
+    try:
+        # jsonld.expand returns a list, which is useless for us
+        return result[0]
+    except IndexError:
+        raise ValueError("Impossible to expand this jsonld document")
+
+
+def insert_context(ctx, doc):
+    """
+    In some situations, we may want to add a default context to an existing document.
+    This function enable that (this will mutate the original document)
+    """
+    existing = doc["@context"]
+    if isinstance(existing, list):
+        if ctx not in existing:
+            existing = existing[:]
+            existing.append(ctx)
+            doc["@context"] = existing
+    else:
+        doc["@context"] = [existing, ctx]
+    return doc
+
+
+def get_session():
+    return aiohttp.ClientSession(raise_for_status=True)
+
+
+async def fetch_json(url, session, cache=None, lock=None):
+    async with session.get(url) as response:
+        response.raise_for_status()
+        return url, await response.json()
+
+
+async def fetch_many(*ids, references=None):
+    """
+    Given a list of object ids, will fetch the remote
+    representations for those objects, expand them
+    and return a dictionnary with id as the key and expanded document as the values
+    """
+    ids = set(ids)
+    results = references if references is not None else {}
+
+    if not ids:
+        return results
+
+    async with get_session() as session:
+        tasks = [fetch_json(url, session) for url in ids if url not in results]
+        tasks_results = await asyncio.gather(*tasks)
+
+    for url, payload in tasks_results:
+        results[url] = payload
+
+    return results
+
+
+DEFAULT_PREPARE_CONFIG = {
+    "type": {"property": "@type", "keep": "first"},
+    "id": {"property": "@id"},
+}
+
+
+def dereference(value, references):
+    """
+    Given a payload and a dictonary containing ids and objects, will replace
+    all the matching objects in the payload by the one in the references dictionary.
+    """
+
+    def replace(obj, id):
+        try:
+            matching = references[id]
+        except KeyError:
+            return
+        # we clear the current dict, and replace its content by the matching obj
+        obj.clear()
+        obj.update(matching)
+
+    if isinstance(value, dict):
+        if "@id" in value:
+            replace(value, value["@id"])
+        else:
+            for attr in value.values():
+                dereference(attr, references)
+
+    elif isinstance(value, list):
+        # we loop on nested objects and trigger dereferencing
+        for obj in value:
+            dereference(obj, references)
+
+    return value
+
+
+def get_value(value, keep=None, attr=None):
+
+    if keep == "first":
+        value = value[0]
+        if attr:
+            value = value[attr]
+
+    elif attr:
+        value = [obj[attr] for obj in value if attr in obj]
+
+    return value
+
+
+def prepare_for_serializer(payload, config, fallbacks={}):
+    """
+    Json-ld payloads, as returned by expand are quite complex to handle, because
+    every attr is basically a list of dictionnaries. To make code simpler,
+    we use this function to clean the payload a little bit, base on the config object.
+
+    Config is a dictionnary, with keys being serializer field names, and values
+    being dictionaries describing how to handle this field.
+    """
+    final_payload = {}
+    final_config = {}
+    final_config.update(DEFAULT_PREPARE_CONFIG)
+    final_config.update(config)
+    for field, field_config in final_config.items():
+        try:
+            value = get_value(
+                payload[field_config["property"]],
+                keep=field_config.get("keep"),
+                attr=field_config.get("attr"),
+            )
+        except (IndexError, KeyError):
+            aliases = field_config.get("aliases", [])
+            noop = object()
+            value = noop
+            if not aliases:
+                continue
+
+            for a in aliases:
+                try:
+                    value = get_value(
+                        payload[a],
+                        keep=field_config.get("keep"),
+                        attr=field_config.get("attr"),
+                    )
+                except (IndexError, KeyError):
+                    continue
+
+                break
+
+            if value is noop:
+                continue
+
+        final_payload[field] = value
+
+    for key, choices in fallbacks.items():
+        if key in final_payload:
+            # initial attr was found, no need to rely on fallbacks
+            continue
+
+        for choice in choices:
+            if choice not in final_payload:
+                continue
+
+            final_payload[key] = final_payload[choice]
+
+    return final_payload
+
+
+def get_ids(v):
+    if isinstance(v, dict) and "@id" in v:
+        yield v["@id"]
+
+    if isinstance(v, list):
+        for obj in v:
+            yield from get_ids(obj)
+
+
+def get_default_context():
+    return ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1", {}]
+
+
+def get_default_context_fw():
+    return [
+        "https://www.w3.org/ns/activitystreams",
+        "https://w3id.org/security/v1",
+        {},
+        "https://funkwhale.audio/ns",
+    ]
+
+
+class JsonLdSerializer(serializers.Serializer):
+    def run_validation(self, data=empty):
+        if data and data is not empty and self.context.get("expand", True):
+            try:
+                data = expand(data)
+            except ValueError:
+                raise serializers.ValidationError(
+                    "{} is not a valid jsonld document".format(data)
+                )
+            try:
+                config = self.Meta.jsonld_mapping
+            except AttributeError:
+                config = {}
+            try:
+                fallbacks = self.Meta.jsonld_fallbacks
+            except AttributeError:
+                fallbacks = {}
+            data = prepare_for_serializer(data, config, fallbacks=fallbacks)
+            dereferenced_fields = [
+                k
+                for k, c in config.items()
+                if k in data and c.get("dereference", False)
+            ]
+            dereferenced_ids = set()
+            for field in dereferenced_fields:
+                for i in get_ids(data[field]):
+                    dereferenced_ids.add(i)
+
+            if dereferenced_ids:
+                try:
+                    loop = asyncio.get_event_loop()
+                except RuntimeError:
+                    loop = asyncio.new_event_loop()
+                references = self.context.setdefault("references", {})
+                loop.run_until_complete(
+                    fetch_many(*dereferenced_ids, references=references)
+                )
+                data = dereference(data, references)
+        return super().run_validation(data)
+
+
+def first_attr(property, attr, aliases=[]):
+    return {"property": property, "keep": "first", "attr": attr, "aliases": aliases}
+
+
+def first_val(property, aliases=[]):
+    return first_attr(property, "@value", aliases=aliases)
+
+
+def first_id(property, aliases=[]):
+    return first_attr(property, "@id", aliases=aliases)
+
+
+def first_obj(property, aliases=[]):
+    return {"property": property, "keep": "first", "aliases": aliases}
+
+
+def raw(property, aliases=[]):
+    return {"property": property, "aliases": aliases}
diff --git a/api/funkwhale_api/federation/migrations/0017_auto_20190130_0926.py b/api/funkwhale_api/federation/migrations/0017_auto_20190130_0926.py
new file mode 100644
index 0000000000000000000000000000000000000000..7c025fa48bf637cced238317b09a26b1d3b46ea7
--- /dev/null
+++ b/api/funkwhale_api/federation/migrations/0017_auto_20190130_0926.py
@@ -0,0 +1,36 @@
+# Generated by Django 2.1.5 on 2019-01-30 09:26
+
+import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
+import django.db.models.deletion
+import funkwhale_api.common.validators
+import funkwhale_api.federation.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('federation', '0016_auto_20181227_1605'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='actor',
+            name='old_domain',
+        ),
+        migrations.AddField(
+            model_name='domain',
+            name='service_actor',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='managed_domains', to='federation.Actor'),
+        ),
+        migrations.AlterField(
+            model_name='domain',
+            name='name',
+            field=models.CharField(max_length=255, primary_key=True, serialize=False, validators=[funkwhale_api.common.validators.DomainValidator()]),
+        ),
+        migrations.AlterField(
+            model_name='domain',
+            name='nodeinfo',
+            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=funkwhale_api.federation.models.empty_dict, max_length=50000),
+        ),
+    ]
diff --git a/api/funkwhale_api/federation/migrations/0018_fetch.py b/api/funkwhale_api/federation/migrations/0018_fetch.py
new file mode 100644
index 0000000000000000000000000000000000000000..11789024fd022cfe25a2cded4984eda34cde6c9d
--- /dev/null
+++ b/api/funkwhale_api/federation/migrations/0018_fetch.py
@@ -0,0 +1,33 @@
+# Generated by Django 2.1.7 on 2019-04-17 14:57
+
+import django.contrib.postgres.fields.jsonb
+import django.core.serializers.json
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import funkwhale_api.federation.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('federation', '0017_auto_20190130_0926'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Fetch',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('url', models.URLField(db_index=True, max_length=500)),
+                ('creation_date', models.DateTimeField(default=django.utils.timezone.now)),
+                ('fetch_date', models.DateTimeField(blank=True, null=True)),
+                ('object_id', models.IntegerField(null=True)),
+                ('status', models.CharField(choices=[('pending', 'Pending'), ('errored', 'Errored'), ('finished', 'Finished'), ('skipped', 'Skipped')], default='pending', max_length=20)),
+                ('detail', django.contrib.postgres.fields.jsonb.JSONField(default=funkwhale_api.federation.models.empty_dict, encoder=django.core.serializers.json.DjangoJSONEncoder, max_length=50000)),
+                ('actor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fetches', to='federation.Actor')),
+                ('object_content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
+            ],
+        ),
+    ]
diff --git a/api/funkwhale_api/federation/models.py b/api/funkwhale_api/federation/models.py
index 843d538e0dd438e1778b6970b010ea50018d06fb..d530c62df1007d4012609eec6fd530ed347cacb2 100644
--- a/api/funkwhale_api/federation/models.py
+++ b/api/funkwhale_api/federation/models.py
@@ -1,4 +1,5 @@
 import tempfile
+import urllib.parse
 import uuid
 
 from django.conf import settings
@@ -43,10 +44,24 @@ class FederationMixin(models.Model):
     class Meta:
         abstract = True
 
+    @property
+    def is_local(self):
+        return federation_utils.is_local(self.fid)
+
+    @property
+    def domain_name(self):
+        if not self.fid:
+            return
+
+        parsed = urllib.parse.urlparse(self.fid)
+        return parsed.hostname
+
 
 class ActorQuerySet(models.QuerySet):
     def local(self, include=True):
-        return self.exclude(user__isnull=include)
+        if include:
+            return self.filter(domain__name=settings.FEDERATION_HOSTNAME)
+        return self.exclude(domain__name=settings.FEDERATION_HOSTNAME)
 
     def with_current_usage(self):
         qs = self
@@ -96,7 +111,13 @@ class Domain(models.Model):
     creation_date = models.DateTimeField(default=timezone.now)
     nodeinfo_fetch_date = models.DateTimeField(default=None, null=True, blank=True)
     nodeinfo = JSONField(default=empty_dict, max_length=50000, blank=True)
-
+    service_actor = models.ForeignKey(
+        "Actor",
+        related_name="managed_domains",
+        on_delete=models.SET_NULL,
+        null=True,
+        blank=True,
+    )
     objects = DomainQuerySet.as_manager()
 
     def __str__(self):
@@ -143,6 +164,10 @@ class Domain(models.Model):
         )
         return data
 
+    @property
+    def is_local(self):
+        return self.name == settings.FEDERATION_HOSTNAME
+
 
 class Actor(models.Model):
     ap_type = "Actor"
@@ -256,6 +281,76 @@ class Actor(models.Model):
         self.private_key = v[0].decode("utf-8")
         self.public_key = v[1].decode("utf-8")
 
+    def can_manage(self, obj):
+        attributed_to = getattr(obj, "attributed_to_id", None)
+        if attributed_to is not None and attributed_to == self.pk:
+            # easiest case, the obj is attributed to the actor
+            return True
+
+        if self.domain.service_actor_id != self.pk:
+            # actor is not system actor, so there is no way the actor can manage
+            # the object
+            return False
+
+        # actor is service actor of its domain, so if the fid domain
+        # matches, we consider the actor has the permission to manage
+        # the object
+        domain = self.domain_id
+        return obj.fid.startswith("http://{}/".format(domain)) or obj.fid.startswith(
+            "https://{}/".format(domain)
+        )
+
+
+FETCH_STATUSES = [
+    ("pending", "Pending"),
+    ("errored", "Errored"),
+    ("finished", "Finished"),
+    ("skipped", "Skipped"),
+]
+
+
+class FetchQuerySet(models.QuerySet):
+    def get_for_object(self, object):
+        content_type = ContentType.objects.get_for_model(object)
+        return self.filter(object_content_type=content_type, object_id=object.pk)
+
+
+class Fetch(models.Model):
+    url = models.URLField(max_length=500, db_index=True)
+    creation_date = models.DateTimeField(default=timezone.now)
+    fetch_date = models.DateTimeField(null=True, blank=True)
+    object_id = models.IntegerField(null=True)
+    object_content_type = models.ForeignKey(
+        ContentType, null=True, on_delete=models.CASCADE
+    )
+    object = GenericForeignKey("object_content_type", "object_id")
+    status = models.CharField(default="pending", choices=FETCH_STATUSES, max_length=20)
+    detail = JSONField(
+        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
+    )
+    actor = models.ForeignKey(Actor, related_name="fetches", on_delete=models.CASCADE)
+
+    objects = FetchQuerySet.as_manager()
+
+    def save(self, **kwargs):
+        if not self.url and self.object:
+            self.url = self.object.fid
+
+        super().save(**kwargs)
+
+    @property
+    def serializers(self):
+        from . import contexts
+        from . import serializers
+
+        return {
+            contexts.FW.Artist: serializers.ArtistSerializer,
+            contexts.FW.Album: serializers.AlbumSerializer,
+            contexts.FW.Track: serializers.TrackSerializer,
+            contexts.AS.Audio: serializers.UploadSerializer,
+            contexts.FW.Library: serializers.LibrarySerializer,
+        }
+
 
 class InboxItem(models.Model):
     """
@@ -297,7 +392,9 @@ class Activity(models.Model):
     uuid = models.UUIDField(default=uuid.uuid4, unique=True)
     fid = models.URLField(unique=True, max_length=500, null=True, blank=True)
     url = models.URLField(max_length=500, null=True, blank=True)
-    payload = JSONField(default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder)
+    payload = JSONField(
+        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
+    )
     creation_date = models.DateTimeField(default=timezone.now, db_index=True)
     type = models.CharField(db_index=True, null=True, max_length=100)
 
@@ -413,7 +510,7 @@ class LibraryTrack(models.Model):
     album_title = models.CharField(max_length=500)
     title = models.CharField(max_length=500)
     metadata = JSONField(
-        default=empty_dict, max_length=10000, encoder=DjangoJSONEncoder
+        default=empty_dict, max_length=10000, encoder=DjangoJSONEncoder, blank=True
     )
 
     @property
diff --git a/api/funkwhale_api/federation/renderers.py b/api/funkwhale_api/federation/renderers.py
index d72c4c06a298b5bb143d620ad4a0c2a72759c3d7..a92658e595b749783a4cf3a00320dc7b1f0f8c9a 100644
--- a/api/funkwhale_api/federation/renderers.py
+++ b/api/funkwhale_api/federation/renderers.py
@@ -1,8 +1,17 @@
 from rest_framework.renderers import JSONRenderer
 
 
-class ActivityPubRenderer(JSONRenderer):
-    media_type = "application/activity+json"
+def get_ap_renderers():
+    MEDIA_TYPES = [
+        ("APActivity", "application/activity+json"),
+        ("APLD", "application/ld+json"),
+        ("APJSON", "application/json"),
+    ]
+
+    return [
+        type(name, (JSONRenderer,), {"media_type": media_type})
+        for name, media_type in MEDIA_TYPES
+    ]
 
 
 class WebfingerRenderer(JSONRenderer):
diff --git a/api/funkwhale_api/federation/routes.py b/api/funkwhale_api/federation/routes.py
index 0295aa46ce4004648075371be181b64072c773e9..bae2812cea0c678d1024e96a4b50233528cb8e2e 100644
--- a/api/funkwhale_api/federation/routes.py
+++ b/api/funkwhale_api/federation/routes.py
@@ -3,6 +3,7 @@ import logging
 from funkwhale_api.music import models as music_models
 
 from . import activity
+from . import actors
 from . import serializers
 
 logger = logging.getLogger(__name__)
@@ -269,3 +270,113 @@ def outbox_delete_audio(context):
             serializer.data, to=[{"type": "followers", "target": library}]
         ),
     }
+
+
+def handle_library_entry_update(payload, context, queryset, serializer_class):
+    actor = context["actor"]
+    obj_id = payload["object"].get("id")
+    if not obj_id:
+        logger.debug("Discarding update of empty obj")
+        return
+
+    try:
+        obj = queryset.select_related("attributed_to").get(fid=obj_id)
+    except queryset.model.DoesNotExist:
+        logger.debug("Discarding update of unkwnown obj %s", obj_id)
+        return
+    if not actor.can_manage(obj):
+        logger.debug(
+            "Discarding unauthorize update of obj %s from %s", obj_id, actor.fid
+        )
+        return
+
+    serializer = serializer_class(obj, data=payload["object"])
+    if serializer.is_valid():
+        serializer.save()
+    else:
+        logger.debug(
+            "Discarding update of obj %s because of payload errors: %s",
+            obj_id,
+            serializer.errors,
+        )
+
+
+@inbox.register({"type": "Update", "object.type": "Track"})
+def inbox_update_track(payload, context):
+    return handle_library_entry_update(
+        payload,
+        context,
+        queryset=music_models.Track.objects.all(),
+        serializer_class=serializers.TrackSerializer,
+    )
+
+
+@inbox.register({"type": "Update", "object.type": "Artist"})
+def inbox_update_artist(payload, context):
+    return handle_library_entry_update(
+        payload,
+        context,
+        queryset=music_models.Artist.objects.all(),
+        serializer_class=serializers.ArtistSerializer,
+    )
+
+
+@inbox.register({"type": "Update", "object.type": "Album"})
+def inbox_update_album(payload, context):
+    return handle_library_entry_update(
+        payload,
+        context,
+        queryset=music_models.Album.objects.all(),
+        serializer_class=serializers.AlbumSerializer,
+    )
+
+
+@outbox.register({"type": "Update", "object.type": "Track"})
+def outbox_update_track(context):
+    track = context["track"]
+    serializer = serializers.ActivitySerializer(
+        {"type": "Update", "object": serializers.TrackSerializer(track).data}
+    )
+
+    yield {
+        "type": "Update",
+        "actor": actors.get_service_actor(),
+        "payload": with_recipients(
+            serializer.data,
+            to=[activity.PUBLIC_ADDRESS, {"type": "instances_with_followers"}],
+        ),
+    }
+
+
+@outbox.register({"type": "Update", "object.type": "Album"})
+def outbox_update_album(context):
+    album = context["album"]
+    serializer = serializers.ActivitySerializer(
+        {"type": "Update", "object": serializers.AlbumSerializer(album).data}
+    )
+
+    yield {
+        "type": "Update",
+        "actor": actors.get_service_actor(),
+        "payload": with_recipients(
+            serializer.data,
+            to=[activity.PUBLIC_ADDRESS, {"type": "instances_with_followers"}],
+        ),
+    }
+
+
+@outbox.register({"type": "Update", "object.type": "Artist"})
+def outbox_update_artist(context):
+    artist = context["artist"]
+    serializer = serializers.ActivitySerializer(
+        {"type": "Update", "object": serializers.ArtistSerializer(artist).data}
+    )
+
+    yield {
+        "type": "Update",
+        "actor": actors.get_service_actor(),
+        "payload": with_recipients(
+            serializer.data,
+            to=[activity.PUBLIC_ADDRESS, {"type": "instances_with_followers"}],
+        ),
+    }
diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py
index f873e197f9afe405ecb8c9dd46a70d84e7dce67f..473585fe7f56d1d519bf2e721bc982da4b31fbb5 100644
--- a/api/funkwhale_api/federation/serializers.py
+++ b/api/funkwhale_api/federation/serializers.py
@@ -1,30 +1,35 @@
 import logging
 import mimetypes
 import urllib.parse
+import uuid
 
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.paginator import Paginator
 from rest_framework import serializers
 
 from funkwhale_api.common import utils as funkwhale_utils
+from funkwhale_api.music import licenses
 from funkwhale_api.music import models as music_models
+from funkwhale_api.music import tasks as music_tasks
 
-from . import activity, models, utils
+from . import activity, actors, contexts, jsonld, models, tasks, utils
 
-AP_CONTEXT = [
-    "https://www.w3.org/ns/activitystreams",
-    "https://w3id.org/security/v1",
-    {},
-]
+AP_CONTEXT = jsonld.get_default_context()
 
 logger = logging.getLogger(__name__)
 
 
-class LinkSerializer(serializers.Serializer):
-    type = serializers.ChoiceField(choices=["Link"])
+class LinkSerializer(jsonld.JsonLdSerializer):
+    type = serializers.ChoiceField(choices=[contexts.AS.Link])
     href = serializers.URLField(max_length=500)
     mediaType = serializers.CharField()
 
+    class Meta:
+        jsonld_mapping = {
+            "href": jsonld.first_id(contexts.AS.href),
+            "mediaType": jsonld.first_val(contexts.AS.mediaType),
+        }
+
     def __init__(self, *args, **kwargs):
         self.allowed_mimetypes = kwargs.pop("allowed_mimetypes", [])
         super().__init__(*args, **kwargs)
@@ -45,18 +50,52 @@ class LinkSerializer(serializers.Serializer):
         )
 
 
-class ActorSerializer(serializers.Serializer):
+class EndpointsSerializer(jsonld.JsonLdSerializer):
+    sharedInbox = serializers.URLField(max_length=500, required=False)
+
+    class Meta:
+        jsonld_mapping = {"sharedInbox": jsonld.first_id(contexts.AS.sharedInbox)}
+
+
+class PublicKeySerializer(jsonld.JsonLdSerializer):
+    publicKeyPem = serializers.CharField(trim_whitespace=False)
+
+    class Meta:
+        jsonld_mapping = {"publicKeyPem": jsonld.first_val(contexts.SEC.publicKeyPem)}
+
+
+class ActorSerializer(jsonld.JsonLdSerializer):
     id = serializers.URLField(max_length=500)
     outbox = serializers.URLField(max_length=500)
     inbox = serializers.URLField(max_length=500)
-    type = serializers.ChoiceField(choices=models.TYPE_CHOICES)
+    type = serializers.ChoiceField(
+        choices=[getattr(contexts.AS, c[0]) for c in models.TYPE_CHOICES]
+    )
     preferredUsername = serializers.CharField()
     manuallyApprovesFollowers = serializers.NullBooleanField(required=False)
     name = serializers.CharField(required=False, max_length=200)
     summary = serializers.CharField(max_length=None, required=False)
     followers = serializers.URLField(max_length=500)
     following = serializers.URLField(max_length=500, required=False, allow_null=True)
-    publicKey = serializers.JSONField(required=False)
+    publicKey = PublicKeySerializer(required=False)
+    endpoints = EndpointsSerializer(required=False)
+
+    class Meta:
+        jsonld_mapping = {
+            "outbox": jsonld.first_id(contexts.AS.outbox),
+            "inbox": jsonld.first_id(contexts.LDP.inbox),
+            "following": jsonld.first_id(contexts.AS.following),
+            "followers": jsonld.first_id(contexts.AS.followers),
+            "preferredUsername": jsonld.first_val(contexts.AS.preferredUsername),
+            "summary": jsonld.first_val(contexts.AS.summary),
+            "name": jsonld.first_val(contexts.AS.name),
+            "publicKey": jsonld.first_obj(contexts.SEC.publicKey),
+            "manuallyApprovesFollowers": jsonld.first_val(
+                contexts.AS.manuallyApprovesFollowers
+            ),
+            "mediaType": jsonld.first_val(contexts.AS.mediaType),
+            "endpoints": jsonld.first_obj(contexts.AS.endpoints),
+        }
 
     def to_representation(self, instance):
         ret = {
@@ -91,7 +130,7 @@ class ActorSerializer(serializers.Serializer):
             if instance.user.avatar:
                 ret["icon"] = {
                     "type": "Image",
-                    "mediaType": mimetypes.guess_type(instance.user.avatar.path)[0],
+                    "mediaType": mimetypes.guess_type(instance.user.avatar_path)[0],
                     "url": utils.full_url(instance.user.avatar.crop["400x400"].url),
                 }
         except ObjectDoesNotExist:
@@ -114,17 +153,25 @@ class ActorSerializer(serializers.Serializer):
         if maf is not None:
             kwargs["manually_approves_followers"] = maf
         domain = urllib.parse.urlparse(kwargs["fid"]).netloc
-        kwargs["domain"] = models.Domain.objects.get_or_create(pk=domain)[0]
-        for endpoint, url in self.initial_data.get("endpoints", {}).items():
+        domain, domain_created = models.Domain.objects.get_or_create(pk=domain)
+        if domain_created and not domain.is_local:
+            # first time we see the domain, we trigger nodeinfo fetching
+            tasks.update_domain_nodeinfo(domain_name=domain.name)
+
+        kwargs["domain"] = domain
+        for endpoint, url in self.validated_data.get("endpoints", {}).items():
             if endpoint == "sharedInbox":
                 kwargs["shared_inbox_url"] = url
                 break
         try:
-            kwargs["public_key"] = self.initial_data["publicKey"]["publicKeyPem"]
+            kwargs["public_key"] = self.validated_data["publicKey"]["publicKeyPem"]
         except KeyError:
             pass
         return kwargs
 
+    def validate_type(self, v):
+        return v.split("#")[-1]
+
     def build(self):
         d = self.prepare_missing_fields()
         return models.Actor(**d)
@@ -251,11 +298,29 @@ class FollowSerializer(serializers.Serializer):
             follow_class = models.Follow
         defaults = kwargs
         defaults["fid"] = self.validated_data["id"]
-        return follow_class.objects.update_or_create(
+        approved = kwargs.pop("approved", None)
+        follow, created = follow_class.objects.update_or_create(
             actor=self.validated_data["actor"],
             target=self.validated_data["object"],
             defaults=defaults,
-        )[0]
+        )
+        if not created:
+            # We likely received a new follow when we had an existing one in database
+            # this can happen when two instances are out of sync, e.g because some
+            # messages are not delivered properly. In this case, we don't change
+            # the follow approved status and return the follow as is.
+            # We set a new UUID to ensure the follow urls are updated properly
+            # cf #830
+            follow.uuid = uuid.uuid4()
+            follow.save(update_fields=["uuid"])
+            return follow
+
+        # it's a brand new follow, we use the approved value stored earlier
+        if approved != follow.approved:
+            follow.approved = approved
+            follow.save(update_fields=["approved"])
+
+        return follow
 
     def to_representation(self, instance):
         return {
@@ -507,14 +572,40 @@ def get_additional_fields(data):
     return additional_fields
 
 
-class PaginatedCollectionSerializer(serializers.Serializer):
-    type = serializers.ChoiceField(choices=["Collection"])
+PAGINATED_COLLECTION_JSONLD_MAPPING = {
+    "totalItems": jsonld.first_val(contexts.AS.totalItems),
+    "actor": jsonld.first_id(contexts.AS.actor),
+    "attributedTo": jsonld.first_id(contexts.AS.attributedTo),
+    "first": jsonld.first_id(contexts.AS.first),
+    "last": jsonld.first_id(contexts.AS.last),
+    "partOf": jsonld.first_id(contexts.AS.partOf),
+}
+
+
+class PaginatedCollectionSerializer(jsonld.JsonLdSerializer):
+    type = serializers.ChoiceField(choices=[contexts.AS.Collection])
     totalItems = serializers.IntegerField(min_value=0)
-    actor = serializers.URLField(max_length=500)
+    actor = serializers.URLField(max_length=500, required=False)
+    attributedTo = serializers.URLField(max_length=500, required=False)
     id = serializers.URLField(max_length=500)
     first = serializers.URLField(max_length=500)
     last = serializers.URLField(max_length=500)
 
+    class Meta:
+        jsonld_mapping = PAGINATED_COLLECTION_JSONLD_MAPPING
+
+    def validate(self, validated_data):
+        d = super().validate(validated_data)
+        actor = d.get("actor")
+        attributed_to = d.get("attributedTo")
+        if not actor and not attributed_to:
+            raise serializers.ValidationError(
+                "You need to provide at least actor or attributedTo"
+            )
+
+        d["attributedTo"] = attributed_to or actor
+        return d
+
     def to_representation(self, conf):
         paginator = Paginator(conf["items"], conf.get("page_size", 20))
         first = funkwhale_utils.set_query_parameter(conf["id"], page=1)
@@ -522,7 +613,9 @@ class PaginatedCollectionSerializer(serializers.Serializer):
         last = funkwhale_utils.set_query_parameter(conf["id"], page=paginator.num_pages)
         d = {
             "id": conf["id"],
+            # XXX Stable release: remove the obsolete actor field
             "actor": conf["actor"].fid,
+            "attributedTo": conf["actor"].fid,
             "totalItems": paginator.count,
             "type": conf.get("type", "Collection"),
             "current": current,
@@ -536,64 +629,77 @@ class PaginatedCollectionSerializer(serializers.Serializer):
 
 
 class LibrarySerializer(PaginatedCollectionSerializer):
-    type = serializers.ChoiceField(choices=["Library"])
+    type = serializers.ChoiceField(
+        choices=[contexts.AS.Collection, contexts.FW.Library]
+    )
     name = serializers.CharField()
     summary = serializers.CharField(allow_blank=True, allow_null=True, required=False)
     followers = serializers.URLField(max_length=500)
     audience = serializers.ChoiceField(
-        choices=["", None, "https://www.w3.org/ns/activitystreams#Public"],
+        choices=["", "./", None, "https://www.w3.org/ns/activitystreams#Public"],
         required=False,
         allow_null=True,
         allow_blank=True,
     )
 
+    class Meta:
+        jsonld_mapping = funkwhale_utils.concat_dicts(
+            PAGINATED_COLLECTION_JSONLD_MAPPING,
+            {
+                "name": jsonld.first_val(contexts.AS.name),
+                "summary": jsonld.first_val(contexts.AS.summary),
+                "audience": jsonld.first_id(contexts.AS.audience),
+                "followers": jsonld.first_id(contexts.AS.followers),
+            },
+        )
+
     def to_representation(self, library):
         conf = {
             "id": library.fid,
             "name": library.name,
             "summary": library.description,
             "page_size": 100,
+            # XXX Stable release: remove the obsolete actor field
             "actor": library.actor,
+            "attributedTo": library.actor,
             "items": library.uploads.for_federation(),
             "type": "Library",
         }
         r = super().to_representation(conf)
         r["audience"] = (
-            "https://www.w3.org/ns/activitystreams#Public"
-            if library.privacy_level == "everyone"
-            else ""
+            contexts.AS.Public if library.privacy_level == "everyone" else ""
         )
         r["followers"] = library.followers_url
         return r
 
     def create(self, validated_data):
         actor = utils.retrieve_ap_object(
-            validated_data["actor"],
+            validated_data["attributedTo"],
+            actor=self.context.get("fetch_actor"),
             queryset=models.Actor,
             serializer_class=ActorSerializer,
         )
+        privacy = {"": "me", "./": "me", None: "me", contexts.AS.Public: "everyone"}
         library, created = music_models.Library.objects.update_or_create(
             fid=validated_data["id"],
             actor=actor,
             defaults={
                 "uploads_count": validated_data["totalItems"],
                 "name": validated_data["name"],
-                "description": validated_data["summary"],
+                "description": validated_data.get("summary"),
                 "followers_url": validated_data["followers"],
-                "privacy_level": "everyone"
-                if validated_data["audience"]
-                == "https://www.w3.org/ns/activitystreams#Public"
-                else "me",
+                "privacy_level": privacy[validated_data["audience"]],
             },
         )
         return library
 
 
-class CollectionPageSerializer(serializers.Serializer):
-    type = serializers.ChoiceField(choices=["CollectionPage"])
+class CollectionPageSerializer(jsonld.JsonLdSerializer):
+    type = serializers.ChoiceField(choices=[contexts.AS.CollectionPage])
     totalItems = serializers.IntegerField(min_value=0)
     items = serializers.ListField()
-    actor = serializers.URLField(max_length=500)
+    actor = serializers.URLField(max_length=500, required=False)
+    attributedTo = serializers.URLField(max_length=500, required=False)
     id = serializers.URLField(max_length=500)
     first = serializers.URLField(max_length=500)
     last = serializers.URLField(max_length=500)
@@ -601,6 +707,19 @@ class CollectionPageSerializer(serializers.Serializer):
     prev = serializers.URLField(max_length=500, required=False)
     partOf = serializers.URLField(max_length=500)
 
+    class Meta:
+        jsonld_mapping = {
+            "totalItems": jsonld.first_val(contexts.AS.totalItems),
+            "items": jsonld.raw(contexts.AS.items),
+            "actor": jsonld.first_id(contexts.AS.actor),
+            "attributedTo": jsonld.first_id(contexts.AS.attributedTo),
+            "first": jsonld.first_id(contexts.AS.first),
+            "last": jsonld.first_id(contexts.AS.last),
+            "next": jsonld.first_id(contexts.AS.next),
+            "prev": jsonld.first_id(contexts.AS.prev),
+            "partOf": jsonld.first_id(contexts.AS.partOf),
+        }
+
     def validate_items(self, v):
         item_serializer = self.context.get("item_serializer")
         if not item_serializer:
@@ -626,7 +745,9 @@ class CollectionPageSerializer(serializers.Serializer):
         d = {
             "id": id,
             "partOf": conf["id"],
+            # XXX Stable release: remove the obsolete actor field
             "actor": conf["actor"].fid,
+            "attributedTo": conf["actor"].fid,
             "totalItems": page.paginator.count,
             "type": "CollectionPage",
             "first": first,
@@ -654,14 +775,46 @@ class CollectionPageSerializer(serializers.Serializer):
         return d
 
 
-class MusicEntitySerializer(serializers.Serializer):
+MUSIC_ENTITY_JSONLD_MAPPING = {
+    "name": jsonld.first_val(contexts.AS.name),
+    "published": jsonld.first_val(contexts.AS.published),
+    "musicbrainzId": jsonld.first_val(contexts.FW.musicbrainzId),
+    "attributedTo": jsonld.first_id(contexts.AS.attributedTo),
+}
+
+
+class MusicEntitySerializer(jsonld.JsonLdSerializer):
     id = serializers.URLField(max_length=500)
     published = serializers.DateTimeField()
     musicbrainzId = serializers.UUIDField(allow_null=True, required=False)
     name = serializers.CharField(max_length=1000)
+    attributedTo = serializers.URLField(max_length=500, allow_null=True, required=False)
+    updateable_fields = []
+
+    def update(self, instance, validated_data):
+        attributed_to_fid = validated_data.get("attributedTo")
+        if attributed_to_fid:
+            validated_data["attributedTo"] = actors.get_actor(attributed_to_fid)
+        updated_fields = funkwhale_utils.get_updated_fields(
+            self.updateable_fields, validated_data, instance
+        )
+        if updated_fields:
+            return music_tasks.update_library_entity(instance, updated_fields)
+
+        return instance
 
 
 class ArtistSerializer(MusicEntitySerializer):
+    updateable_fields = [
+        ("name", "name"),
+        ("musicbrainzId", "mbid"),
+        ("attributedTo", "attributed_to"),
+    ]
+
+    class Meta:
+        model = music_models.Artist
+        jsonld_mapping = MUSIC_ENTITY_JSONLD_MAPPING
+
     def to_representation(self, instance):
         d = {
             "type": "Artist",
@@ -669,6 +822,9 @@ class ArtistSerializer(MusicEntitySerializer):
             "name": instance.name,
             "published": instance.creation_date.isoformat(),
             "musicbrainzId": str(instance.mbid) if instance.mbid else None,
+            "attributedTo": instance.attributed_to.fid
+            if instance.attributed_to
+            else None,
         }
 
         if self.context.get("include_ap_context", self.parent is None):
@@ -682,6 +838,23 @@ class AlbumSerializer(MusicEntitySerializer):
     cover = LinkSerializer(
         allowed_mimetypes=["image/*"], allow_null=True, required=False
     )
+    updateable_fields = [
+        ("name", "title"),
+        ("musicbrainzId", "mbid"),
+        ("attributedTo", "attributed_to"),
+        ("released", "release_date"),
+    ]
+
+    class Meta:
+        model = music_models.Album
+        jsonld_mapping = funkwhale_utils.concat_dicts(
+            MUSIC_ENTITY_JSONLD_MAPPING,
+            {
+                "released": jsonld.first_val(contexts.FW.released),
+                "artists": jsonld.first_attr(contexts.FW.artists, "@list"),
+                "cover": jsonld.first_obj(contexts.FW.cover),
+            },
+        )
 
     def to_representation(self, instance):
         d = {
@@ -698,34 +871,21 @@ class AlbumSerializer(MusicEntitySerializer):
                     instance.artist, context={"include_ap_context": False}
                 ).data
             ],
+            "attributedTo": instance.attributed_to.fid
+            if instance.attributed_to
+            else None,
         }
         if instance.cover:
             d["cover"] = {
                 "type": "Link",
                 "href": utils.full_url(instance.cover.url),
-                "mediaType": mimetypes.guess_type(instance.cover.path)[0]
+                "mediaType": mimetypes.guess_type(instance.cover_path)[0]
                 or "image/jpeg",
             }
         if self.context.get("include_ap_context", self.parent is None):
             d["@context"] = AP_CONTEXT
         return d
 
-    def get_create_data(self, validated_data):
-        artist_data = validated_data["artists"][0]
-        artist = ArtistSerializer(
-            context={"activity": self.context.get("activity")}
-        ).create(artist_data)
-
-        return {
-            "mbid": validated_data.get("musicbrainzId"),
-            "fid": validated_data["id"],
-            "title": validated_data["name"],
-            "creation_date": validated_data["published"],
-            "artist": artist,
-            "release_date": validated_data.get("released"),
-            "from_activity": self.context.get("activity"),
-        }
-
 
 class TrackSerializer(MusicEntitySerializer):
     position = serializers.IntegerField(min_value=0, allow_null=True, required=False)
@@ -735,6 +895,30 @@ class TrackSerializer(MusicEntitySerializer):
     license = serializers.URLField(allow_null=True, required=False)
     copyright = serializers.CharField(allow_null=True, required=False)
 
+    updateable_fields = [
+        ("name", "title"),
+        ("musicbrainzId", "mbid"),
+        ("attributedTo", "attributed_to"),
+        ("disc", "disc_number"),
+        ("position", "position"),
+        ("copyright", "copyright"),
+        ("license", "license"),
+    ]
+
+    class Meta:
+        model = music_models.Track
+        jsonld_mapping = funkwhale_utils.concat_dicts(
+            MUSIC_ENTITY_JSONLD_MAPPING,
+            {
+                "album": jsonld.first_obj(contexts.FW.album),
+                "artists": jsonld.first_attr(contexts.FW.artists, "@list"),
+                "copyright": jsonld.first_val(contexts.FW.copyright),
+                "disc": jsonld.first_val(contexts.FW.disc),
+                "license": jsonld.first_id(contexts.FW.license),
+                "position": jsonld.first_val(contexts.FW.position),
+            },
+        )
+
     def to_representation(self, instance):
         d = {
             "type": "Track",
@@ -756,6 +940,9 @@ class TrackSerializer(MusicEntitySerializer):
             "album": AlbumSerializer(
                 instance.album, context={"include_ap_context": False}
             ).data,
+            "attributedTo": instance.attributed_to.fid
+            if instance.attributed_to
+            else None,
         }
 
         if self.context.get("include_ap_context", self.parent is None):
@@ -765,16 +952,56 @@ class TrackSerializer(MusicEntitySerializer):
     def create(self, validated_data):
         from funkwhale_api.music import tasks as music_tasks
 
-        metadata = music_tasks.federation_audio_track_to_metadata(validated_data)
+        references = {}
+        actors_to_fetch = set()
+        actors_to_fetch.add(
+            funkwhale_utils.recursive_getattr(
+                validated_data, "attributedTo", permissive=True
+            )
+        )
+        actors_to_fetch.add(
+            funkwhale_utils.recursive_getattr(
+                validated_data, "album.attributedTo", permissive=True
+            )
+        )
+        artists = (
+            funkwhale_utils.recursive_getattr(
+                validated_data, "artists", permissive=True
+            )
+            or []
+        )
+        album_artists = (
+            funkwhale_utils.recursive_getattr(
+                validated_data, "album.artists", permissive=True
+            )
+            or []
+        )
+        for artist in artists + album_artists:
+            actors_to_fetch.add(artist.get("attributedTo"))
+
+        for url in actors_to_fetch:
+            if not url:
+                continue
+            references[url] = actors.get_actor(url)
+
+        metadata = music_tasks.federation_audio_track_to_metadata(
+            validated_data, references
+        )
+
         from_activity = self.context.get("activity")
         if from_activity:
             metadata["from_activity_id"] = from_activity.pk
         track = music_tasks.get_track_from_import_metadata(metadata, update_cover=True)
         return track
 
+    def update(self, obj, validated_data):
+        if validated_data.get("license"):
+            validated_data["license"] = licenses.match(validated_data["license"])
+        return super().update(obj, validated_data)
+
 
-class UploadSerializer(serializers.Serializer):
-    type = serializers.ChoiceField(choices=["Audio"])
+class UploadSerializer(jsonld.JsonLdSerializer):
+    type = serializers.ChoiceField(choices=[contexts.AS.Audio])
     id = serializers.URLField(max_length=500)
     library = serializers.URLField(max_length=500)
     url = LinkSerializer(allowed_mimetypes=["audio/*"])
@@ -786,6 +1013,19 @@ class UploadSerializer(serializers.Serializer):
 
     track = TrackSerializer(required=True)
 
+    class Meta:
+        model = music_models.Upload
+        jsonld_mapping = {
+            "track": jsonld.first_obj(contexts.FW.track),
+            "library": jsonld.first_id(contexts.FW.library),
+            "url": jsonld.first_obj(contexts.AS.url),
+            "published": jsonld.first_val(contexts.AS.published),
+            "updated": jsonld.first_val(contexts.AS.updated),
+            "duration": jsonld.first_val(contexts.AS.duration),
+            "bitrate": jsonld.first_val(contexts.FW.bitrate),
+            "size": jsonld.first_val(contexts.FW.size),
+        }
+
     def validate_url(self, v):
         try:
             v["href"]
@@ -870,26 +1110,6 @@ class UploadSerializer(serializers.Serializer):
         return d
 
 
-class CollectionSerializer(serializers.Serializer):
-    def to_representation(self, conf):
-        d = {
-            "id": conf["id"],
-            "actor": conf["actor"].fid,
-            "totalItems": len(conf["items"]),
-            "type": "Collection",
-            "items": [
-                conf["item_serializer"](
-                    i, context={"actor": conf["actor"], "include_ap_context": False}
-                ).data
-                for i in conf["items"]
-            ],
-        }
-
-        if self.context.get("include_ap_context", True):
-            d["@context"] = AP_CONTEXT
-        return d
-
-
 class NodeInfoLinkSerializer(serializers.Serializer):
     href = serializers.URLField()
     rel = serializers.URLField()
diff --git a/api/funkwhale_api/federation/tasks.py b/api/funkwhale_api/federation/tasks.py
index e7aafc2e850e21e6014a9a452992a2c1d02c7639..f6471ef215f9a2528786407f7b24a29045e008e2 100644
--- a/api/funkwhale_api/federation/tasks.py
+++ b/api/funkwhale_api/federation/tasks.py
@@ -1,9 +1,11 @@
 import datetime
+import json
 import logging
 import os
 import requests
 
 from django.conf import settings
+from django.db import transaction
 from django.db.models import Q, F
 from django.utils import timezone
 from dynamic_preferences.registries import global_preferences_registry
@@ -11,13 +13,17 @@ from requests.exceptions import RequestException
 
 from funkwhale_api.common import preferences
 from funkwhale_api.common import session
+from funkwhale_api.common import utils as common_utils
 from funkwhale_api.music import models as music_models
 from funkwhale_api.taskapp import celery
 
+from . import actors
+from . import jsonld
 from . import keys
 from . import models, signing
 from . import serializers
 from . import routes
+from . import utils
 
 logger = logging.getLogger(__name__)
 
@@ -97,7 +103,8 @@ def dispatch_outbox(activity):
     inbox_items = activity.inbox_items.filter(is_read=False).select_related()
 
     if inbox_items.exists():
-        dispatch_inbox.delay(activity_id=activity.pk, call_handlers=False)
+        call_handlers = activity.type in ["Follow"]
+        dispatch_inbox.delay(activity_id=activity.pk, call_handlers=call_handlers)
 
     if not preferences.get("federation__enabled"):
         # federation is disabled, we only deliver to local recipients
@@ -185,9 +192,44 @@ def update_domain_nodeinfo(domain):
         nodeinfo = {"status": "ok", "payload": fetch_nodeinfo(domain.name)}
     except (requests.RequestException, serializers.serializers.ValidationError) as e:
         nodeinfo = {"status": "error", "error": str(e)}
+
+    service_actor_id = common_utils.recursive_getattr(
+        nodeinfo, "payload.metadata.actorId", permissive=True
+    )
+    try:
+        domain.service_actor = (
+            utils.retrieve_ap_object(
+                service_actor_id,
+                actor=actors.get_service_actor(),
+                queryset=models.Actor,
+                serializer_class=serializers.ActorSerializer,
+            )
+            if service_actor_id
+            else None
+        )
+    except (serializers.serializers.ValidationError, RequestException) as e:
+        logger.warning(
+            "Cannot fetch system actor for domain %s: %s", domain.name, str(e)
+        )
     domain.nodeinfo_fetch_date = now
     domain.nodeinfo = nodeinfo
-    domain.save(update_fields=["nodeinfo", "nodeinfo_fetch_date"])
+    domain.save(update_fields=["nodeinfo", "nodeinfo_fetch_date", "service_actor"])
+
+
+@celery.app.task(name="federation.refresh_nodeinfo_known_nodes")
+def refresh_nodeinfo_known_nodes():
+    """
+    Trigger a node info refresh on all nodes that weren't refreshed since
+    settings.NODEINFO_REFRESH_DELAY
+    """
+    limit = timezone.now() - datetime.timedelta(seconds=settings.NODEINFO_REFRESH_DELAY)
+    candidates = models.Domain.objects.external().exclude(
+        nodeinfo_fetch_date__gte=limit
+    )
+    names = candidates.values_list("name", flat=True)
+    logger.info("Launching periodic nodeinfo refresh on %s domains", len(names))
+    for domain_name in names:
+        update_domain_nodeinfo.delay(domain_name=domain_name)
 
 
 def delete_qs(qs):
@@ -240,3 +282,83 @@ def rotate_actor_key(actor):
     actor.private_key = pair[0].decode()
     actor.public_key = pair[1].decode()
     actor.save(update_fields=["private_key", "public_key"])
+
+
+@celery.app.task(name="federation.fetch")
+@transaction.atomic
+@celery.require_instance(
+    models.Fetch.objects.filter(status="pending").select_related("actor"), "fetch"
+)
+def fetch(fetch):
+    actor = fetch.actor
+    auth = signing.get_auth(actor.private_key, actor.private_key_id)
+
+    def error(code, **kwargs):
+        fetch.status = "errored"
+        fetch.fetch_date = timezone.now()
+        fetch.detail = {"error_code": code}
+        fetch.detail.update(kwargs)
+        fetch.save(update_fields=["fetch_date", "status", "detail"])
+
+    try:
+        response = session.get_session().get(
+            auth=auth,
+            url=fetch.url,
+            timeout=5,
+            verify=settings.EXTERNAL_REQUESTS_VERIFY_SSL,
+            headers={"Content-Type": "application/activity+json"},
+        )
+        logger.debug("Remote answered with %s", response.status_code)
+        response.raise_for_status()
+    except requests.exceptions.HTTPError as e:
+        return error("http", status_code=e.response.status_code if e.response else None)
+    except requests.exceptions.Timeout:
+        return error("timeout")
+    except requests.exceptions.ConnectionError as e:
+        return error("connection", message=str(e))
+    except requests.RequestException as e:
+        return error("request", message=str(e))
+    except Exception as e:
+        return error("unhandled", message=str(e))
+
+    try:
+        payload = response.json()
+    except json.decoder.JSONDecodeError:
+        return error("invalid_json")
+
+    try:
+        doc = jsonld.expand(payload)
+    except ValueError:
+        return error("invalid_jsonld")
+
+    try:
+        type = doc.get("@type", [])[0]
+    except IndexError:
+        return error("missing_jsonld_type")
+    try:
+        serializer_class = fetch.serializers[type]
+        model = serializer_class.Meta.model
+    except (KeyError, AttributeError):
+        fetch.status = "skipped"
+        fetch.fetch_date = timezone.now()
+        fetch.detail = {"reason": "unhandled_type", "type": type}
+        return fetch.save(update_fields=["fetch_date", "status", "detail"])
+    try:
+        id = doc.get("@id")
+    except IndexError:
+        existing = None
+    else:
+        existing = model.objects.filter(fid=id).first()
+
+    serializer = serializer_class(existing, data=payload)
+    if not serializer.is_valid():
+        return error("validation", validation_errors=serializer.errors)
+    try:
+        serializer.save()
+    except Exception as e:
+        error("save", message=str(e))
+        raise
+
+    fetch.status = "finished"
+    fetch.fetch_date = timezone.now()
+    return fetch.save(update_fields=["fetch_date", "status"])
diff --git a/api/funkwhale_api/federation/urls.py b/api/funkwhale_api/federation/urls.py
index f8347d1ebf47c2f300d6b7d0941809d7457d7ed2..f7d5006da0cdf50df601da96e78fc5b8e97d00ca 100644
--- a/api/funkwhale_api/federation/urls.py
+++ b/api/funkwhale_api/federation/urls.py
@@ -8,6 +8,7 @@ music_router = routers.SimpleRouter(trailing_slash=False)
 
 router.register(r"federation/shared", views.SharedViewSet, "shared")
 router.register(r"federation/actors", views.ActorViewSet, "actors")
+router.register(r"federation/edits", views.EditViewSet, "edits")
 router.register(r".well-known", views.WellKnownViewSet, "well-known")
 
 music_router.register(r"libraries", views.MusicLibraryViewSet, "libraries")
diff --git a/api/funkwhale_api/federation/utils.py b/api/funkwhale_api/federation/utils.py
index e49a4dd63c4f8140c8f8e52ed13cb095585927c7..8f73c57350a2290f4fea9e106859b460052a24c0 100644
--- a/api/funkwhale_api/federation/utils.py
+++ b/api/funkwhale_api/federation/utils.py
@@ -1,6 +1,7 @@
 import unicodedata
 import re
 from django.conf import settings
+from django.db.models import Q
 
 from funkwhale_api.common import session
 from funkwhale_api.moderation import models as moderation_models
@@ -61,7 +62,7 @@ def slugify_username(username):
 
 
 def retrieve_ap_object(
-    fid, actor=None, serializer_class=None, queryset=None, apply_instance_policies=True
+    fid, actor, serializer_class=None, queryset=None, apply_instance_policies=True
 ):
     from . import activity
 
@@ -100,10 +101,33 @@ def retrieve_ap_object(
     except KeyError:
         pass
     else:
-        if apply_instance_policies and activity.should_reject(id=id, payload=data):
+        if apply_instance_policies and activity.should_reject(fid=id, payload=data):
             raise exceptions.BlockedActorOrDomain()
     if not serializer_class:
         return data
-    serializer = serializer_class(data=data)
+    serializer = serializer_class(data=data, context={"fetch_actor": actor})
     serializer.is_valid(raise_exception=True)
     return serializer.save()
+
+
+def get_domain_query_from_url(domain, url_field="fid"):
+    """
+    Given a domain name and a field, will return a Q() object
+    to match objects that have this domain in the given field.
+    """
+
+    query = Q(**{"{}__startswith".format(url_field): "http://{}/".format(domain)})
+    query = query | Q(
+        **{"{}__startswith".format(url_field): "https://{}/".format(domain)}
+    )
+    return query
+
+
+def is_local(url):
+    if not url:
+        return True
+
+    d = settings.FEDERATION_HOSTNAME
+    return url.startswith("http://{}/".format(d)) or url.startswith(
+        "https://{}/".format(d)
+    )
diff --git a/api/funkwhale_api/federation/views.py b/api/funkwhale_api/federation/views.py
index 3b322e915144bec01e536640022402a1b20429bf..97bcebbfb374d5a765f30386ab430935d84f68f5 100644
--- a/api/funkwhale_api/federation/views.py
+++ b/api/funkwhale_api/federation/views.py
@@ -7,6 +7,7 @@ from rest_framework.decorators import action
 
 from funkwhale_api.common import preferences
 from funkwhale_api.music import models as music_models
+from funkwhale_api.music import utils as music_utils
 
 from . import activity, authentication, models, renderers, serializers, utils, webfinger
 
@@ -21,7 +22,7 @@ class FederationMixin(object):
 class SharedViewSet(FederationMixin, viewsets.GenericViewSet):
     permission_classes = []
     authentication_classes = [authentication.SignatureAuthentication]
-    renderer_classes = [renderers.ActivityPubRenderer]
+    renderer_classes = renderers.get_ap_renderers()
 
     @action(methods=["post"], detail=False)
     def inbox(self, request, *args, **kwargs):
@@ -38,7 +39,7 @@ class ActorViewSet(FederationMixin, mixins.RetrieveModelMixin, viewsets.GenericV
     lookup_field = "preferred_username"
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
-    renderer_classes = [renderers.ActivityPubRenderer]
+    renderer_classes = renderers.get_ap_renderers()
     queryset = models.Actor.objects.local().select_related("user")
     serializer_class = serializers.ActorSerializer
 
@@ -69,6 +70,15 @@ class ActorViewSet(FederationMixin, mixins.RetrieveModelMixin, viewsets.GenericV
         return response.Response({})
 
 
+class EditViewSet(FederationMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
+    lookup_field = "uuid"
+    authentication_classes = [authentication.SignatureAuthentication]
+    permission_classes = []
+    renderer_classes = renderers.get_ap_renderers()
+    # queryset = common_models.Mutation.objects.local().select_related()
+    # serializer_class = serializers.ActorSerializer
+
+
 class WellKnownViewSet(viewsets.GenericViewSet):
     authentication_classes = []
     permission_classes = []
@@ -137,7 +147,7 @@ class MusicLibraryViewSet(
 ):
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
-    renderer_classes = [renderers.ActivityPubRenderer]
+    renderer_classes = renderers.get_ap_renderers()
     serializer_class = serializers.LibrarySerializer
     queryset = music_models.Library.objects.all().select_related("actor")
     lookup_field = "uuid"
@@ -192,18 +202,27 @@ class MusicUploadViewSet(
 ):
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
-    renderer_classes = [renderers.ActivityPubRenderer]
-    queryset = music_models.Upload.objects.none()
+    renderer_classes = renderers.get_ap_renderers()
+    queryset = music_models.Upload.objects.local().select_related(
+        "library__actor", "track__artist", "track__album__artist"
+    )
+    serializer_class = serializers.UploadSerializer
     lookup_field = "uuid"
 
+    def get_queryset(self):
+        queryset = super().get_queryset()
+        actor = music_utils.get_actor_from_request(self.request)
+        return queryset.playable_by(actor)
+
 
 class MusicArtistViewSet(
     FederationMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet
 ):
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
-    renderer_classes = [renderers.ActivityPubRenderer]
-    queryset = music_models.Artist.objects.none()
+    renderer_classes = renderers.get_ap_renderers()
+    queryset = music_models.Artist.objects.local()
+    serializer_class = serializers.ArtistSerializer
     lookup_field = "uuid"
 
 
@@ -212,8 +231,9 @@ class MusicAlbumViewSet(
 ):
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
-    renderer_classes = [renderers.ActivityPubRenderer]
-    queryset = music_models.Album.objects.none()
+    renderer_classes = renderers.get_ap_renderers()
+    queryset = music_models.Album.objects.local().select_related("artist")
+    serializer_class = serializers.AlbumSerializer
     lookup_field = "uuid"
 
 
@@ -222,6 +242,9 @@ class MusicTrackViewSet(
 ):
     authentication_classes = [authentication.SignatureAuthentication]
     permission_classes = []
-    renderer_classes = [renderers.ActivityPubRenderer]
-    queryset = music_models.Track.objects.none()
+    renderer_classes = renderers.get_ap_renderers()
+    queryset = music_models.Track.objects.local().select_related(
+        "album__artist", "artist"
+    )
+    serializer_class = serializers.TrackSerializer
     lookup_field = "uuid"
diff --git a/api/funkwhale_api/history/filters.py b/api/funkwhale_api/history/filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..30bc78f6a9d0a10394a1d76bf2e5ea4de0c6e8aa
--- /dev/null
+++ b/api/funkwhale_api/history/filters.py
@@ -0,0 +1,12 @@
+from funkwhale_api.moderation import filters as moderation_filters
+
+from . import models
+
+
+class ListeningFilter(moderation_filters.HiddenContentFilterSet):
+    class Meta:
+        model = models.Listening
+        hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
+            "LISTENING"
+        ]
+        fields = ["hidden"]
diff --git a/api/funkwhale_api/history/views.py b/api/funkwhale_api/history/views.py
index 56c30af36511e8cf124645dfcd00f835e3a04287..30219629a4b0c5a2852d0cff1f9f04605604a654 100644
--- a/api/funkwhale_api/history/views.py
+++ b/api/funkwhale_api/history/views.py
@@ -1,5 +1,4 @@
 from rest_framework import mixins, viewsets
-from rest_framework.permissions import IsAuthenticatedOrReadOnly
 
 from django.db.models import Prefetch
 
@@ -7,7 +6,9 @@ from funkwhale_api.activity import record
 from funkwhale_api.common import fields, permissions
 from funkwhale_api.music.models import Track
 from funkwhale_api.music import utils as music_utils
-from . import models, serializers
+from . import filters, models, serializers
+
+from funkwhale_api.users.oauth import permissions as oauth_permissions
 
 
 class ListeningViewSet(
@@ -19,12 +20,15 @@ class ListeningViewSet(
 
     serializer_class = serializers.ListeningSerializer
     queryset = models.Listening.objects.all().select_related("user")
+
     permission_classes = [
-        permissions.ConditionalAuthentication,
+        oauth_permissions.ScopePermission,
         permissions.OwnerPermission,
-        IsAuthenticatedOrReadOnly,
     ]
+    required_scope = "listenings"
+    anonymous_policy = "setting"
     owner_checks = ["write"]
+    filterset_class = filters.ListeningFilter
 
     def get_serializer_class(self):
         if self.request.method.lower() in ["head", "get", "options"]:
diff --git a/api/funkwhale_api/instance/nodeinfo.py b/api/funkwhale_api/instance/nodeinfo.py
index 286cb0284f9d922c74b10d10b4cd5ee4f3a70d1f..f45fbb129402ac0437147ac8eff1147f99335d1b 100644
--- a/api/funkwhale_api/instance/nodeinfo.py
+++ b/api/funkwhale_api/instance/nodeinfo.py
@@ -2,6 +2,8 @@ import memoize.djangocache
 
 import funkwhale_api
 from funkwhale_api.common import preferences
+from funkwhale_api.federation import actors
+from funkwhale_api.music import utils as music_utils
 
 from . import stats
 
@@ -19,6 +21,7 @@ def get():
         "openRegistrations": preferences.get("users__registration_enabled"),
         "usage": {"users": {"total": 0, "activeHalfyear": 0, "activeMonth": 0}},
         "metadata": {
+            "actorId": actors.get_service_actor().fid,
             "private": preferences.get("instance__nodeinfo_private"),
             "shortDescription": preferences.get("instance__short_description"),
             "longDescription": preferences.get("instance__long_description"),
@@ -32,6 +35,7 @@ def get():
                     "common__api_authentication_required"
                 ),
             },
+            "supportedUploadExtensions": music_utils.SUPPORTED_EXTENSIONS,
         },
     }
     if share_stats:
diff --git a/api/funkwhale_api/instance/views.py b/api/funkwhale_api/instance/views.py
index ea6311033333ad0603a1f88d52fd51bda44ceeaa..1800c3dbc7e60bcc022f24dd3e64d6a0d45b8697 100644
--- a/api/funkwhale_api/instance/views.py
+++ b/api/funkwhale_api/instance/views.py
@@ -5,7 +5,7 @@ from rest_framework import views
 from rest_framework.response import Response
 
 from funkwhale_api.common import preferences
-from funkwhale_api.users.permissions import HasUserPermission
+from funkwhale_api.users.oauth import permissions as oauth_permissions
 
 from . import nodeinfo
 
@@ -14,8 +14,8 @@ NODEINFO_2_CONTENT_TYPE = "application/json; profile=http://nodeinfo.diaspora.so
 
 class AdminSettings(preferences_viewsets.GlobalPreferencesViewSet):
     pagination_class = None
-    permission_classes = (HasUserPermission,)
-    required_permissions = ["settings"]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "instance:settings"
 
 
 class InstanceSettings(views.APIView):
diff --git a/api/funkwhale_api/manage/filters.py b/api/funkwhale_api/manage/filters.py
index edae49f991bcb9f2a415f8f829df1a1e7d7c5248..984b83133734e81a87194de73016a4f0ca5ee11f 100644
--- a/api/funkwhale_api/manage/filters.py
+++ b/api/funkwhale_api/manage/filters.py
@@ -1,27 +1,238 @@
+from django import forms
+from django.db.models import Q
+from django.conf import settings
+
+import django_filters
 from django_filters import rest_framework as filters
 
 from funkwhale_api.common import fields
 from funkwhale_api.common import search
 
 from funkwhale_api.federation import models as federation_models
+from funkwhale_api.federation import utils as federation_utils
 from funkwhale_api.moderation import models as moderation_models
 from funkwhale_api.music import models as music_models
 from funkwhale_api.users import models as users_models
 
 
+class ActorField(forms.CharField):
+    def clean(self, value):
+        value = super().clean(value)
+        if not value:
+            return value
+
+        parts = value.split("@")
+
+        return {
+            "username": parts[0],
+            "domain": parts[1] if len(parts) > 1 else settings.FEDERATION_HOSTNAME,
+        }
+
+
+def get_actor_filter(actor_field):
+    def handler(v):
+        if not v:
+            return Q(**{actor_field: None})
+        return Q(
+            **{
+                "{}__preferred_username__iexact".format(actor_field): v["username"],
+                "{}__domain__name__iexact".format(actor_field): v["domain"],
+            }
+        )
+
+    return {"field": ActorField(), "handler": handler}
+
+
+class ManageArtistFilterSet(filters.FilterSet):
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "name": {"to": "name"},
+                "fid": {"to": "fid"},
+                "mbid": {"to": "mbid"},
+            },
+            filter_fields={
+                "uuid": {"to": "uuid"},
+                "domain": {
+                    "handler": lambda v: federation_utils.get_domain_query_from_url(v)
+                },
+                "library_id": {
+                    "to": "tracks__uploads__library_id",
+                    "field": forms.IntegerField(),
+                    "distinct": True,
+                },
+            },
+        )
+    )
+
+    class Meta:
+        model = music_models.Artist
+        fields = ["q", "name", "mbid", "fid"]
+
+
+class ManageAlbumFilterSet(filters.FilterSet):
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "title": {"to": "title"},
+                "fid": {"to": "fid"},
+                "artist": {"to": "artist__name"},
+                "mbid": {"to": "mbid"},
+            },
+            filter_fields={
+                "uuid": {"to": "uuid"},
+                "artist_id": {"to": "artist_id", "field": forms.IntegerField()},
+                "domain": {
+                    "handler": lambda v: federation_utils.get_domain_query_from_url(v)
+                },
+                "library_id": {
+                    "to": "tracks__uploads__library_id",
+                    "field": forms.IntegerField(),
+                    "distinct": True,
+                },
+            },
+        )
+    )
+
+    class Meta:
+        model = music_models.Album
+        fields = ["q", "title", "mbid", "fid", "artist"]
+
+
+class ManageTrackFilterSet(filters.FilterSet):
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "title": {"to": "title"},
+                "fid": {"to": "fid"},
+                "mbid": {"to": "mbid"},
+                "artist": {"to": "artist__name"},
+                "album": {"to": "album__title"},
+                "album_artist": {"to": "album__artist__name"},
+                "copyright": {"to": "copyright"},
+            },
+            filter_fields={
+                "album_id": {"to": "album_id", "field": forms.IntegerField()},
+                "album_artist_id": {
+                    "to": "album__artist_id",
+                    "field": forms.IntegerField(),
+                },
+                "artist_id": {"to": "artist_id", "field": forms.IntegerField()},
+                "uuid": {"to": "uuid"},
+                "license": {"to": "license"},
+                "domain": {
+                    "handler": lambda v: federation_utils.get_domain_query_from_url(v)
+                },
+                "library_id": {
+                    "to": "uploads__library_id",
+                    "field": forms.IntegerField(),
+                    "distinct": True,
+                },
+            },
+        )
+    )
+
+    class Meta:
+        model = music_models.Track
+        fields = ["q", "title", "mbid", "fid", "artist", "album", "license"]
+
+
+class ManageLibraryFilterSet(filters.FilterSet):
+    ordering = django_filters.OrderingFilter(
+        # tuple-mapping retains order
+        fields=(
+            ("creation_date", "creation_date"),
+            ("_uploads_count", "uploads_count"),
+            ("followers_count", "followers_count"),
+        )
+    )
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "name": {"to": "name"},
+                "description": {"to": "description"},
+                "fid": {"to": "fid"},
+            },
+            filter_fields={
+                "uuid": {"to": "uuid"},
+                "artist_id": {
+                    "to": "uploads__track__artist_id",
+                    "field": forms.IntegerField(),
+                    "distinct": True,
+                },
+                "album_id": {
+                    "to": "uploads__track__album_id",
+                    "field": forms.IntegerField(),
+                    "distinct": True,
+                },
+                "track_id": {
+                    "to": "uploads__track__id",
+                    "field": forms.IntegerField(),
+                    "distinct": True,
+                },
+                "domain": {"to": "actor__domain_id"},
+                "account": get_actor_filter("actor"),
+                "privacy_level": {"to": "privacy_level"},
+            },
+        )
+    )
+    domain = filters.CharFilter("actor__domain_id")
+
+    class Meta:
+        model = music_models.Library
+        fields = ["q", "name", "fid", "privacy_level", "domain"]
+
+
 class ManageUploadFilterSet(filters.FilterSet):
-    q = fields.SearchFilter(
-        search_fields=[
-            "track__title",
-            "track__album__title",
-            "track__artist__name",
-            "source",
-        ]
+    ordering = django_filters.OrderingFilter(
+        # tuple-mapping retains order
+        fields=(
+            ("creation_date", "creation_date"),
+            ("modification_date", "modification_date"),
+            ("accessed_date", "accessed_date"),
+            ("size", "size"),
+            ("bitrate", "bitrate"),
+            ("duration", "duration"),
+        )
+    )
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "source": {"to": "source"},
+                "fid": {"to": "fid"},
+                "track": {"to": "track__title"},
+                "album": {"to": "track__album__title"},
+                "artist": {"to": "track__artist__name"},
+            },
+            filter_fields={
+                "uuid": {"to": "uuid"},
+                "library_id": {"to": "library_id", "field": forms.IntegerField()},
+                "artist_id": {"to": "track__artist_id", "field": forms.IntegerField()},
+                "album_id": {"to": "track__album_id", "field": forms.IntegerField()},
+                "track_id": {"to": "track__id", "field": forms.IntegerField()},
+                "domain": {"to": "library__actor__domain_id"},
+                "import_reference": {"to": "import_reference"},
+                "type": {"to": "mimetype"},
+                "status": {"to": "import_status"},
+                "account": get_actor_filter("library__actor"),
+                "privacy_level": {"to": "library__privacy_level"},
+            },
+        )
     )
+    domain = filters.CharFilter("library__actor__domain_id")
+    privacy_level = filters.CharFilter("library__privacy_level")
 
     class Meta:
         model = music_models.Upload
-        fields = ["q", "track__album", "track__artist", "track"]
+        fields = [
+            "q",
+            "fid",
+            "privacy_level",
+            "domain",
+            "mimetype",
+            "import_reference",
+            "import_status",
+        ]
 
 
 class ManageDomainFilterSet(filters.FilterSet):
@@ -43,6 +254,7 @@ class ManageActorFilterSet(filters.FilterSet):
                 "type": {"to": "type"},
             },
             filter_fields={
+                "uuid": {"to": "uuid"},
                 "domain": {"to": "domain__name__iexact"},
                 "username": {"to": "preferred_username__iexact"},
                 "email": {"to": "user__email__iexact"},
@@ -60,7 +272,15 @@ class ManageActorFilterSet(filters.FilterSet):
 
 
 class ManageUserFilterSet(filters.FilterSet):
-    q = fields.SearchFilter(search_fields=["username", "email", "name"])
+    q = fields.SmartSearchFilter(
+        config=search.SearchConfig(
+            search_fields={
+                "name": {"to": "name"},
+                "username": {"to": "username"},
+                "email": {"to": "email"},
+            }
+        )
+    )
 
     class Meta:
         model = users_models.User
diff --git a/api/funkwhale_api/manage/serializers.py b/api/funkwhale_api/manage/serializers.py
index ed50d86777d30c7d8fc255944f5034f70a3f4bef..add9364e86a3fc9e7f82873fbbea15949a59fde4 100644
--- a/api/funkwhale_api/manage/serializers.py
+++ b/api/funkwhale_api/manage/serializers.py
@@ -9,72 +9,12 @@ from funkwhale_api.federation import fields as federation_fields
 from funkwhale_api.federation import tasks as federation_tasks
 from funkwhale_api.moderation import models as moderation_models
 from funkwhale_api.music import models as music_models
+from funkwhale_api.music import serializers as music_serializers
 from funkwhale_api.users import models as users_models
 
 from . import filters
 
 
-class ManageUploadArtistSerializer(serializers.ModelSerializer):
-    class Meta:
-        model = music_models.Artist
-        fields = ["id", "mbid", "creation_date", "name"]
-
-
-class ManageUploadAlbumSerializer(serializers.ModelSerializer):
-    artist = ManageUploadArtistSerializer()
-
-    class Meta:
-        model = music_models.Album
-        fields = (
-            "id",
-            "mbid",
-            "title",
-            "artist",
-            "release_date",
-            "cover",
-            "creation_date",
-        )
-
-
-class ManageUploadTrackSerializer(serializers.ModelSerializer):
-    artist = ManageUploadArtistSerializer()
-    album = ManageUploadAlbumSerializer()
-
-    class Meta:
-        model = music_models.Track
-        fields = ("id", "mbid", "title", "album", "artist", "creation_date", "position")
-
-
-class ManageUploadSerializer(serializers.ModelSerializer):
-    track = ManageUploadTrackSerializer()
-
-    class Meta:
-        model = music_models.Upload
-        fields = (
-            "id",
-            "path",
-            "source",
-            "filename",
-            "mimetype",
-            "track",
-            "duration",
-            "mimetype",
-            "creation_date",
-            "bitrate",
-            "size",
-            "path",
-        )
-
-
-class ManageUploadActionSerializer(common_serializers.ActionSerializer):
-    actions = [common_serializers.Action("delete", allow_all=False)]
-    filterset_class = filters.ManageUploadFilterSet
-
-    @transaction.atomic
-    def handle_delete(self, objects):
-        return objects.delete()
-
-
 class PermissionsSerializer(serializers.Serializer):
     def to_representation(self, o):
         return o.get_permissions(defaults=self.context.get("default_permissions"))
@@ -216,10 +156,7 @@ class ManageDomainActionSerializer(common_serializers.ActionSerializer):
         common_utils.on_commit(federation_tasks.purge_actors.delay, domains=list(ids))
 
 
-class ManageActorSerializer(serializers.ModelSerializer):
-    uploads_count = serializers.SerializerMethodField()
-    user = ManageUserSerializer()
-
+class ManageBaseActorSerializer(serializers.ModelSerializer):
     class Meta:
         model = federation_models.Actor
         fields = [
@@ -238,6 +175,17 @@ class ManageActorSerializer(serializers.ModelSerializer):
             "outbox_url",
             "shared_inbox_url",
             "manually_approves_followers",
+        ]
+        read_only_fields = ["creation_date", "instance_policy"]
+
+
+class ManageActorSerializer(ManageBaseActorSerializer):
+    uploads_count = serializers.SerializerMethodField()
+    user = ManageUserSerializer()
+
+    class Meta:
+        model = federation_models.Actor
+        fields = ManageBaseActorSerializer.Meta.fields + [
             "uploads_count",
             "user",
             "instance_policy",
@@ -339,3 +287,256 @@ class ManageInstancePolicySerializer(serializers.ModelSerializer):
                 )
 
         return instance
+
+
+class ManageBaseArtistSerializer(serializers.ModelSerializer):
+    domain = serializers.CharField(source="domain_name")
+
+    class Meta:
+        model = music_models.Artist
+        fields = ["id", "fid", "mbid", "name", "creation_date", "domain", "is_local"]
+
+
+class ManageBaseAlbumSerializer(serializers.ModelSerializer):
+    cover = music_serializers.cover_field
+    domain = serializers.CharField(source="domain_name")
+
+    class Meta:
+        model = music_models.Album
+        fields = [
+            "id",
+            "fid",
+            "mbid",
+            "title",
+            "creation_date",
+            "release_date",
+            "cover",
+            "domain",
+            "is_local",
+        ]
+
+
+class ManageNestedTrackSerializer(serializers.ModelSerializer):
+    domain = serializers.CharField(source="domain_name")
+
+    class Meta:
+        model = music_models.Track
+        fields = [
+            "id",
+            "fid",
+            "mbid",
+            "title",
+            "creation_date",
+            "position",
+            "disc_number",
+            "domain",
+            "is_local",
+            "copyright",
+            "license",
+        ]
+
+
+class ManageNestedAlbumSerializer(ManageBaseAlbumSerializer):
+
+    tracks_count = serializers.SerializerMethodField()
+
+    class Meta:
+        model = music_models.Album
+        fields = ManageBaseAlbumSerializer.Meta.fields + ["tracks_count"]
+
+    def get_tracks_count(self, obj):
+        return getattr(obj, "tracks_count", None)
+
+
+class ManageArtistSerializer(ManageBaseArtistSerializer):
+    albums = ManageNestedAlbumSerializer(many=True)
+    tracks = ManageNestedTrackSerializer(many=True)
+    attributed_to = ManageBaseActorSerializer()
+
+    class Meta:
+        model = music_models.Artist
+        fields = ManageBaseArtistSerializer.Meta.fields + [
+            "albums",
+            "tracks",
+            "attributed_to",
+        ]
+
+
+class ManageNestedArtistSerializer(ManageBaseArtistSerializer):
+    pass
+
+
+class ManageAlbumSerializer(ManageBaseAlbumSerializer):
+    tracks = ManageNestedTrackSerializer(many=True)
+    attributed_to = ManageBaseActorSerializer()
+    artist = ManageNestedArtistSerializer()
+
+    class Meta:
+        model = music_models.Album
+        fields = ManageBaseAlbumSerializer.Meta.fields + [
+            "artist",
+            "tracks",
+            "attributed_to",
+        ]
+
+
+class ManageTrackAlbumSerializer(ManageBaseAlbumSerializer):
+    artist = ManageNestedArtistSerializer()
+
+    class Meta:
+        model = music_models.Album
+        fields = ManageBaseAlbumSerializer.Meta.fields + ["artist"]
+
+
+class ManageTrackSerializer(ManageNestedTrackSerializer):
+    artist = ManageNestedArtistSerializer()
+    album = ManageTrackAlbumSerializer()
+    attributed_to = ManageBaseActorSerializer()
+    uploads_count = serializers.SerializerMethodField()
+
+    class Meta:
+        model = music_models.Track
+        fields = ManageNestedTrackSerializer.Meta.fields + [
+            "artist",
+            "album",
+            "attributed_to",
+            "uploads_count",
+        ]
+
+    def get_uploads_count(self, obj):
+        return getattr(obj, "uploads_count", None)
+
+
+class ManageTrackActionSerializer(common_serializers.ActionSerializer):
+    actions = [common_serializers.Action("delete", allow_all=False)]
+    filterset_class = filters.ManageTrackFilterSet
+
+    @transaction.atomic
+    def handle_delete(self, objects):
+        return objects.delete()
+
+
+class ManageAlbumActionSerializer(common_serializers.ActionSerializer):
+    actions = [common_serializers.Action("delete", allow_all=False)]
+    filterset_class = filters.ManageAlbumFilterSet
+
+    @transaction.atomic
+    def handle_delete(self, objects):
+        return objects.delete()
+
+
+class ManageArtistActionSerializer(common_serializers.ActionSerializer):
+    actions = [common_serializers.Action("delete", allow_all=False)]
+    filterset_class = filters.ManageArtistFilterSet
+
+    @transaction.atomic
+    def handle_delete(self, objects):
+        return objects.delete()
+
+
+class ManageLibraryActionSerializer(common_serializers.ActionSerializer):
+    actions = [common_serializers.Action("delete", allow_all=False)]
+    filterset_class = filters.ManageLibraryFilterSet
+
+    @transaction.atomic
+    def handle_delete(self, objects):
+        return objects.delete()
+
+
+class ManageUploadActionSerializer(common_serializers.ActionSerializer):
+    actions = [common_serializers.Action("delete", allow_all=False)]
+    filterset_class = filters.ManageUploadFilterSet
+
+    @transaction.atomic
+    def handle_delete(self, objects):
+        return objects.delete()
+
+
+class ManageLibrarySerializer(serializers.ModelSerializer):
+    domain = serializers.CharField(source="domain_name")
+    actor = ManageBaseActorSerializer()
+    uploads_count = serializers.SerializerMethodField()
+    followers_count = serializers.SerializerMethodField()
+
+    class Meta:
+        model = music_models.Library
+        fields = [
+            "id",
+            "uuid",
+            "fid",
+            "url",
+            "name",
+            "description",
+            "domain",
+            "is_local",
+            "creation_date",
+            "privacy_level",
+            "uploads_count",
+            "followers_count",
+            "followers_url",
+            "actor",
+        ]
+
+    def get_uploads_count(self, obj):
+        return getattr(obj, "_uploads_count", obj.uploads_count)
+
+    def get_followers_count(self, obj):
+        return getattr(obj, "followers_count", None)
+
+
+class ManageNestedLibrarySerializer(serializers.ModelSerializer):
+    domain = serializers.CharField(source="domain_name")
+    actor = ManageBaseActorSerializer()
+
+    class Meta:
+        model = music_models.Library
+        fields = [
+            "id",
+            "uuid",
+            "fid",
+            "url",
+            "name",
+            "description",
+            "domain",
+            "is_local",
+            "creation_date",
+            "privacy_level",
+            "followers_url",
+            "actor",
+        ]
+
+
+class ManageUploadSerializer(serializers.ModelSerializer):
+    track = ManageNestedTrackSerializer()
+    library = ManageNestedLibrarySerializer()
+    domain = serializers.CharField(source="domain_name")
+
+    class Meta:
+        model = music_models.Upload
+        fields = (
+            "id",
+            "uuid",
+            "fid",
+            "domain",
+            "is_local",
+            "audio_file",
+            "listen_url",
+            "source",
+            "filename",
+            "mimetype",
+            "duration",
+            "mimetype",
+            "bitrate",
+            "size",
+            "creation_date",
+            "accessed_date",
+            "modification_date",
+            "metadata",
+            "import_date",
+            "import_details",
+            "import_status",
+            "import_metadata",
+            "import_reference",
+            "track",
+            "library",
+        )
diff --git a/api/funkwhale_api/manage/urls.py b/api/funkwhale_api/manage/urls.py
index 4c220fe0ef28598eab3feec59c9fb19ecf33bd86..2d5da59e3ed6b8656c3438fb9121819e18079d47 100644
--- a/api/funkwhale_api/manage/urls.py
+++ b/api/funkwhale_api/manage/urls.py
@@ -7,6 +7,10 @@ federation_router = routers.SimpleRouter()
 federation_router.register(r"domains", views.ManageDomainViewSet, "domains")
 
 library_router = routers.SimpleRouter()
+library_router.register(r"albums", views.ManageAlbumViewSet, "albums")
+library_router.register(r"artists", views.ManageArtistViewSet, "artists")
+library_router.register(r"libraries", views.ManageLibraryViewSet, "libraries")
+library_router.register(r"tracks", views.ManageTrackViewSet, "tracks")
 library_router.register(r"uploads", views.ManageUploadViewSet, "uploads")
 
 moderation_router = routers.SimpleRouter()
diff --git a/api/funkwhale_api/manage/views.py b/api/funkwhale_api/manage/views.py
index 99d9020315882a3c461b3e8fe44eb1310635b0f5..83981116c59c69f9b350ab23e1182ee930e07464 100644
--- a/api/funkwhale_api/manage/views.py
+++ b/api/funkwhale_api/manage/views.py
@@ -1,39 +1,278 @@
 from rest_framework import mixins, response, viewsets
 from rest_framework import decorators as rest_decorators
+
+from django.db.models import Count, Prefetch, Q, Sum, OuterRef, Subquery
+from django.db.models.functions import Coalesce
 from django.shortcuts import get_object_or_404
 
+from funkwhale_api.common import models as common_models
 from funkwhale_api.common import preferences, decorators
+from funkwhale_api.favorites import models as favorites_models
 from funkwhale_api.federation import models as federation_models
 from funkwhale_api.federation import tasks as federation_tasks
+from funkwhale_api.history import models as history_models
 from funkwhale_api.music import models as music_models
 from funkwhale_api.moderation import models as moderation_models
+from funkwhale_api.playlists import models as playlists_models
 from funkwhale_api.users import models as users_models
-from funkwhale_api.users.permissions import HasUserPermission
+
 
 from . import filters, serializers
 
 
+def get_stats(tracks, target):
+    data = {}
+    tracks = list(tracks.values_list("pk", flat=True))
+    uploads = music_models.Upload.objects.filter(track__in=tracks)
+    data["listenings"] = history_models.Listening.objects.filter(
+        track__in=tracks
+    ).count()
+    data["mutations"] = common_models.Mutation.objects.get_for_target(target).count()
+    data["playlists"] = (
+        playlists_models.PlaylistTrack.objects.filter(track__in=tracks)
+        .values_list("playlist", flat=True)
+        .distinct()
+        .count()
+    )
+    data["track_favorites"] = favorites_models.TrackFavorite.objects.filter(
+        track__in=tracks
+    ).count()
+    data["libraries"] = uploads.values_list("library", flat=True).distinct().count()
+    data["uploads"] = uploads.count()
+    data.update(get_media_stats(uploads))
+    return data
+
+
+def get_media_stats(uploads):
+    data = {}
+    data["media_total_size"] = uploads.aggregate(v=Sum("size"))["v"] or 0
+    data["media_downloaded_size"] = (
+        uploads.with_file().aggregate(v=Sum("size"))["v"] or 0
+    )
+    return data
+
+
+class ManageArtistViewSet(
+    mixins.ListModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
+):
+    queryset = (
+        music_models.Artist.objects.all()
+        .order_by("-id")
+        .select_related("attributed_to")
+        .prefetch_related(
+            "tracks",
+            Prefetch(
+                "albums",
+                queryset=music_models.Album.objects.annotate(
+                    tracks_count=Count("tracks")
+                ),
+            ),
+        )
+    )
+    serializer_class = serializers.ManageArtistSerializer
+    filterset_class = filters.ManageArtistFilterSet
+    required_scope = "instance:libraries"
+    ordering_fields = ["creation_date", "name"]
+
+    @rest_decorators.action(methods=["get"], detail=True)
+    def stats(self, request, *args, **kwargs):
+        artist = self.get_object()
+        tracks = music_models.Track.objects.filter(
+            Q(artist=artist) | Q(album__artist=artist)
+        )
+        data = get_stats(tracks, artist)
+        return response.Response(data, status=200)
+
+    @rest_decorators.action(methods=["post"], detail=False)
+    def action(self, request, *args, **kwargs):
+        queryset = self.get_queryset()
+        serializer = serializers.ManageArtistActionSerializer(
+            request.data, queryset=queryset
+        )
+        serializer.is_valid(raise_exception=True)
+        result = serializer.save()
+        return response.Response(result, status=200)
+
+
+class ManageAlbumViewSet(
+    mixins.ListModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
+):
+    queryset = (
+        music_models.Album.objects.all()
+        .order_by("-id")
+        .select_related("attributed_to", "artist")
+        .prefetch_related("tracks")
+    )
+    serializer_class = serializers.ManageAlbumSerializer
+    filterset_class = filters.ManageAlbumFilterSet
+    required_scope = "instance:libraries"
+    ordering_fields = ["creation_date", "title", "release_date"]
+
+    @rest_decorators.action(methods=["get"], detail=True)
+    def stats(self, request, *args, **kwargs):
+        album = self.get_object()
+        data = get_stats(album.tracks.all(), album)
+        return response.Response(data, status=200)
+
+    @rest_decorators.action(methods=["post"], detail=False)
+    def action(self, request, *args, **kwargs):
+        queryset = self.get_queryset()
+        serializer = serializers.ManageAlbumActionSerializer(
+            request.data, queryset=queryset
+        )
+        serializer.is_valid(raise_exception=True)
+        result = serializer.save()
+        return response.Response(result, status=200)
+
+
+uploads_subquery = (
+    music_models.Upload.objects.filter(track_id=OuterRef("pk"))
+    .order_by()
+    .values("track_id")
+    .annotate(track_count=Count("track_id"))
+    .values("track_count")
+)
+
+
+class ManageTrackViewSet(
+    mixins.ListModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
+):
+    queryset = (
+        music_models.Track.objects.all()
+        .order_by("-id")
+        .select_related("attributed_to", "artist", "album__artist")
+        .annotate(uploads_count=Coalesce(Subquery(uploads_subquery), 0))
+    )
+    serializer_class = serializers.ManageTrackSerializer
+    filterset_class = filters.ManageTrackFilterSet
+    required_scope = "instance:libraries"
+    ordering_fields = [
+        "creation_date",
+        "title",
+        "album__release_date",
+        "position",
+        "disc_number",
+    ]
+
+    @rest_decorators.action(methods=["get"], detail=True)
+    def stats(self, request, *args, **kwargs):
+        track = self.get_object()
+        data = get_stats(track.__class__.objects.filter(pk=track.pk), track)
+        return response.Response(data, status=200)
+
+    @rest_decorators.action(methods=["post"], detail=False)
+    def action(self, request, *args, **kwargs):
+        queryset = self.get_queryset()
+        serializer = serializers.ManageTrackActionSerializer(
+            request.data, queryset=queryset
+        )
+        serializer.is_valid(raise_exception=True)
+        result = serializer.save()
+        return response.Response(result, status=200)
+
+
+uploads_subquery = (
+    music_models.Upload.objects.filter(library_id=OuterRef("pk"))
+    .order_by()
+    .values("library_id")
+    .annotate(library_count=Count("library_id"))
+    .values("library_count")
+)
+
+follows_subquery = (
+    federation_models.LibraryFollow.objects.filter(target_id=OuterRef("pk"))
+    .order_by()
+    .values("target_id")
+    .annotate(library_count=Count("target_id"))
+    .values("library_count")
+)
+
+
+class ManageLibraryViewSet(
+    mixins.ListModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
+):
+    lookup_field = "uuid"
+    queryset = (
+        music_models.Library.objects.all()
+        .order_by("-id")
+        .select_related("actor")
+        .annotate(
+            followers_count=Coalesce(Subquery(follows_subquery), 0),
+            _uploads_count=Coalesce(Subquery(uploads_subquery), 0),
+        )
+    )
+    serializer_class = serializers.ManageLibrarySerializer
+    filterset_class = filters.ManageLibraryFilterSet
+    required_scope = "instance:libraries"
+
+    @rest_decorators.action(methods=["get"], detail=True)
+    def stats(self, request, *args, **kwargs):
+        library = self.get_object()
+        uploads = library.uploads.all()
+        tracks = uploads.values_list("track", flat=True).distinct()
+        albums = (
+            music_models.Track.objects.filter(pk__in=tracks)
+            .values_list("album", flat=True)
+            .distinct()
+        )
+        artists = set(
+            music_models.Album.objects.filter(pk__in=albums).values_list(
+                "artist", flat=True
+            )
+        ) | set(
+            music_models.Track.objects.filter(pk__in=tracks).values_list(
+                "artist", flat=True
+            )
+        )
+
+        data = {
+            "uploads": uploads.count(),
+            "followers": library.received_follows.count(),
+            "tracks": tracks.count(),
+            "albums": albums.count(),
+            "artists": len(artists),
+        }
+        data.update(get_media_stats(uploads.all()))
+        return response.Response(data, status=200)
+
+    @rest_decorators.action(methods=["post"], detail=False)
+    def action(self, request, *args, **kwargs):
+        queryset = self.get_queryset()
+        serializer = serializers.ManageTrackActionSerializer(
+            request.data, queryset=queryset
+        )
+        serializer.is_valid(raise_exception=True)
+        result = serializer.save()
+        return response.Response(result, status=200)
+
+
 class ManageUploadViewSet(
-    mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet
+    mixins.ListModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
 ):
+    lookup_field = "uuid"
     queryset = (
         music_models.Upload.objects.all()
-        .select_related("track__artist", "track__album__artist")
         .order_by("-id")
+        .select_related("library__actor", "track__artist", "track__album__artist")
     )
     serializer_class = serializers.ManageUploadSerializer
     filterset_class = filters.ManageUploadFilterSet
-    permission_classes = (HasUserPermission,)
-    required_permissions = ["library"]
-    ordering_fields = [
-        "accessed_date",
-        "modification_date",
-        "creation_date",
-        "track__artist__name",
-        "bitrate",
-        "size",
-        "duration",
-    ]
+    required_scope = "instance:libraries"
 
     @rest_decorators.action(methods=["post"], detail=False)
     def action(self, request, *args, **kwargs):
@@ -55,8 +294,7 @@ class ManageUserViewSet(
     queryset = users_models.User.objects.all().order_by("-id")
     serializer_class = serializers.ManageUserSerializer
     filterset_class = filters.ManageUserFilterSet
-    permission_classes = (HasUserPermission,)
-    required_permissions = ["settings"]
+    required_scope = "instance:users"
     ordering_fields = ["date_joined", "last_activity", "username"]
 
     def get_serializer_context(self):
@@ -80,8 +318,7 @@ class ManageInvitationViewSet(
     )
     serializer_class = serializers.ManageInvitationSerializer
     filterset_class = filters.ManageInvitationFilterSet
-    permission_classes = (HasUserPermission,)
-    required_permissions = ["settings"]
+    required_scope = "instance:invitations"
     ordering_fields = ["creation_date", "expiration_date"]
 
     def perform_create(self, serializer):
@@ -114,8 +351,7 @@ class ManageDomainViewSet(
     )
     serializer_class = serializers.ManageDomainSerializer
     filterset_class = filters.ManageDomainFilterSet
-    permission_classes = (HasUserPermission,)
-    required_permissions = ["moderation"]
+    required_scope = "instance:domains"
     ordering_fields = [
         "name",
         "creation_date",
@@ -125,6 +361,10 @@ class ManageDomainViewSet(
         "instance_policy",
     ]
 
+    def perform_create(self, serializer):
+        domain = serializer.save()
+        federation_tasks.update_domain_nodeinfo(domain_name=domain.name)
+
     @rest_decorators.action(methods=["get"], detail=True)
     def nodeinfo(self, request, *args, **kwargs):
         domain = self.get_object()
@@ -153,7 +393,7 @@ class ManageActorViewSet(
     )
     serializer_class = serializers.ManageActorSerializer
     filterset_class = filters.ManageActorFilterSet
-    permission_classes = (HasUserPermission,)
+    required_scope = "instance:accounts"
     required_permissions = ["moderation"]
     ordering_fields = [
         "name",
@@ -199,8 +439,7 @@ class ManageInstancePolicyViewSet(
     )
     serializer_class = serializers.ManageInstancePolicySerializer
     filterset_class = filters.ManageInstancePolicyFilterSet
-    permission_classes = (HasUserPermission,)
-    required_permissions = ["moderation"]
+    required_scope = "instance:policies"
     ordering_fields = ["id", "creation_date"]
 
     def perform_create(self, serializer):
diff --git a/api/funkwhale_api/moderation/admin.py b/api/funkwhale_api/moderation/admin.py
index 5e421255ed344d61335edbb588f7792d07ac21ec..9f8340030e3aa4108ee7f63a87b0c2f8a50e85d9 100644
--- a/api/funkwhale_api/moderation/admin.py
+++ b/api/funkwhale_api/moderation/admin.py
@@ -28,3 +28,10 @@ class InstancePolicyAdmin(admin.ModelAdmin):
         "summary",
     ]
     list_select_related = True
+
+
+@admin.register(models.UserFilter)
+class UserFilterAdmin(admin.ModelAdmin):
+    list_display = ["uuid", "user", "target_artist", "creation_date"]
+    search_fields = ["target_artist__name", "user__username", "user__email"]
+    list_select_related = True
diff --git a/api/funkwhale_api/moderation/factories.py b/api/funkwhale_api/moderation/factories.py
index aba5256c9cba399cf2e345101eb0d9958f1b13f4..8829caa2bacf60b444b18984c71b24b5f8b788d0 100644
--- a/api/funkwhale_api/moderation/factories.py
+++ b/api/funkwhale_api/moderation/factories.py
@@ -2,6 +2,8 @@ import factory
 
 from funkwhale_api.factories import registry, NoUpdateOnCreate
 from funkwhale_api.federation import factories as federation_factories
+from funkwhale_api.music import factories as music_factories
+from funkwhale_api.users import factories as users_factories
 
 
 @registry.register
@@ -21,3 +23,17 @@ class InstancePolicyFactory(NoUpdateOnCreate, factory.DjangoModelFactory):
         for_actor = factory.Trait(
             target_actor=factory.SubFactory(federation_factories.ActorFactory)
         )
+
+
+@registry.register
+class UserFilterFactory(NoUpdateOnCreate, factory.DjangoModelFactory):
+    user = factory.SubFactory(users_factories.UserFactory)
+    target_artist = None
+
+    class Meta:
+        model = "moderation.UserFilter"
+
+    class Params:
+        for_artist = factory.Trait(
+            target_artist=factory.SubFactory(music_factories.ArtistFactory)
+        )
diff --git a/api/funkwhale_api/moderation/filters.py b/api/funkwhale_api/moderation/filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddf183045869bd01eeb71e2f3cfe80341e57e244
--- /dev/null
+++ b/api/funkwhale_api/moderation/filters.py
@@ -0,0 +1,69 @@
+from django.db.models import Q
+
+from django_filters import rest_framework as filters
+
+
+USER_FILTER_CONFIG = {
+    "ARTIST": {"target_artist": ["pk"]},
+    "ALBUM": {"target_artist": ["artist__pk"]},
+    "TRACK": {"target_artist": ["artist__pk", "album__artist__pk"]},
+    "LISTENING": {"target_artist": ["track__album__artist__pk", "track__artist__pk"]},
+    "TRACK_FAVORITE": {
+        "target_artist": ["track__album__artist__pk", "track__artist__pk"]
+    },
+}
+
+
+def get_filtered_content_query(config, user):
+    final_query = None
+    for filter_field, model_fields in config.items():
+        query = None
+        ids = user.content_filters.values_list(filter_field, flat=True)
+        for model_field in model_fields:
+            q = Q(**{"{}__in".format(model_field): ids})
+            if query:
+                query |= q
+            else:
+                query = q
+
+        final_query = query
+    return final_query
+
+
+class HiddenContentFilterSet(filters.FilterSet):
+    """
+    A filterset that include a "hidden" param:
+    - hidden=true : list user hidden/filtered objects
+    - hidden=false : list all objects user hidden/filtered objects
+    - not specified: hidden=false
+
+    Usage:
+
+    class MyFilterSet(HiddenContentFilterSet):
+        class Meta:
+            hidden_content_fields_mapping = {'target_artist': ['pk']}
+
+    Will map UserContentFilter.artist values to the pk field of the filtered model.
+
+    """
+
+    hidden = filters.BooleanFilter(field_name="_", method="filter_hidden_content")
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.data = self.data.copy()
+        self.data.setdefault("hidden", False)
+
+    def filter_hidden_content(self, queryset, name, value):
+        user = self.request.user
+        if not user.is_authenticated:
+            # no filter to apply
+            return queryset
+
+        config = self.__class__.Meta.hidden_content_fields_mapping
+        final_query = get_filtered_content_query(config, user)
+
+        if value is True:
+            return queryset.filter(final_query)
+        else:
+            return queryset.exclude(final_query)
diff --git a/api/funkwhale_api/moderation/migrations/0002_auto_20190213_0927.py b/api/funkwhale_api/moderation/migrations/0002_auto_20190213_0927.py
new file mode 100644
index 0000000000000000000000000000000000000000..2832a34ef669b2d10aec088d6bae4347bb88091b
--- /dev/null
+++ b/api/funkwhale_api/moderation/migrations/0002_auto_20190213_0927.py
@@ -0,0 +1,57 @@
+# Generated by Django 2.1.5 on 2019-02-13 09:27
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import uuid
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ("music", "0037_auto_20190103_1757"),
+        ("moderation", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="UserFilter",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("uuid", models.UUIDField(default=uuid.uuid4, unique=True)),
+                (
+                    "creation_date",
+                    models.DateTimeField(default=django.utils.timezone.now),
+                ),
+                (
+                    "target_artist",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="user_filters",
+                        to="music.Artist",
+                    ),
+                ),
+                (
+                    "user",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="content_filters",
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+        ),
+        migrations.AlterUniqueTogether(
+            name="userfilter", unique_together={("user", "target_artist")}
+        ),
+    ]
diff --git a/api/funkwhale_api/moderation/models.py b/api/funkwhale_api/moderation/models.py
index c184bbda8117929da26940a1197b36c6cb75f6f4..7ade5d05a1e5a1ff0bfb0e259b5770b100a77489 100644
--- a/api/funkwhale_api/moderation/models.py
+++ b/api/funkwhale_api/moderation/models.py
@@ -73,3 +73,22 @@ class InstancePolicy(models.Model):
             return {"type": "actor", "obj": self.target_actor}
         if self.target_domain_id:
             return {"type": "domain", "obj": self.target_domain}
+
+
+class UserFilter(models.Model):
+    uuid = models.UUIDField(default=uuid.uuid4, unique=True)
+    creation_date = models.DateTimeField(default=timezone.now)
+    target_artist = models.ForeignKey(
+        "music.Artist", on_delete=models.CASCADE, related_name="user_filters"
+    )
+    user = models.ForeignKey(
+        "users.User", on_delete=models.CASCADE, related_name="content_filters"
+    )
+
+    class Meta:
+        unique_together = ("user", "target_artist")
+
+    @property
+    def target(self):
+        if self.target_artist:
+            return {"type": "artist", "obj": self.target_artist}
diff --git a/api/funkwhale_api/moderation/serializers.py b/api/funkwhale_api/moderation/serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..20c34242102d4f302ac29a9781a059c08fef2fb9
--- /dev/null
+++ b/api/funkwhale_api/moderation/serializers.py
@@ -0,0 +1,45 @@
+from rest_framework import serializers
+
+from funkwhale_api.music import models as music_models
+from . import models
+
+
+class FilteredArtistSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = music_models.Artist
+        fields = ["id", "name"]
+
+
+class TargetSerializer(serializers.Serializer):
+    type = serializers.ChoiceField(choices=["artist"])
+    id = serializers.CharField()
+
+    def to_representation(self, value):
+        if value["type"] == "artist":
+            data = FilteredArtistSerializer(value["obj"]).data
+            data.update({"type": "artist"})
+            return data
+
+    def to_internal_value(self, value):
+        if value["type"] == "artist":
+            field = serializers.PrimaryKeyRelatedField(
+                queryset=music_models.Artist.objects.all()
+            )
+        value["obj"] = field.to_internal_value(value["id"])
+        return value
+
+
+class UserFilterSerializer(serializers.ModelSerializer):
+    target = TargetSerializer()
+
+    class Meta:
+        model = models.UserFilter
+        fields = ["uuid", "target", "creation_date"]
+        read_only_fields = ["uuid", "creation_date"]
+
+    def validate(self, data):
+        target = data.pop("target")
+        if target["type"] == "artist":
+            data["target_artist"] = target["obj"]
+
+        return data
diff --git a/api/funkwhale_api/moderation/urls.py b/api/funkwhale_api/moderation/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..05d2e7a9223774db0329f66ae295255cb88d9b7a
--- /dev/null
+++ b/api/funkwhale_api/moderation/urls.py
@@ -0,0 +1,8 @@
+from rest_framework import routers
+
+from . import views
+
+router = routers.SimpleRouter()
+router.register(r"content-filters", views.UserFilterViewSet, "content-filters")
+
+urlpatterns = router.urls
diff --git a/api/funkwhale_api/moderation/views.py b/api/funkwhale_api/moderation/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d4e3e039abdd68858fe96df79ad965a02e49771
--- /dev/null
+++ b/api/funkwhale_api/moderation/views.py
@@ -0,0 +1,41 @@
+from django.db import IntegrityError
+
+from rest_framework import mixins
+from rest_framework import response
+from rest_framework import status
+from rest_framework import viewsets
+
+from . import models
+from . import serializers
+
+
+class UserFilterViewSet(
+    mixins.ListModelMixin,
+    mixins.CreateModelMixin,
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    viewsets.GenericViewSet,
+):
+    lookup_field = "uuid"
+    queryset = (
+        models.UserFilter.objects.all()
+        .order_by("-creation_date")
+        .select_related("target_artist")
+    )
+    serializer_class = serializers.UserFilterSerializer
+    required_scope = "filters"
+    ordering_fields = ("creation_date",)
+
+    def create(self, request, *args, **kwargs):
+        try:
+            return super().create(request, *args, **kwargs)
+        except IntegrityError:
+            content = {"detail": "A content filter already exists for this object"}
+            return response.Response(content, status=status.HTTP_400_BAD_REQUEST)
+
+    def get_queryset(self):
+        qs = super().get_queryset()
+        return qs.filter(user=self.request.user)
+
+    def perform_create(self, serializer):
+        serializer.save(user=self.request.user)
diff --git a/api/funkwhale_api/music/admin.py b/api/funkwhale_api/music/admin.py
index b2f001527f3285b24958fd55ce9f1fdd98262984..584653ab9ae7d76d3a959f40f72ef6e700a33667 100644
--- a/api/funkwhale_api/music/admin.py
+++ b/api/funkwhale_api/music/admin.py
@@ -39,22 +39,6 @@ class ImportJobAdmin(admin.ModelAdmin):
     list_filter = ["status"]
 
 
-@admin.register(models.Work)
-class WorkAdmin(admin.ModelAdmin):
-    list_display = ["title", "mbid", "language", "nature"]
-    list_select_related = True
-    search_fields = ["title"]
-    list_filter = ["language", "nature"]
-
-
-@admin.register(models.Lyrics)
-class LyricsAdmin(admin.ModelAdmin):
-    list_display = ["url", "id", "url"]
-    list_select_related = True
-    search_fields = ["url", "work__title"]
-    list_filter = ["work__language"]
-
-
 @admin.register(models.Upload)
 class UploadAdmin(admin.ModelAdmin):
     list_display = [
diff --git a/api/funkwhale_api/music/factories.py b/api/funkwhale_api/music/factories.py
index cd2a91ccb1d72766493b8998189ea8bc58e654e4..430c82439805957c007c1a3c80aa8d02e2dcefb8 100644
--- a/api/funkwhale_api/music/factories.py
+++ b/api/funkwhale_api/music/factories.py
@@ -64,6 +64,12 @@ class ArtistFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     class Meta:
         model = "music.Artist"
 
+    class Params:
+        attributed = factory.Trait(
+            attributed_to=factory.SubFactory(federation_factories.ActorFactory)
+        )
+        local = factory.Trait(fid=factory.Faker("federation_url", local=True))
+
 
 @registry.register
 class AlbumFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
@@ -79,6 +85,15 @@ class AlbumFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     class Meta:
         model = "music.Album"
 
+    class Params:
+        attributed = factory.Trait(
+            attributed_to=factory.SubFactory(federation_factories.ActorFactory)
+        )
+
+        local = factory.Trait(
+            fid=factory.Faker("federation_url", local=True), artist__local=True
+        )
+
 
 @registry.register
 class TrackFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
@@ -94,6 +109,15 @@ class TrackFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     class Meta:
         model = "music.Track"
 
+    class Params:
+        attributed = factory.Trait(
+            attributed_to=factory.SubFactory(federation_factories.ActorFactory)
+        )
+
+        local = factory.Trait(
+            fid=factory.Faker("federation_url", local=True), album__local=True
+        )
+
     @factory.post_generation
     def license(self, created, extracted, **kwargs):
         if not created:
@@ -140,27 +164,6 @@ class UploadVersionFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
         model = "music.UploadVersion"
 
 
-@registry.register
-class WorkFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
-    mbid = factory.Faker("uuid4")
-    language = "eng"
-    nature = "song"
-    title = factory.Faker("sentence", nb_words=3)
-
-    class Meta:
-        model = "music.Work"
-
-
-@registry.register
-class LyricsFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
-    work = factory.SubFactory(WorkFactory)
-    url = factory.Faker("url")
-    content = factory.Faker("paragraphs", nb=4)
-
-    class Meta:
-        model = "music.Lyrics"
-
-
 @registry.register
 class TagFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
     name = factory.SelfAttribute("slug")
diff --git a/api/funkwhale_api/music/filters.py b/api/funkwhale_api/music/filters.py
index 76bc93b6776c8b4c1ae294381b448fb47efbe9b5..fa5a10f6d4397ed296d8710d6b76d6dc6646ec28 100644
--- a/api/funkwhale_api/music/filters.py
+++ b/api/funkwhale_api/music/filters.py
@@ -1,13 +1,15 @@
 from django_filters import rest_framework as filters
 
 from funkwhale_api.common import fields
+from funkwhale_api.common import filters as common_filters
 from funkwhale_api.common import search
+from funkwhale_api.moderation import filters as moderation_filters
 
 from . import models
 from . import utils
 
 
-class ArtistFilter(filters.FilterSet):
+class ArtistFilter(moderation_filters.HiddenContentFilterSet):
     q = fields.SearchFilter(search_fields=["name"])
     playable = filters.BooleanFilter(field_name="_", method="filter_playable")
 
@@ -17,25 +19,29 @@ class ArtistFilter(filters.FilterSet):
             "name": ["exact", "iexact", "startswith", "icontains"],
             "playable": "exact",
         }
+        hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ARTIST"]
 
     def filter_playable(self, queryset, name, value):
         actor = utils.get_actor_from_request(self.request)
         return queryset.playable_by(actor, value)
 
 
-class TrackFilter(filters.FilterSet):
+class TrackFilter(moderation_filters.HiddenContentFilterSet):
     q = fields.SearchFilter(search_fields=["title", "album__title", "artist__name"])
     playable = filters.BooleanFilter(field_name="_", method="filter_playable")
+    id = common_filters.MultipleQueryFilter(coerce=int)
 
     class Meta:
         model = models.Track
         fields = {
             "title": ["exact", "iexact", "startswith", "icontains"],
             "playable": ["exact"],
+            "id": ["exact"],
             "artist": ["exact"],
             "album": ["exact"],
             "license": ["exact"],
         }
+        hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["TRACK"]
 
     def filter_playable(self, queryset, name, value):
         actor = utils.get_actor_from_request(self.request)
@@ -85,13 +91,14 @@ class UploadFilter(filters.FilterSet):
         return queryset.playable_by(actor, value)
 
 
-class AlbumFilter(filters.FilterSet):
+class AlbumFilter(moderation_filters.HiddenContentFilterSet):
     playable = filters.BooleanFilter(field_name="_", method="filter_playable")
-    q = fields.SearchFilter(search_fields=["title", "artist__name" "source"])
+    q = fields.SearchFilter(search_fields=["title", "artist__name"])
 
     class Meta:
         model = models.Album
         fields = ["playable", "q", "artist"]
+        hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ALBUM"]
 
     def filter_playable(self, queryset, name, value):
         actor = utils.get_actor_from_request(self.request)
diff --git a/api/funkwhale_api/music/importers.py b/api/funkwhale_api/music/importers.py
index 28763a4951386ac458ce554dd141f654c1f1040c..add3993c8f749f3cf29da0f6b3cbce7ed1503937 100644
--- a/api/funkwhale_api/music/importers.py
+++ b/api/funkwhale_api/music/importers.py
@@ -47,4 +47,4 @@ class Mapping(object):
         )
 
 
-registry = {"Artist": Importer, "Track": Importer, "Album": Importer, "Work": Importer}
+registry = {"Artist": Importer, "Track": Importer, "Album": Importer}
diff --git a/api/funkwhale_api/music/lyrics.py b/api/funkwhale_api/music/lyrics.py
deleted file mode 100644
index 6d5f20e44d54320db9ebc4fb5b344de6585ba6cf..0000000000000000000000000000000000000000
--- a/api/funkwhale_api/music/lyrics.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import urllib.request
-
-from bs4 import BeautifulSoup
-
-
-def _get_html(url):
-    with urllib.request.urlopen(url) as response:
-        html = response.read()
-    return html.decode("utf-8")
-
-
-def extract_content(html):
-    soup = BeautifulSoup(html, "html.parser")
-    return soup.find_all("div", class_="lyricbox")[0].contents
-
-
-def clean_content(contents):
-    final_content = ""
-    for e in contents:
-        if e == "\n":
-            continue
-        if e.name == "script":
-            continue
-        if e.name == "br":
-            final_content += "\n"
-            continue
-        try:
-            final_content += e.text
-        except AttributeError:
-            final_content += str(e)
-    return final_content
diff --git a/api/funkwhale_api/music/management/commands/check_inplace_files.py b/api/funkwhale_api/music/management/commands/check_inplace_files.py
new file mode 100644
index 0000000000000000000000000000000000000000..f274ee589086f5446ef83c7791c33688c072d014
--- /dev/null
+++ b/api/funkwhale_api/music/management/commands/check_inplace_files.py
@@ -0,0 +1,76 @@
+import os
+from argparse import RawTextHelpFormatter
+
+from django.core.management.base import BaseCommand
+
+from django.db import transaction
+
+from funkwhale_api.music import models
+
+
+def progress(buffer, count, total, status=""):
+    bar_len = 60
+    filled_len = int(round(bar_len * count / float(total)))
+
+    bar = "=" * filled_len + "-" * (bar_len - filled_len)
+
+    buffer.write("[%s] %s/%s ...%s\r" % (bar, count, total, status))
+    buffer.flush()
+
+
+class Command(BaseCommand):
+    help = """
+    Loop through all in-place imported files in the database, and verify
+    that the corresponding files are present on the filesystem. If some files are not
+    found and --no-dry-run is specified, the corresponding database objects will be deleted.
+    """
+
+    def create_parser(self, *args, **kwargs):
+        parser = super().create_parser(*args, **kwargs)
+        parser.formatter_class = RawTextHelpFormatter
+        return parser
+
+    def add_arguments(self, parser):
+        parser.add_argument(
+            "--no-dry-run",
+            action="store_false",
+            dest="dry_run",
+            default=True,
+            help="Disable dry run mode and apply pruning for real on the database",
+        )
+
+    @transaction.atomic
+    def handle(self, *args, **options):
+        candidates = models.Upload.objects.filter(source__startswith="file://")
+        candidates = candidates.filter(audio_file__in=["", None])
+        total = candidates.count()
+        self.stdout.write("Checking {} in-place imported files…".format(total))
+
+        missing = []
+        for i, row in enumerate(candidates.values("id", "source")):
+            path = row["source"].replace("file://", "")
+            progress(self.stdout, i + 1, total)
+            if not os.path.exists(path):
+                missing.append((path, row["id"]))
+
+        if missing:
+            for path, _ in missing:
+                self.stdout.write("  {}".format(path))
+            self.stdout.write(
+                "The previous {} paths are referenced in database, but not found on disk!".format(
+                    len(missing)
+                )
+            )
+
+        else:
+            self.stdout.write("All in-place imports have a matching on-disk file")
+            return
+
+        to_delete = candidates.filter(pk__in=[id for _, id in missing])
+        if options["dry_run"]:
+            self.stdout.write(
+                "Nothing was deleted, rerun this command with --no-dry-run to apply the changes"
+            )
+        else:
+            self.stdout.write("Deleting {} uploads…".format(to_delete.count()))
+            to_delete.delete()
diff --git a/api/funkwhale_api/music/management/commands/prune_library.py b/api/funkwhale_api/music/management/commands/prune_library.py
new file mode 100644
index 0000000000000000000000000000000000000000..e06ee0fdb6581ed593c1ab1b08bc6b7da3294316
--- /dev/null
+++ b/api/funkwhale_api/music/management/commands/prune_library.py
@@ -0,0 +1,145 @@
+from argparse import RawTextHelpFormatter
+
+from django.core.management.base import BaseCommand
+from django.core.management.base import CommandError
+
+from django.db import transaction
+
+from funkwhale_api.music import models, tasks
+
+
+class Command(BaseCommand):
+    help = """
+    Remove tracks, albums and artists that are not associated with any file from the instance library:
+
+    - Tracks without uploads are deleted, if the --tracks flag is passed
+    - Albums without tracks are deleted, if the --albums flag is passed
+    - Artists without albums are deleted, if the --artists flag is passed
+
+    Tracks with associated favorites, playlists or listening won't be deleted
+    by default, unless you pass the corresponding --ignore-* flags.
+
+    """
+
+    def create_parser(self, *args, **kwargs):
+        parser = super().create_parser(*args, **kwargs)
+        parser.formatter_class = RawTextHelpFormatter
+        return parser
+
+    def add_arguments(self, parser):
+        parser.add_argument(
+            "--no-dry-run",
+            action="store_false",
+            dest="dry_run",
+            default=True,
+            help="Disable dry run mode and apply pruning for real on the database",
+        )
+        parser.add_argument(
+            "--artists",
+            action="store_true",
+            dest="prune_artists",
+            default=False,
+            help="Prune artists without albums/tracks",
+        )
+        parser.add_argument(
+            "--albums",
+            action="store_true",
+            dest="prune_albums",
+            default=False,
+            help="Prune albums without tracks",
+        )
+        parser.add_argument(
+            "--tracks",
+            action="store_true",
+            dest="prune_tracks",
+            default=False,
+            help="Prune tracks without uploads",
+        )
+
+        parser.add_argument(
+            "--ignore-favorites",
+            action="store_false",
+            dest="exclude_favorites",
+            default=True,
+            help="Allow favorited tracks to be pruned",
+        )
+
+        parser.add_argument(
+            "--ignore-playlists",
+            action="store_false",
+            dest="exclude_playlists",
+            default=True,
+            help="Allow tracks included in playlists to be pruned",
+        )
+
+        parser.add_argument(
+            "--ignore-listenings",
+            action="store_false",
+            dest="exclude_listenings",
+            default=True,
+            help="Allow tracks with listening history to be pruned",
+        )
+
+    @transaction.atomic
+    def handle(self, *args, **options):
+        if not any(
+            [options["prune_albums"], options["prune_tracks"], options["prune_artists"]]
+        ):
+            raise CommandError(
+                "You need to provide at least one of the --tracks, --albums or --artists flags"
+            )
+
+        if options["dry_run"]:
+            self.stdout.write("Dry-run on, will not commit anything")
+        else:
+            self.stdout.write("Dry-run off, *pruning for real*")
+        self.stdout.write("")
+        if options["prune_tracks"]:
+            prunable = tasks.get_prunable_tracks(
+                exclude_favorites=options["exclude_favorites"],
+                exclude_playlists=options["exclude_playlists"],
+                exclude_listenings=options["exclude_listenings"],
+            )
+            pruned_total = prunable.count()
+            total = models.Track.objects.count()
+            if options["dry_run"]:
+                self.stdout.write(
+                    "Would prune {}/{} tracks".format(pruned_total, total)
+                )
+            else:
+                self.stdout.write("Deleting {}/{} tracks…".format(pruned_total, total))
+                prunable.delete()
+
+        if options["prune_albums"]:
+            prunable = tasks.get_prunable_albums()
+            pruned_total = prunable.count()
+            total = models.Album.objects.count()
+            if options["dry_run"]:
+                self.stdout.write(
+                    "Would prune {}/{} albums".format(pruned_total, total)
+                )
+            else:
+                self.stdout.write("Deleting {}/{} albums…".format(pruned_total, total))
+                prunable.delete()
+
+        if options["prune_artists"]:
+            prunable = tasks.get_prunable_artists()
+            pruned_total = prunable.count()
+            total = models.Artist.objects.count()
+            if options["dry_run"]:
+                self.stdout.write(
+                    "Would prune {}/{} artists".format(pruned_total, total)
+                )
+            else:
+                self.stdout.write("Deleting {}/{} artists…".format(pruned_total, total))
+                prunable.delete()
+
+        self.stdout.write("")
+        if options["dry_run"]:
+            self.stdout.write(
+                "Nothing was pruned, rerun this command with --no-dry-run to apply the changes"
+            )
+        else:
+            self.stdout.write("Pruning completed!")
+
+        self.stdout.write("")
diff --git a/api/funkwhale_api/music/metadata.py b/api/funkwhale_api/music/metadata.py
index 7a105e432ca441783f9778dbad6c5858aeb7f54b..387b8ffe7de425ecca879999e39d671d619caff8 100644
--- a/api/funkwhale_api/music/metadata.py
+++ b/api/funkwhale_api/music/metadata.py
@@ -8,7 +8,8 @@ import mutagen.oggtheora
 import mutagen.oggvorbis
 import mutagen.flac
 
-from django import forms
+from rest_framework import serializers
+from rest_framework.compat import Mapping
 
 logger = logging.getLogger(__name__)
 NODEFAULT = object()
@@ -122,85 +123,23 @@ def get_mp3_recording_id(f, k):
         raise TagNotFound(k)
 
 
-def convert_position(v):
-    try:
-        return int(v)
-    except ValueError:
-        # maybe the position is of the form "1/4"
-        pass
-
-    try:
-        return int(v.split("/")[0])
-    except (ValueError, AttributeError, IndexError):
-        pass
-
-
-class FirstUUIDField(forms.UUIDField):
-    def to_python(self, value):
-        try:
-            # sometimes, Picard leaves two uuids in the field, separated
-            # by a slash or a ;
-            value = value.split(";")[0].split("/")[0].strip()
-        except (AttributeError, IndexError, TypeError):
-            pass
-
-        return super().to_python(value)
-
-
-def get_date(value):
-    ADDITIONAL_FORMATS = ["%Y-%d-%m %H:%M"]  # deezer date format
-    try:
-        parsed = pendulum.parse(str(value))
-        return datetime.date(parsed.year, parsed.month, parsed.day)
-    except pendulum.exceptions.ParserError:
-        pass
-
-    for date_format in ADDITIONAL_FORMATS:
-        try:
-            parsed = datetime.datetime.strptime(value, date_format)
-        except ValueError:
-            continue
-        else:
-            return datetime.date(parsed.year, parsed.month, parsed.day)
-
-    raise ParseError("{} cannot be parsed as a date".format(value))
-
-
-def split_and_return_first(separator):
-    def inner(v):
-        return v.split(separator)[0].strip()
-
-    return inner
-
-
-VALIDATION = {
-    "musicbrainz_artistid": FirstUUIDField(),
-    "musicbrainz_albumid": FirstUUIDField(),
-    "musicbrainz_recordingid": FirstUUIDField(),
-    "musicbrainz_albumartistid": FirstUUIDField(),
-}
+VALIDATION = {}
 
 CONF = {
     "OggOpus": {
         "getter": lambda f, k: f[k][0],
         "fields": {
-            "track_number": {
-                "field": "TRACKNUMBER",
-                "to_application": convert_position,
-            },
-            "disc_number": {"field": "DISCNUMBER", "to_application": convert_position},
+            "position": {"field": "TRACKNUMBER"},
+            "disc_number": {"field": "DISCNUMBER"},
             "title": {},
             "artist": {},
-            "album_artist": {
-                "field": "albumartist",
-                "to_application": split_and_return_first(";"),
-            },
+            "album_artist": {"field": "albumartist"},
             "album": {},
-            "date": {"field": "date", "to_application": get_date},
+            "date": {"field": "date"},
             "musicbrainz_albumid": {},
             "musicbrainz_artistid": {},
             "musicbrainz_albumartistid": {},
-            "musicbrainz_recordingid": {"field": "musicbrainz_trackid"},
+            "mbid": {"field": "musicbrainz_trackid"},
             "license": {},
             "copyright": {},
         },
@@ -208,23 +147,17 @@ CONF = {
     "OggVorbis": {
         "getter": lambda f, k: f[k][0],
         "fields": {
-            "track_number": {
-                "field": "TRACKNUMBER",
-                "to_application": convert_position,
-            },
-            "disc_number": {"field": "DISCNUMBER", "to_application": convert_position},
+            "position": {"field": "TRACKNUMBER"},
+            "disc_number": {"field": "DISCNUMBER"},
             "title": {},
             "artist": {},
-            "album_artist": {
-                "field": "albumartist",
-                "to_application": split_and_return_first(";"),
-            },
+            "album_artist": {"field": "albumartist"},
             "album": {},
-            "date": {"field": "date", "to_application": get_date},
+            "date": {"field": "date"},
             "musicbrainz_albumid": {},
             "musicbrainz_artistid": {},
             "musicbrainz_albumartistid": {},
-            "musicbrainz_recordingid": {"field": "musicbrainz_trackid"},
+            "mbid": {"field": "musicbrainz_trackid"},
             "license": {},
             "copyright": {},
             "pictures": {
@@ -236,20 +169,17 @@ CONF = {
     "OggTheora": {
         "getter": lambda f, k: f[k][0],
         "fields": {
-            "track_number": {
-                "field": "TRACKNUMBER",
-                "to_application": convert_position,
-            },
-            "disc_number": {"field": "DISCNUMBER", "to_application": convert_position},
+            "position": {"field": "TRACKNUMBER"},
+            "disc_number": {"field": "DISCNUMBER"},
             "title": {},
             "artist": {},
             "album_artist": {"field": "albumartist"},
             "album": {},
-            "date": {"field": "date", "to_application": get_date},
+            "date": {"field": "date"},
             "musicbrainz_albumid": {"field": "MusicBrainz Album Id"},
             "musicbrainz_artistid": {"field": "MusicBrainz Artist Id"},
             "musicbrainz_albumartistid": {"field": "MusicBrainz Album Artist Id"},
-            "musicbrainz_recordingid": {"field": "MusicBrainz Track Id"},
+            "mbid": {"field": "MusicBrainz Track Id"},
             "license": {},
             "copyright": {},
         },
@@ -258,20 +188,17 @@ CONF = {
         "getter": get_id3_tag,
         "clean_pictures": clean_id3_pictures,
         "fields": {
-            "track_number": {"field": "TRCK", "to_application": convert_position},
-            "disc_number": {"field": "TPOS", "to_application": convert_position},
+            "position": {"field": "TRCK"},
+            "disc_number": {"field": "TPOS"},
             "title": {"field": "TIT2"},
             "artist": {"field": "TPE1"},
             "album_artist": {"field": "TPE2"},
             "album": {"field": "TALB"},
-            "date": {"field": "TDRC", "to_application": get_date},
+            "date": {"field": "TDRC"},
             "musicbrainz_albumid": {"field": "MusicBrainz Album Id"},
             "musicbrainz_artistid": {"field": "MusicBrainz Artist Id"},
             "musicbrainz_albumartistid": {"field": "MusicBrainz Album Artist Id"},
-            "musicbrainz_recordingid": {
-                "field": "UFID",
-                "getter": get_mp3_recording_id,
-            },
+            "mbid": {"field": "UFID", "getter": get_mp3_recording_id},
             "pictures": {},
             "license": {"field": "WCOP"},
             "copyright": {"field": "TCOP"},
@@ -281,20 +208,17 @@ CONF = {
         "getter": get_flac_tag,
         "clean_pictures": clean_flac_pictures,
         "fields": {
-            "track_number": {
-                "field": "tracknumber",
-                "to_application": convert_position,
-            },
-            "disc_number": {"field": "discnumber", "to_application": convert_position},
+            "position": {"field": "tracknumber"},
+            "disc_number": {"field": "discnumber"},
             "title": {},
             "artist": {},
             "album_artist": {"field": "albumartist"},
             "album": {},
-            "date": {"field": "date", "to_application": get_date},
+            "date": {"field": "date"},
             "musicbrainz_albumid": {},
             "musicbrainz_artistid": {},
             "musicbrainz_albumartistid": {},
-            "musicbrainz_recordingid": {"field": "musicbrainz_trackid"},
+            "mbid": {"field": "musicbrainz_trackid"},
             "test": {},
             "pictures": {},
             "license": {},
@@ -304,7 +228,7 @@ CONF = {
 }
 
 ALL_FIELDS = [
-    "track_number",
+    "position",
     "disc_number",
     "title",
     "artist",
@@ -314,13 +238,13 @@ ALL_FIELDS = [
     "musicbrainz_albumid",
     "musicbrainz_artistid",
     "musicbrainz_albumartistid",
-    "musicbrainz_recordingid",
+    "mbid",
     "license",
     "copyright",
 ]
 
 
-class Metadata(object):
+class Metadata(Mapping):
     def __init__(self, filething, kind=mutagen.File):
         self._file = kind(filething)
         if self._file is None:
@@ -368,6 +292,21 @@ class Metadata(object):
             else:
                 return self.fallback.get(key, default=default)
 
+    def all(self):
+        """
+        Return a dict with all support metadata fields, if they are available
+        """
+        final = {}
+        for field in self._conf["fields"]:
+            if field in ["pictures"]:
+                continue
+            value = self.get(field, None)
+            if value is None:
+                continue
+            final[field] = str(value)
+
+        return final
+
     def _get_from_self(self, key, default=NODEFAULT):
         try:
             field_conf = self._conf["fields"][key]
@@ -390,25 +329,6 @@ class Metadata(object):
             v = field.to_python(v)
         return v
 
-    def all(self, ignore_parse_errors=True):
-        """
-        Return a dict containing all metadata of the file
-        """
-
-        data = {}
-        for field in ALL_FIELDS:
-            try:
-                data[field] = self.get(field, None)
-            except (TagNotFound, forms.ValidationError):
-                data[field] = None
-            except ParseError as e:
-                if not ignore_parse_errors:
-                    raise
-                logger.warning("Unparsable field {}: {}".format(field, str(e)))
-                data[field] = None
-
-        return data
-
     def get_picture(self, *picture_types):
         if not picture_types:
             raise ValueError("You need to request at least one picture type")
@@ -430,3 +350,192 @@ class Metadata(object):
             for p in pictures:
                 if p["type"] == ptype:
                     return p
+
+    def __getitem__(self, key):
+        return self.get(key)
+
+    def __len__(self):
+        return 1
+
+    def __iter__(self):
+        for field in self._conf["fields"]:
+            yield field
+
+
+class ArtistField(serializers.Field):
+    def __init__(self, *args, **kwargs):
+        self.for_album = kwargs.pop("for_album", False)
+        super().__init__(*args, **kwargs)
+
+    def get_value(self, data):
+        if self.for_album:
+            keys = [("names", "album_artist"), ("mbids", "musicbrainz_albumartistid")]
+        else:
+            keys = [("names", "artist"), ("mbids", "musicbrainz_artistid")]
+
+        final = {}
+        for field, key in keys:
+            final[field] = data.get(key, None)
+
+        return final
+
+    def to_internal_value(self, data):
+        # we have multiple values that can be separated by various separators
+        separators = [";"]
+        # we get a list like that if tagged via musicbrainz
+        # ae29aae4-abfb-4609-8f54-417b1f4d64cc; 3237b5a8-ae44-400c-aa6d-cea51f0b9074;
+        raw_mbids = data["mbids"]
+        used_separator = None
+        mbids = [raw_mbids]
+        if raw_mbids:
+            if "/" in raw_mbids:
+                # it's a featuring, we can't handle this now
+                mbids = []
+            else:
+                for separator in separators:
+                    if separator in raw_mbids:
+                        used_separator = separator
+                        mbids = [m.strip() for m in raw_mbids.split(separator)]
+                        break
+
+        # now, we split on artist names, using the same separator as the one used
+        # by mbids, if any
+        if used_separator and mbids:
+            names = [n.strip() for n in data["names"].split(used_separator)]
+        else:
+            names = [data["names"]]
+
+        final = []
+        for i, name in enumerate(names):
+            try:
+                mbid = mbids[i]
+            except IndexError:
+                mbid = None
+            artist = {"name": name, "mbid": mbid}
+            final.append(artist)
+
+        field = serializers.ListField(child=ArtistSerializer(), min_length=1)
+
+        return field.to_internal_value(final)
+
+
+class AlbumField(serializers.Field):
+    def get_value(self, data):
+        return data
+
+    def to_internal_value(self, data):
+        try:
+            title = data.get("album")
+        except TagNotFound:
+            raise serializers.ValidationError("Missing album tag")
+        final = {
+            "title": title,
+            "release_date": data.get("date", None),
+            "mbid": data.get("musicbrainz_albumid", None),
+        }
+        artists_field = ArtistField(for_album=True)
+        payload = artists_field.get_value(data)
+        try:
+            artists = artists_field.to_internal_value(payload)
+        except serializers.ValidationError as e:
+            artists = []
+            logger.debug("Ignoring validation error on album artists: %s", e)
+        album_serializer = AlbumSerializer(data=final)
+        album_serializer.is_valid(raise_exception=True)
+        album_serializer.validated_data["artists"] = artists
+        return album_serializer.validated_data
+
+
+class CoverDataField(serializers.Field):
+    def get_value(self, data):
+        return data
+
+    def to_internal_value(self, data):
+        return data.get_picture("cover_front", "other")
+
+
+class PermissiveDateField(serializers.CharField):
+    def to_internal_value(self, value):
+        if not value:
+            return None
+        value = super().to_internal_value(str(value))
+        ADDITIONAL_FORMATS = [
+            "%Y-%d-%m %H:%M",  # deezer date format
+            "%Y-%W",  # weird date format based on week number, see #718
+        ]
+
+        for date_format in ADDITIONAL_FORMATS:
+            try:
+                parsed = datetime.datetime.strptime(value, date_format)
+            except ValueError:
+                continue
+            else:
+                return datetime.date(parsed.year, parsed.month, parsed.day)
+
+        try:
+            parsed = pendulum.parse(str(value))
+            return datetime.date(parsed.year, parsed.month, parsed.day)
+        except pendulum.exceptions.ParserError:
+            pass
+
+        return None
+
+
+class ArtistSerializer(serializers.Serializer):
+    name = serializers.CharField()
+    mbid = serializers.UUIDField(required=False, allow_null=True)
+
+
+class AlbumSerializer(serializers.Serializer):
+    title = serializers.CharField()
+    mbid = serializers.UUIDField(required=False, allow_null=True)
+    release_date = PermissiveDateField(required=False, allow_null=True)
+
+
+class PositionField(serializers.CharField):
+    def to_internal_value(self, v):
+        v = super().to_internal_value(v)
+        if not v:
+            return v
+
+        try:
+            return int(v)
+        except ValueError:
+            # maybe the position is of the form "1/4"
+            pass
+
+        try:
+            return int(v.split("/")[0])
+        except (ValueError, AttributeError, IndexError):
+            pass
+
+
+class TrackMetadataSerializer(serializers.Serializer):
+    title = serializers.CharField()
+    position = PositionField(allow_null=True, required=False)
+    disc_number = PositionField(allow_null=True, required=False)
+    copyright = serializers.CharField(allow_null=True, required=False)
+    license = serializers.CharField(allow_null=True, required=False)
+    mbid = serializers.UUIDField(allow_null=True, required=False)
+
+    album = AlbumField()
+    artists = ArtistField()
+    cover_data = CoverDataField()
+
+
+class FakeMetadata(Mapping):
+    def __init__(self, data, picture=None):
+        self.data = data
+        self.picture = None
+
+    def __getitem__(self, key):
+        return self.data[key]
+
+    def __len__(self):
+        return len(self.data)
+
+    def __iter__(self):
+        yield from self.data
+
+    def get_picture(self, *args):
+        return self.picture
diff --git a/api/funkwhale_api/music/migrations/0038_attributed_to.py b/api/funkwhale_api/music/migrations/0038_attributed_to.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1ac8cfd4c4f5c5106f483fa1da8ab11852c659b
--- /dev/null
+++ b/api/funkwhale_api/music/migrations/0038_attributed_to.py
@@ -0,0 +1,48 @@
+# Generated by Django 2.1.7 on 2019-04-09 09:33
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("federation", "0017_auto_20190130_0926"),
+        ("music", "0037_auto_20190103_1757"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="artist",
+            name="attributed_to",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name="attributed_artists",
+                to="federation.Actor",
+            ),
+        ),
+        migrations.AddField(
+            model_name="album",
+            name="attributed_to",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name="attributed_albums",
+                to="federation.Actor",
+            ),
+        ),
+        migrations.AddField(
+            model_name="track",
+            name="attributed_to",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name="attributed_tracks",
+                to="federation.Actor",
+            ),
+        ),
+    ]
diff --git a/api/funkwhale_api/music/migrations/0039_auto_20190423_0820.py b/api/funkwhale_api/music/migrations/0039_auto_20190423_0820.py
new file mode 100644
index 0000000000000000000000000000000000000000..06ea1af3d8aeb397d3dc7bd3030972c9e40142a8
--- /dev/null
+++ b/api/funkwhale_api/music/migrations/0039_auto_20190423_0820.py
@@ -0,0 +1,31 @@
+# Generated by Django 2.1.7 on 2019-04-23 08:20
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('music', '0038_attributed_to'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='lyrics',
+            name='work',
+        ),
+        migrations.RemoveField(
+            model_name='work',
+            name='from_activity',
+        ),
+        migrations.RemoveField(
+            model_name='track',
+            name='work',
+        ),
+        migrations.DeleteModel(
+            name='Lyrics',
+        ),
+        migrations.DeleteModel(
+            name='Work',
+        ),
+    ]
diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 4ba8327179eebbe9f57628de37ab5faeb739ed5d..309eb1266dd5fd8db1446ff8981a89de4a1fecf9 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -3,9 +3,9 @@ import logging
 import mimetypes
 import os
 import tempfile
+import urllib.parse
 import uuid
 
-import markdown
 import pendulum
 import pydub
 from django.conf import settings
@@ -24,6 +24,7 @@ from versatileimagefield.image_warmer import VersatileImageFieldWarmer
 
 from funkwhale_api import musicbrainz
 from funkwhale_api.common import fields
+from funkwhale_api.common import models as common_models
 from funkwhale_api.common import session
 from funkwhale_api.common import utils as common_utils
 from funkwhale_api.federation import models as federation_models
@@ -113,6 +114,18 @@ class APIModelMixin(models.Model):
 
         return super().save(**kwargs)
 
+    @property
+    def is_local(self):
+        return federation_utils.is_local(self.fid)
+
+    @property
+    def domain_name(self):
+        if not self.fid:
+            return
+
+        parsed = urllib.parse.urlparse(self.fid)
+        return parsed.hostname
+
 
 class License(models.Model):
     code = models.CharField(primary_key=True, max_length=100)
@@ -141,7 +154,7 @@ class License(models.Model):
         logger.warning("%s do not match any registered license", self.code)
 
 
-class ArtistQuerySet(models.QuerySet):
+class ArtistQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet):
     def with_albums_count(self):
         return self.annotate(_albums_count=models.Count("albums"))
 
@@ -177,6 +190,16 @@ class Artist(APIModelMixin):
         "mbid": {"musicbrainz_field_name": "id"},
         "name": {"musicbrainz_field_name": "name"},
     }
+    # Music entities are attributed to actors, to validate that updates occur
+    # from an authorized account. On top of that, we consider the instance actor
+    # can update anything under it's own domain
+    attributed_to = models.ForeignKey(
+        "federation.Actor",
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
+        related_name="attributed_artists",
+    )
     api = musicbrainz.api.artists
     objects = ArtistQuerySet.as_manager()
 
@@ -215,7 +238,7 @@ def import_tracks(instance, cleaned_data, raw_data):
         importers.load(Track, track_cleaned_data, track_data, Track.import_hooks)
 
 
-class AlbumQuerySet(models.QuerySet):
+class AlbumQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet):
     def with_tracks_count(self):
         return self.annotate(_tracks_count=models.Count("tracks"))
 
@@ -253,6 +276,16 @@ class Album(APIModelMixin):
     TYPE_CHOICES = (("album", "Album"),)
     type = models.CharField(choices=TYPE_CHOICES, max_length=30, default="album")
 
+    # Music entities are attributed to actors, to validate that updates occur
+    # from an authorized account. On top of that, we consider the instance actor
+    # can update anything under it's own domain
+    attributed_to = models.ForeignKey(
+        "federation.Actor",
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
+        related_name="attributed_albums",
+    )
     api_includes = ["artist-credits", "recordings", "media", "release-groups"]
     api = musicbrainz.api.releases
     federation_namespace = "albums"
@@ -313,6 +346,16 @@ class Album(APIModelMixin):
     def __str__(self):
         return self.title
 
+    @property
+    def cover_path(self):
+        if not self.cover:
+            return None
+        try:
+            return self.cover.path
+        except NotImplementedError:
+            # external storage
+            return self.cover.name
+
     @property
     def tags(self):
         t = []
@@ -345,78 +388,7 @@ def import_album(v):
     return a
 
 
-def link_recordings(instance, cleaned_data, raw_data):
-    tracks = [r["target"] for r in raw_data["recording-relation-list"]]
-    Track.objects.filter(mbid__in=tracks).update(work=instance)
-
-
-def import_lyrics(instance, cleaned_data, raw_data):
-    try:
-        url = [
-            url_data
-            for url_data in raw_data["url-relation-list"]
-            if url_data["type"] == "lyrics"
-        ][0]["target"]
-    except (IndexError, KeyError):
-        return
-    l, _ = Lyrics.objects.get_or_create(work=instance, url=url)
-
-    return l
-
-
-class Work(APIModelMixin):
-    language = models.CharField(max_length=20)
-    nature = models.CharField(max_length=50)
-    title = models.CharField(max_length=255)
-
-    api = musicbrainz.api.works
-    api_includes = ["url-rels", "recording-rels"]
-    musicbrainz_model = "work"
-    federation_namespace = "works"
-
-    musicbrainz_mapping = {
-        "mbid": {"musicbrainz_field_name": "id"},
-        "title": {"musicbrainz_field_name": "title"},
-        "language": {"musicbrainz_field_name": "language"},
-        "nature": {"musicbrainz_field_name": "type", "converter": lambda v: v.lower()},
-    }
-    import_hooks = [import_lyrics, link_recordings]
-
-    def fetch_lyrics(self):
-        lyric = self.lyrics.first()
-        if lyric:
-            return lyric
-        data = self.api.get(self.mbid, includes=["url-rels"])["work"]
-        lyric = import_lyrics(self, {}, data)
-
-        return lyric
-
-    def get_federation_id(self):
-        if self.fid:
-            return self.fid
-
-        return None
-
-
-class Lyrics(models.Model):
-    uuid = models.UUIDField(unique=True, db_index=True, default=uuid.uuid4)
-    work = models.ForeignKey(
-        Work, related_name="lyrics", null=True, blank=True, on_delete=models.CASCADE
-    )
-    url = models.URLField(unique=True)
-    content = models.TextField(null=True, blank=True)
-
-    @property
-    def content_rendered(self):
-        return markdown.markdown(
-            self.content,
-            safe_mode=True,
-            enable_attributes=False,
-            extensions=["markdown.extensions.nl2br"],
-        )
-
-
-class TrackQuerySet(models.QuerySet):
+class TrackQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet):
     def for_nested_serialization(self):
         return self.select_related().select_related("album__artist", "artist")
 
@@ -465,9 +437,6 @@ class Track(APIModelMixin):
     album = models.ForeignKey(
         Album, related_name="tracks", null=True, blank=True, on_delete=models.CASCADE
     )
-    work = models.ForeignKey(
-        Work, related_name="tracks", null=True, blank=True, on_delete=models.CASCADE
-    )
     license = models.ForeignKey(
         License,
         null=True,
@@ -475,11 +444,21 @@ class Track(APIModelMixin):
         on_delete=models.DO_NOTHING,
         related_name="tracks",
     )
+    # Music entities are attributed to actors, to validate that updates occur
+    # from an authorized account. On top of that, we consider the instance actor
+    # can update anything under it's own domain
+    attributed_to = models.ForeignKey(
+        "federation.Actor",
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
+        related_name="attributed_tracks",
+    )
     copyright = models.CharField(max_length=500, null=True, blank=True)
     federation_namespace = "tracks"
     musicbrainz_model = "recording"
     api = musicbrainz.api.recordings
-    api_includes = ["artist-credits", "releases", "media", "tags", "work-rels"]
+    api_includes = ["artist-credits", "releases", "media", "tags"]
     musicbrainz_mapping = {
         "mbid": {"musicbrainz_field_name": "id"},
         "title": {"musicbrainz_field_name": "title"},
@@ -508,20 +487,6 @@ class Track(APIModelMixin):
             self.artist = self.album.artist
         super().save(**kwargs)
 
-    def get_work(self):
-        if self.work:
-            return self.work
-        data = self.api.get(self.mbid, includes=["work-rels"])
-        try:
-            work_data = data["recording"]["work-relation-list"][0]["work"]
-        except (IndexError, KeyError):
-            return
-        work, _ = Work.get_or_create_from_api(mbid=work_data["id"])
-        return work
-
-    def get_lyrics_url(self):
-        return reverse("api:v1:tracks-lyrics", kwargs={"pk": self.pk})
-
     @property
     def full_name(self):
         try:
@@ -605,7 +570,7 @@ class Track(APIModelMixin):
         return licenses.LICENSES_BY_ID.get(self.license_id)
 
 
-class UploadQuerySet(models.QuerySet):
+class UploadQuerySet(common_models.NullsLastQuerySet):
     def playable_by(self, actor, include=True):
         libraries = Library.objects.viewable_by(actor)
 
@@ -677,12 +642,12 @@ class Upload(models.Model):
 
     # metadata from federation
     metadata = JSONField(
-        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder
+        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
     )
     import_date = models.DateTimeField(null=True, blank=True)
     # optionnal metadata provided during import
     import_metadata = JSONField(
-        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder
+        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
     )
     # status / error details for the import
     import_status = models.CharField(
@@ -694,20 +659,32 @@ class Upload(models.Model):
 
     # optionnal metadata about import results (error messages, etc.)
     import_details = JSONField(
-        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder
+        default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
     )
     from_activity = models.ForeignKey(
-        "federation.Activity", null=True, on_delete=models.SET_NULL
+        "federation.Activity", null=True, on_delete=models.SET_NULL, blank=True
     )
 
     objects = UploadQuerySet.as_manager()
 
-    def download_audio_from_remote(self, user):
+    @property
+    def is_local(self):
+        return federation_utils.is_local(self.fid)
+
+    @property
+    def domain_name(self):
+        if not self.fid:
+            return
+
+        parsed = urllib.parse.urlparse(self.fid)
+        return parsed.hostname
+
+    def download_audio_from_remote(self, actor):
         from funkwhale_api.common import session
         from funkwhale_api.federation import signing
 
-        if user.is_authenticated and user.actor:
-            auth = signing.get_auth(user.actor.private_key, user.actor.private_key_id)
+        if actor:
+            auth = signing.get_auth(actor.private_key, actor.private_key_id)
         else:
             auth = None
 
@@ -812,23 +789,35 @@ class Upload(models.Model):
     def listen_url(self):
         return self.track.listen_url + "?upload={}".format(self.uuid)
 
-    def get_transcoded_version(self, format):
-        mimetype = utils.EXTENSION_TO_MIMETYPE[format]
-        existing_versions = list(self.versions.filter(mimetype=mimetype))
+    def get_transcoded_version(self, format, max_bitrate=None):
+        if format:
+            mimetype = utils.EXTENSION_TO_MIMETYPE[format]
+        else:
+            mimetype = self.mimetype or "audio/mpeg"
+            format = utils.MIMETYPE_TO_EXTENSION[mimetype]
+
+        existing_versions = self.versions.filter(mimetype=mimetype)
+        if max_bitrate is not None:
+            # we don't want to transcode if a 320kbps version is available
+            # and we're requestiong 300kbps
+            acceptable_max_bitrate = max_bitrate * 1.2
+            acceptable_min_bitrate = max_bitrate * 0.8
+            existing_versions = existing_versions.filter(
+                bitrate__gte=acceptable_min_bitrate, bitrate__lte=acceptable_max_bitrate
+            ).order_by("-bitrate")
         if existing_versions:
             # we found an existing version, no need to transcode again
             return existing_versions[0]
 
-        return self.create_transcoded_version(mimetype, format)
+        return self.create_transcoded_version(mimetype, format, bitrate=max_bitrate)
 
     @transaction.atomic
-    def create_transcoded_version(self, mimetype, format):
+    def create_transcoded_version(self, mimetype, format, bitrate):
         # we create the version with an empty file, then
         # we'll write to it
         f = ContentFile(b"")
-        version = self.versions.create(
-            mimetype=mimetype, bitrate=self.bitrate or 128000, size=0
-        )
+        bitrate = min(bitrate or 320000, self.bitrate or 320000)
+        version = self.versions.create(mimetype=mimetype, bitrate=bitrate, size=0)
         # we keep the same name, but we update the extension
         new_name = os.path.splitext(os.path.basename(self.audio_file.name))[
             0
@@ -838,6 +827,7 @@ class Upload(models.Model):
             audio=self.get_audio_segment(),
             output=version.audio_file,
             output_format=utils.MIMETYPE_TO_EXTENSION[mimetype],
+            bitrate=str(bitrate),
         )
         version.size = version.audio_file.size
         version.save(update_fields=["size"])
@@ -850,6 +840,16 @@ class Upload(models.Model):
             return
         return self.source.lstrip("file://")
 
+    @property
+    def audio_file_path(self):
+        if not self.audio_file:
+            return None
+        try:
+            return self.audio_file.path
+        except NotImplementedError:
+            # external storage
+            return self.audio_file.name
+
 
 MIMETYPE_CHOICES = [(mt, ext) for ext, mt in utils.AUDIO_EXTENSIONS_AND_MIMETYPE]
 
@@ -872,6 +872,16 @@ class UploadVersion(models.Model):
     def filename(self):
         return self.upload.filename
 
+    @property
+    def audio_file_path(self):
+        if not self.audio_file:
+            return None
+        try:
+            return self.audio_file.path
+        except NotImplementedError:
+            # external storage
+            return self.audio_file.name
+
 
 IMPORT_STATUS_CHOICES = (
     ("pending", "Pending"),
diff --git a/api/funkwhale_api/music/mutations.py b/api/funkwhale_api/music/mutations.py
new file mode 100644
index 0000000000000000000000000000000000000000..9fd91fb506d245e0ea50f5ef9cab28c7e7ee0dc1
--- /dev/null
+++ b/api/funkwhale_api/music/mutations.py
@@ -0,0 +1,62 @@
+from funkwhale_api.common import mutations
+from funkwhale_api.federation import routes
+
+from . import models
+
+
+def can_suggest(obj, actor):
+    return obj.is_local
+
+
+def can_approve(obj, actor):
+    return obj.is_local and actor.user and actor.user.get_permissions()["library"]
+
+
+@mutations.registry.connect(
+    "update",
+    models.Track,
+    perm_checkers={"suggest": can_suggest, "approve": can_approve},
+)
+class TrackMutationSerializer(mutations.UpdateMutationSerializer):
+    serialized_relations = {"license": "code"}
+
+    class Meta:
+        model = models.Track
+        fields = ["license", "title", "position", "copyright"]
+
+    def post_apply(self, obj, validated_data):
+        routes.outbox.dispatch(
+            {"type": "Update", "object": {"type": "Track"}}, context={"track": obj}
+        )
+
+
+@mutations.registry.connect(
+    "update",
+    models.Artist,
+    perm_checkers={"suggest": can_suggest, "approve": can_approve},
+)
+class ArtistMutationSerializer(mutations.UpdateMutationSerializer):
+    class Meta:
+        model = models.Artist
+        fields = ["name"]
+
+    def post_apply(self, obj, validated_data):
+        routes.outbox.dispatch(
+            {"type": "Update", "object": {"type": "Artist"}}, context={"artist": obj}
+        )
+
+
+@mutations.registry.connect(
+    "update",
+    models.Album,
+    perm_checkers={"suggest": can_suggest, "approve": can_approve},
+)
+class AlbumMutationSerializer(mutations.UpdateMutationSerializer):
+    class Meta:
+        model = models.Album
+        fields = ["title", "release_date"]
+
+    def post_apply(self, obj, validated_data):
+        routes.outbox.dispatch(
+            {"type": "Update", "object": {"type": "Album"}}, context={"album": obj}
+        )
diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py
index 192fc024cbd890f01aa5ef079c139a0039c6a373..867d15d8ddb864292263be107b159fb095f7de1e 100644
--- a/api/funkwhale_api/music/serializers.py
+++ b/api/funkwhale_api/music/serializers.py
@@ -43,6 +43,7 @@ class ArtistAlbumSerializer(serializers.ModelSerializer):
         model = models.Album
         fields = (
             "id",
+            "fid",
             "mbid",
             "title",
             "artist",
@@ -51,6 +52,7 @@ class ArtistAlbumSerializer(serializers.ModelSerializer):
             "creation_date",
             "tracks_count",
             "is_playable",
+            "is_local",
         )
 
     def get_tracks_count(self, o):
@@ -68,13 +70,13 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = models.Artist
-        fields = ("id", "mbid", "name", "creation_date", "albums")
+        fields = ("id", "fid", "mbid", "name", "creation_date", "albums", "is_local")
 
 
 class ArtistSimpleSerializer(serializers.ModelSerializer):
     class Meta:
         model = models.Artist
-        fields = ("id", "mbid", "name", "creation_date")
+        fields = ("id", "fid", "mbid", "name", "creation_date", "is_local")
 
 
 class AlbumTrackSerializer(serializers.ModelSerializer):
@@ -87,6 +89,7 @@ class AlbumTrackSerializer(serializers.ModelSerializer):
         model = models.Track
         fields = (
             "id",
+            "fid",
             "mbid",
             "title",
             "album",
@@ -99,6 +102,7 @@ class AlbumTrackSerializer(serializers.ModelSerializer):
             "duration",
             "copyright",
             "license",
+            "is_local",
         )
 
     def get_uploads(self, obj):
@@ -125,6 +129,7 @@ class AlbumSerializer(serializers.ModelSerializer):
         model = models.Album
         fields = (
             "id",
+            "fid",
             "mbid",
             "title",
             "artist",
@@ -133,6 +138,7 @@ class AlbumSerializer(serializers.ModelSerializer):
             "cover",
             "creation_date",
             "is_playable",
+            "is_local",
         )
 
     def get_tracks(self, o):
@@ -156,12 +162,14 @@ class TrackAlbumSerializer(serializers.ModelSerializer):
         model = models.Album
         fields = (
             "id",
+            "fid",
             "mbid",
             "title",
             "artist",
             "release_date",
             "cover",
             "creation_date",
+            "is_local",
         )
 
 
@@ -182,7 +190,6 @@ class TrackUploadSerializer(serializers.ModelSerializer):
 class TrackSerializer(serializers.ModelSerializer):
     artist = ArtistSimpleSerializer(read_only=True)
     album = TrackAlbumSerializer(read_only=True)
-    lyrics = serializers.SerializerMethodField()
     uploads = serializers.SerializerMethodField()
     listen_url = serializers.SerializerMethodField()
 
@@ -190,6 +197,7 @@ class TrackSerializer(serializers.ModelSerializer):
         model = models.Track
         fields = (
             "id",
+            "fid",
             "mbid",
             "title",
             "album",
@@ -197,16 +205,13 @@ class TrackSerializer(serializers.ModelSerializer):
             "creation_date",
             "position",
             "disc_number",
-            "lyrics",
             "uploads",
             "listen_url",
             "copyright",
             "license",
+            "is_local",
         )
 
-    def get_lyrics(self, obj):
-        return obj.get_lyrics_url()
-
     def get_listen_url(self, obj):
         return obj.listen_url
 
@@ -367,12 +372,6 @@ class SimpleAlbumSerializer(serializers.ModelSerializer):
         fields = ("id", "mbid", "title", "release_date", "cover")
 
 
-class LyricsSerializer(serializers.ModelSerializer):
-    class Meta:
-        model = models.Lyrics
-        fields = ("id", "work", "content", "content_rendered")
-
-
 class TrackActivitySerializer(activity_serializers.ModelSerializer):
     type = serializers.SerializerMethodField()
     name = serializers.CharField(source="title")
@@ -387,6 +386,10 @@ class TrackActivitySerializer(activity_serializers.ModelSerializer):
         return "Audio"
 
 
+def get_embed_url(type, id):
+    return settings.FUNKWHALE_EMBED_URL + "?type={}&id={}".format(type, id)
+
+
 class OembedSerializer(serializers.Serializer):
     format = serializers.ChoiceField(choices=["json"])
     url = serializers.URLField()
@@ -466,6 +469,36 @@ class OembedSerializer(serializers.Serializer):
                     "library_artist", kwargs={"pk": album.artist.pk}
                 )
             )
+        elif match.url_name == "library_artist":
+            qs = models.Artist.objects.filter(pk=int(match.kwargs["pk"]))
+            try:
+                artist = qs.get()
+            except models.Artist.DoesNotExist:
+                raise serializers.ValidationError(
+                    "No artist matching id {}".format(match.kwargs["pk"])
+                )
+            embed_type = "artist"
+            embed_id = artist.pk
+            album = (
+                artist.albums.filter(cover__isnull=False)
+                .exclude(cover="")
+                .order_by("-id")
+                .first()
+            )
+
+            if album and album.cover:
+                data["thumbnail_url"] = federation_utils.full_url(
+                    album.cover.crop["400x400"].url
+                )
+                data["thumbnail_width"] = 400
+                data["thumbnail_height"] = 400
+            data["title"] = artist.name
+            data["description"] = artist.name
+            data["author_name"] = artist.name
+            data["height"] = 400
+            data["author_url"] = federation_utils.full_url(
+                common_utils.spa_reverse("library_artist", kwargs={"pk": artist.pk})
+            )
         else:
             raise serializers.ValidationError(
                 "Unsupported url: {}".format(validated_data["url"])
@@ -473,10 +506,7 @@ class OembedSerializer(serializers.Serializer):
         data[
             "html"
         ] = '<iframe width="{}" height="{}" scrolling="no" frameborder="no" src="{}"></iframe>'.format(
-            data["width"],
-            data["height"],
-            settings.FUNKWHALE_EMBED_URL
-            + "?type={}&id={}".format(embed_type, embed_id),
+            data["width"], data["height"], get_embed_url(embed_type, embed_id)
         )
         return data
 
diff --git a/api/funkwhale_api/music/spa_views.py b/api/funkwhale_api/music/spa_views.py
index e71612caefd427578936e4285ba7bc9e6acd6cbb..7fafedf618ed013d08824d4e22cf73d705e3fdd3 100644
--- a/api/funkwhale_api/music/spa_views.py
+++ b/api/funkwhale_api/music/spa_views.py
@@ -2,10 +2,25 @@ import urllib.parse
 
 from django.conf import settings
 from django.urls import reverse
+from django.db.models import Q
 
 from funkwhale_api.common import utils
 
 from . import models
+from . import serializers
+
+
+def get_twitter_card_metas(type, id):
+    return [
+        {"tag": "meta", "property": "twitter:card", "content": "player"},
+        {
+            "tag": "meta",
+            "property": "twitter:player",
+            "content": serializers.get_embed_url(type, id),
+        },
+        {"tag": "meta", "property": "twitter:player:width", "content": "600"},
+        {"tag": "meta", "property": "twitter:player:height", "content": "400"},
+    ]
 
 
 def library_track(request, pk):
@@ -72,6 +87,8 @@ def library_track(request, pk):
                 ),
             }
         )
+        # twitter player is also supported in various software
+        metas += get_twitter_card_metas(type="track", id=obj.pk)
     return metas
 
 
@@ -131,6 +148,8 @@ def library_album(request, pk):
                 ),
             }
         )
+        # twitter player is also supported in various software
+        metas += get_twitter_card_metas(type="album", id=obj.pk)
     return metas
 
 
@@ -165,4 +184,22 @@ def library_artist(request, pk):
             }
         )
 
+    if (
+        models.Upload.objects.filter(Q(track__artist=obj) | Q(track__album__artist=obj))
+        .playable_by(None)
+        .exists()
+    ):
+        metas.append(
+            {
+                "tag": "link",
+                "rel": "alternate",
+                "type": "application/json+oembed",
+                "href": (
+                    utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
+                    + "?format=json&url={}".format(urllib.parse.quote_plus(artist_url))
+                ),
+            }
+        )
+        # twitter player is also supported in various software
+        metas += get_twitter_card_metas(type="artist", id=obj.pk)
     return metas
diff --git a/api/funkwhale_api/music/tasks.py b/api/funkwhale_api/music/tasks.py
index 946d7a411f9de1e1eb6089fd148974718e20ea65..ff3cde440a40eeb021e43127e5944d043dd151d7 100644
--- a/api/funkwhale_api/music/tasks.py
+++ b/api/funkwhale_api/music/tasks.py
@@ -17,7 +17,6 @@ from funkwhale_api.federation import library as lb
 from funkwhale_api.taskapp import celery
 
 from . import licenses
-from . import lyrics as lyrics_utils
 from . import models
 from . import metadata
 from . import signals
@@ -70,16 +69,6 @@ def get_cover_from_fs(dir_path):
                 return {"mimetype": m, "content": c.read()}
 
 
-@celery.app.task(name="Lyrics.fetch_content")
-@celery.require_instance(models.Lyrics, "lyrics")
-def fetch_content(lyrics):
-    html = lyrics_utils._get_html(lyrics.url)
-    content = lyrics_utils.extract_content(html)
-    cleaned_content = lyrics_utils.clean_content(content)
-    lyrics.content = cleaned_content
-    lyrics.save(update_fields=["content"])
-
-
 @celery.app.task(name="music.start_library_scan")
 @celery.require_instance(
     models.LibraryScan.objects.select_related().filter(status="pending"), "library_scan"
@@ -151,10 +140,11 @@ class UploadImportError(ValueError):
         super().__init__(code)
 
 
-def fail_import(upload, error_code):
+def fail_import(upload, error_code, detail=None, **fields):
     old_status = upload.import_status
     upload.import_status = "errored"
-    upload.import_details = {"error_code": error_code}
+    upload.import_details = {"error_code": error_code, "detail": detail}
+    upload.import_details.update(fields)
     upload.import_date = timezone.now()
     upload.save(update_fields=["import_details", "import_status", "import_date"])
 
@@ -182,20 +172,32 @@ def process_upload(upload):
     old_status = upload.import_status
     audio_file = upload.get_audio_file()
     additional_data = {}
+
+    m = metadata.Metadata(audio_file)
     try:
-        if not audio_file:
-            # we can only rely on user proveded data
-            final_metadata = import_metadata
-        else:
-            # we use user provided data and data from the file itself
-            m = metadata.Metadata(audio_file)
-            file_metadata = m.all()
-            final_metadata = collections.ChainMap(
-                additional_data, import_metadata, file_metadata
-            )
-            additional_data["cover_data"] = m.get_picture("cover_front", "other")
-        additional_data["upload_source"] = upload.source
-        track = get_track_from_import_metadata(final_metadata)
+        serializer = metadata.TrackMetadataSerializer(data=m)
+        serializer.is_valid()
+    except Exception:
+        fail_import(upload, "unknown_error")
+        raise
+    if not serializer.is_valid():
+        detail = serializer.errors
+        try:
+            metadata_dump = m.all()
+        except Exception as e:
+            logger.warn("Cannot dump metadata for file %s: %s", audio_file, str(e))
+        return fail_import(
+            upload, "invalid_metadata", detail=detail, file_metadata=metadata_dump
+        )
+
+    final_metadata = collections.ChainMap(
+        additional_data, serializer.validated_data, import_metadata
+    )
+    additional_data["upload_source"] = upload.source
+    try:
+        track = get_track_from_import_metadata(
+            final_metadata, attributed_to=upload.library.actor
+        )
     except UploadImportError as e:
         return fail_import(upload, e.code)
     except Exception:
@@ -271,48 +273,54 @@ def process_upload(upload):
         )
 
 
-def federation_audio_track_to_metadata(payload):
+def federation_audio_track_to_metadata(payload, references):
     """
     Given a valid payload as returned by federation.serializers.TrackSerializer.validated_data,
     returns a correct metadata payload for use with get_track_from_import_metadata.
     """
-    musicbrainz_recordingid = payload.get("musicbrainzId")
-    musicbrainz_artistid = payload["artists"][0].get("musicbrainzId")
-    musicbrainz_albumartistid = payload["album"]["artists"][0].get("musicbrainzId")
-    musicbrainz_albumid = payload["album"].get("musicbrainzId")
-
     new_data = {
         "title": payload["name"],
-        "album": payload["album"]["name"],
-        "track_number": payload.get("position") or 1,
+        "position": payload.get("position") or 1,
         "disc_number": payload.get("disc"),
-        "artist": payload["artists"][0]["name"],
-        "album_artist": payload["album"]["artists"][0]["name"],
-        "date": payload["album"].get("released"),
         "license": payload.get("license"),
         "copyright": payload.get("copyright"),
-        # musicbrainz
-        "musicbrainz_recordingid": str(musicbrainz_recordingid)
-        if musicbrainz_recordingid
-        else None,
-        "musicbrainz_artistid": str(musicbrainz_artistid)
-        if musicbrainz_artistid
-        else None,
-        "musicbrainz_albumartistid": str(musicbrainz_albumartistid)
-        if musicbrainz_albumartistid
-        else None,
-        "musicbrainz_albumid": str(musicbrainz_albumid)
-        if musicbrainz_albumid
+        "attributed_to": references.get(payload.get("attributedTo")),
+        "mbid": str(payload.get("musicbrainzId"))
+        if payload.get("musicbrainzId")
         else None,
+        "album": {
+            "title": payload["album"]["name"],
+            "fdate": payload["album"]["published"],
+            "fid": payload["album"]["id"],
+            "attributed_to": references.get(payload["album"].get("attributedTo")),
+            "mbid": str(payload["album"]["musicbrainzId"])
+            if payload["album"].get("musicbrainzId")
+            else None,
+            "release_date": payload["album"].get("released"),
+            "artists": [
+                {
+                    "fid": a["id"],
+                    "name": a["name"],
+                    "fdate": a["published"],
+                    "attributed_to": references.get(a.get("attributedTo")),
+                    "mbid": str(a["musicbrainzId"]) if a.get("musicbrainzId") else None,
+                }
+                for a in payload["album"]["artists"]
+            ],
+        },
+        "artists": [
+            {
+                "fid": a["id"],
+                "name": a["name"],
+                "fdate": a["published"],
+                "attributed_to": references.get(a.get("attributedTo")),
+                "mbid": str(a["musicbrainzId"]) if a.get("musicbrainzId") else None,
+            }
+            for a in payload["artists"]
+        ],
         # federation
         "fid": payload["id"],
-        "artist_fid": payload["artists"][0]["id"],
-        "album_artist_fid": payload["album"]["artists"][0]["id"],
-        "album_fid": payload["album"]["id"],
         "fdate": payload["published"],
-        "album_fdate": payload["album"]["published"],
-        "album_artist_fdate": payload["album"]["artists"][0]["published"],
-        "artist_fdate": payload["artists"][0]["published"],
     }
     cover = payload["album"].get("cover")
     if cover:
@@ -380,8 +388,8 @@ def sort_candidates(candidates, important_fields):
 
 
 @transaction.atomic
-def get_track_from_import_metadata(data, update_cover=False):
-    track = _get_track(data)
+def get_track_from_import_metadata(data, update_cover=False, attributed_to=None):
+    track = _get_track(data, attributed_to=attributed_to)
     if update_cover and track and not track.album.cover:
         update_album_cover(
             track.album,
@@ -391,7 +399,7 @@ def get_track_from_import_metadata(data, update_cover=False):
     return track
 
 
-def _get_track(data):
+def _get_track(data, attributed_to=None):
     track_uuid = getter(data, "funkwhale", "track", "uuid")
 
     if track_uuid:
@@ -405,8 +413,8 @@ def _get_track(data):
         return track
 
     from_activity_id = data.get("from_activity_id", None)
-    track_mbid = data.get("musicbrainz_recordingid", None)
-    album_mbid = data.get("musicbrainz_albumid", None)
+    track_mbid = data.get("mbid", None)
+    album_mbid = getter(data, "album", "mbid")
     track_fid = getter(data, "fid")
 
     query = None
@@ -428,12 +436,16 @@ def _get_track(data):
             pass
 
     # get / create artist and album artist
-    artist_mbid = data.get("musicbrainz_artistid", None)
-    artist_fid = data.get("artist_fid", None)
-    artist_name = data["artist"]
-    query = Q(name__iexact=artist_name)
+    artists = getter(data, "artists", default=[])
+    artist = artists[0]
+    artist_mbid = artist.get("mbid", None)
+    artist_fid = artist.get("fid", None)
+    artist_name = artist["name"]
+
     if artist_mbid:
-        query |= Q(mbid=artist_mbid)
+        query = Q(mbid=artist_mbid)
+    else:
+        query = Q(name__iexact=artist_name)
     if artist_fid:
         query |= Q(fid=artist_fid)
     defaults = {
@@ -441,21 +453,24 @@ def _get_track(data):
         "mbid": artist_mbid,
         "fid": artist_fid,
         "from_activity_id": from_activity_id,
+        "attributed_to": artist.get("attributed_to", attributed_to),
     }
-    if data.get("artist_fdate"):
-        defaults["creation_date"] = data.get("artist_fdate")
+    if artist.get("fdate"):
+        defaults["creation_date"] = artist.get("fdate")
 
     artist = get_best_candidate_or_create(
         models.Artist, query, defaults=defaults, sort_fields=["mbid", "fid"]
     )[0]
 
-    album_artist_name = data.get("album_artist") or artist_name
+    album_artists = getter(data, "album", "artists", default=artists) or artists
+    album_artist = album_artists[0]
+    album_artist_name = album_artist.get("name")
     if album_artist_name == artist_name:
         album_artist = artist
     else:
         query = Q(name__iexact=album_artist_name)
-        album_artist_mbid = data.get("musicbrainz_albumartistid", None)
-        album_artist_fid = data.get("album_artist_fid", None)
+        album_artist_mbid = album_artist.get("mbid", None)
+        album_artist_fid = album_artist.get("fid", None)
         if album_artist_mbid:
             query |= Q(mbid=album_artist_mbid)
         if album_artist_fid:
@@ -465,32 +480,38 @@ def _get_track(data):
             "mbid": album_artist_mbid,
             "fid": album_artist_fid,
             "from_activity_id": from_activity_id,
+            "attributed_to": album_artist.get("attributed_to", attributed_to),
         }
-        if data.get("album_artist_fdate"):
-            defaults["creation_date"] = data.get("album_artist_fdate")
+        if album_artist.get("fdate"):
+            defaults["creation_date"] = album_artist.get("fdate")
 
         album_artist = get_best_candidate_or_create(
             models.Artist, query, defaults=defaults, sort_fields=["mbid", "fid"]
         )[0]
 
     # get / create album
-    album_title = data["album"]
-    album_fid = data.get("album_fid", None)
-    query = Q(title__iexact=album_title, artist=album_artist)
+    album = data["album"]
+    album_title = album["title"]
+    album_fid = album.get("fid", None)
+
     if album_mbid:
-        query |= Q(mbid=album_mbid)
+        query = Q(mbid=album_mbid)
+    else:
+        query = Q(title__iexact=album_title, artist=album_artist)
+
     if album_fid:
         query |= Q(fid=album_fid)
     defaults = {
         "title": album_title,
         "artist": album_artist,
         "mbid": album_mbid,
-        "release_date": data.get("date"),
+        "release_date": album.get("release_date"),
         "fid": album_fid,
         "from_activity_id": from_activity_id,
+        "attributed_to": album.get("attributed_to", attributed_to),
     }
-    if data.get("album_fdate"):
-        defaults["creation_date"] = data.get("album_fdate")
+    if album.get("fdate"):
+        defaults["creation_date"] = album.get("fdate")
 
     album = get_best_candidate_or_create(
         models.Album, query, defaults=defaults, sort_fields=["mbid", "fid"]
@@ -498,8 +519,8 @@ def _get_track(data):
 
     # get / create track
     track_title = data["title"]
-    track_number = data.get("track_number", 1)
-    query = Q(title__iexact=track_title, artist=artist, album=album)
+    position = data.get("position", 1)
+    query = Q(title__iexact=track_title, artist=artist, album=album, position=position)
     if track_mbid:
         query |= Q(mbid=track_mbid)
     if track_fid:
@@ -509,10 +530,11 @@ def _get_track(data):
         "album": album,
         "mbid": track_mbid,
         "artist": artist,
-        "position": track_number,
+        "position": position,
         "disc_number": data.get("disc_number"),
         "fid": track_fid,
         "from_activity_id": from_activity_id,
+        "attributed_to": data.get("attributed_to", attributed_to),
         "license": licenses.match(data.get("license"), data.get("copyright")),
         "copyright": data.get("copyright"),
     }
@@ -562,3 +584,46 @@ def clean_transcoding_cache():
         .order_by("id")
     )
     return candidates.delete()
+
+
+def get_prunable_tracks(
+    exclude_favorites=True, exclude_playlists=True, exclude_listenings=True
+):
+    """
+    Returns a list of tracks with no associated uploads,
+    excluding the one that were listened/favorited/included in playlists.
+    """
+
+    queryset = models.Track.objects.all()
+    queryset = queryset.filter(uploads__isnull=True)
+    if exclude_favorites:
+        queryset = queryset.filter(track_favorites__isnull=True)
+    if exclude_playlists:
+        queryset = queryset.filter(playlist_tracks__isnull=True)
+    if exclude_listenings:
+        queryset = queryset.filter(listenings__isnull=True)
+
+    return queryset
+
+
+def get_prunable_albums():
+    return models.Album.objects.filter(tracks__isnull=True)
+
+
+def get_prunable_artists():
+    return models.Artist.objects.filter(tracks__isnull=True, albums__isnull=True)
+
+
+def update_library_entity(obj, data):
+    """
+    Given an obj and some updated fields, will persist the changes on the obj
+    and also check if the entity need to be aliased with existing objs (i.e
+    if a mbid was added on the obj, and match another entity with the same mbid)
+    """
+    for key, value in data.items():
+        setattr(obj, key, value)
+
+    # Todo: handle integrity error on unique fields (such as MBID)
+    obj.save(update_fields=list(data.keys()))
+
+    return obj
diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py
index 574f4c8e152fd7e6dd7bc87ae0d5183490a54c67..5031e69ba8030f3db1ec4bffa22bd01af1151c5f 100644
--- a/api/funkwhale_api/music/utils.py
+++ b/api/funkwhale_api/music/utils.py
@@ -39,6 +39,10 @@ AUDIO_EXTENSIONS_AND_MIMETYPE = [
 EXTENSION_TO_MIMETYPE = {ext: mt for ext, mt in AUDIO_EXTENSIONS_AND_MIMETYPE}
 MIMETYPE_TO_EXTENSION = {mt: ext for ext, mt in AUDIO_EXTENSIONS_AND_MIMETYPE}
 
+SUPPORTED_EXTENSIONS = list(
+    sorted(set([ext for ext, _ in AUDIO_EXTENSIONS_AND_MIMETYPE]))
+)
+
 
 def get_ext_from_type(mimetype):
     return MIMETYPE_TO_EXTENSION.get(mimetype)
diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py
index 5de07ca947edb23ac3a7334c6f94c294e1b64a15..391a4b333fe45628626383c4479d4a952c9df4b5 100644
--- a/api/funkwhale_api/music/views.py
+++ b/api/funkwhale_api/music/views.py
@@ -8,19 +8,23 @@ from django.db.models.functions import Length
 from django.utils import timezone
 
 from rest_framework import mixins
-from rest_framework import permissions
 from rest_framework import settings as rest_settings
 from rest_framework import views, viewsets
 from rest_framework.decorators import action
 from rest_framework.response import Response
 from taggit.models import Tag
 
+from funkwhale_api.common import decorators as common_decorators
 from funkwhale_api.common import permissions as common_permissions
 from funkwhale_api.common import preferences
 from funkwhale_api.common import utils as common_utils
+from funkwhale_api.common import views as common_views
 from funkwhale_api.federation.authentication import SignatureAuthentication
+from funkwhale_api.federation import actors
 from funkwhale_api.federation import api_serializers as federation_api_serializers
+from funkwhale_api.federation import decorators as federation_decorators
 from funkwhale_api.federation import routes
+from funkwhale_api.users.oauth import permissions as oauth_permissions
 
 from . import filters, licenses, models, serializers, tasks, utils
 
@@ -58,13 +62,18 @@ class TagViewSetMixin(object):
         return queryset
 
 
-class ArtistViewSet(viewsets.ReadOnlyModelViewSet):
+class ArtistViewSet(common_views.SkipFilterForGetObject, viewsets.ReadOnlyModelViewSet):
     queryset = models.Artist.objects.all()
     serializer_class = serializers.ArtistWithAlbumsSerializer
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     filterset_class = filters.ArtistFilter
     ordering_fields = ("id", "name", "creation_date")
 
+    fetches = federation_decorators.fetches_route()
+    mutations = common_decorators.mutations_route(types=["update"])
+
     def get_queryset(self):
         queryset = super().get_queryset()
         albums = models.Album.objects.with_tracks_count()
@@ -82,15 +91,20 @@ class ArtistViewSet(viewsets.ReadOnlyModelViewSet):
     )
 
 
-class AlbumViewSet(viewsets.ReadOnlyModelViewSet):
+class AlbumViewSet(common_views.SkipFilterForGetObject, viewsets.ReadOnlyModelViewSet):
     queryset = (
         models.Album.objects.all().order_by("artist", "release_date").select_related()
     )
     serializer_class = serializers.AlbumSerializer
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     ordering_fields = ("creation_date", "release_date", "title")
     filterset_class = filters.AlbumFilter
 
+    fetches = federation_decorators.fetches_route()
+    mutations = common_decorators.mutations_route(types=["update"])
+
     def get_queryset(self):
         queryset = super().get_queryset()
         tracks = (
@@ -123,9 +137,11 @@ class LibraryViewSet(
     )
     serializer_class = serializers.LibraryForOwnerSerializer
     permission_classes = [
-        permissions.IsAuthenticated,
+        oauth_permissions.ScopePermission,
         common_permissions.OwnerPermission,
     ]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     owner_field = "actor.user"
     owner_checks = ["read", "write"]
 
@@ -166,22 +182,30 @@ class LibraryViewSet(
         return Response(serializer.data)
 
 
-class TrackViewSet(TagViewSetMixin, viewsets.ReadOnlyModelViewSet):
+class TrackViewSet(
+    common_views.SkipFilterForGetObject, TagViewSetMixin, viewsets.ReadOnlyModelViewSet
+):
     """
     A simple ViewSet for viewing and editing accounts.
     """
 
     queryset = models.Track.objects.all().for_nested_serialization()
     serializer_class = serializers.TrackSerializer
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     filterset_class = filters.TrackFilter
     ordering_fields = (
         "creation_date",
         "title",
         "album__release_date",
         "size",
+        "position",
+        "disc_number",
         "artist__name",
     )
+    fetches = federation_decorators.fetches_route()
+    mutations = common_decorators.mutations_route(types=["update"])
 
     def get_queryset(self):
         queryset = super().get_queryset()
@@ -195,31 +219,6 @@ class TrackViewSet(TagViewSetMixin, viewsets.ReadOnlyModelViewSet):
         )
         return queryset
 
-    @action(methods=["get"], detail=True)
-    @transaction.non_atomic_requests
-    def lyrics(self, request, *args, **kwargs):
-        try:
-            track = models.Track.objects.get(pk=kwargs["pk"])
-        except models.Track.DoesNotExist:
-            return Response(status=404)
-
-        work = track.work
-        if not work:
-            work = track.get_work()
-
-        if not work:
-            return Response({"error": "unavailable work "}, status=404)
-
-        lyrics = work.fetch_lyrics()
-        try:
-            if not lyrics.content:
-                tasks.fetch_content(lyrics_id=lyrics.pk)
-                lyrics.refresh_from_db()
-        except AttributeError:
-            return Response({"error": "unavailable lyrics"}, status=404)
-        serializer = serializers.LyricsSerializer(lyrics)
-        return Response(serializer.data)
-
     libraries = action(methods=["get"], detail=True)(
         get_libraries(filter_uploads=lambda o, uploads: uploads.filter(track=o))
     )
@@ -241,6 +240,8 @@ def get_file_path(audio_file):
                     "MUSIC_DIRECTORY_PATH to serve in-place imported files"
                 )
             path = "/music" + audio_file.replace(prefix, "", 1)
+        if path.startswith("http://") or path.startswith("https://"):
+            return (settings.PROTECT_FILES_PATH + "/media/" + path).encode("utf-8")
         return (settings.PROTECT_FILES_PATH + path).encode("utf-8")
     if t == "apache2":
         try:
@@ -256,25 +257,35 @@ def get_file_path(audio_file):
         return path.encode("utf-8")
 
 
-def should_transcode(upload, format):
+def should_transcode(upload, format, max_bitrate=None):
     if not preferences.get("music__transcoding_enabled"):
         return False
+    format_need_transcoding = True
+    bitrate_need_transcoding = True
     if format is None:
-        return False
-    if format not in utils.EXTENSION_TO_MIMETYPE:
+        format_need_transcoding = False
+    elif format not in utils.EXTENSION_TO_MIMETYPE:
         # format should match supported formats
-        return False
-    if upload.mimetype is None:
+        format_need_transcoding = False
+    elif upload.mimetype is None:
         # upload should have a mimetype, otherwise we cannot transcode
-        return False
-    if upload.mimetype == utils.EXTENSION_TO_MIMETYPE[format]:
+        format_need_transcoding = False
+    elif upload.mimetype == utils.EXTENSION_TO_MIMETYPE[format]:
         # requested format sould be different than upload mimetype, otherwise
         # there is no need to transcode
-        return False
-    return True
+        format_need_transcoding = False
+
+    if max_bitrate is None:
+        bitrate_need_transcoding = False
+    elif not upload.bitrate:
+        bitrate_need_transcoding = False
+    elif upload.bitrate <= max_bitrate:
+        bitrate_need_transcoding = False
+
+    return format_need_transcoding or bitrate_need_transcoding
 
 
-def handle_serve(upload, user, format=None):
+def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
     f = upload
     # we update the accessed_date
     now = timezone.now()
@@ -295,7 +306,11 @@ def handle_serve(upload, user, format=None):
             # thus resulting in multiple downloads from the remote
             qs = f.__class__.objects.select_for_update()
             f = qs.get(pk=f.pk)
-            f.download_audio_from_remote(user=user)
+            if user.is_authenticated:
+                actor = user.actor
+            else:
+                actor = actors.get_service_actor()
+            f.download_audio_from_remote(actor=actor)
         data = f.get_audio_data()
         if data:
             f.duration = data["duration"]
@@ -307,13 +322,18 @@ def handle_serve(upload, user, format=None):
         file_path = get_file_path(f.source.replace("file://", "", 1))
     mt = f.mimetype
 
-    if should_transcode(f, format):
-        transcoded_version = upload.get_transcoded_version(format)
+    if should_transcode(f, format, max_bitrate=max_bitrate):
+        transcoded_version = f.get_transcoded_version(format, max_bitrate=max_bitrate)
         transcoded_version.accessed_date = now
         transcoded_version.save(update_fields=["accessed_date"])
         f = transcoded_version
         file_path = get_file_path(f.audio_file)
         mt = f.mimetype
+    if not proxy_media:
+        # we simply issue a 302 redirect to the real URL
+        response = Response(status=302)
+        response["Location"] = f.audio_file.url
+        return response
     if mt:
         response = Response(content_type=mt)
     else:
@@ -337,7 +357,9 @@ class ListenViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
         rest_settings.api_settings.DEFAULT_AUTHENTICATION_CLASSES
         + [SignatureAuthentication]
     )
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     lookup_field = "uuid"
 
     def retrieve(self, request, *args, **kwargs):
@@ -354,7 +376,21 @@ class ListenViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
             return Response(status=404)
 
         format = request.GET.get("to")
-        return handle_serve(upload, user=request.user, format=format)
+        max_bitrate = request.GET.get("max_bitrate")
+        try:
+            max_bitrate = min(max(int(max_bitrate), 0), 320) or None
+        except (TypeError, ValueError):
+            max_bitrate = None
+
+        if max_bitrate:
+            max_bitrate = max_bitrate * 1000
+        return handle_serve(
+            upload,
+            user=request.user,
+            format=format,
+            max_bitrate=max_bitrate,
+            proxy_media=settings.PROXY_MEDIA,
+        )
 
 
 class UploadViewSet(
@@ -372,9 +408,11 @@ class UploadViewSet(
     )
     serializer_class = serializers.UploadForOwnerSerializer
     permission_classes = [
-        permissions.IsAuthenticated,
+        oauth_permissions.ScopePermission,
         common_permissions.OwnerPermission,
     ]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     owner_field = "library.actor.user"
     owner_checks = ["read", "write"]
     filterset_class = filters.UploadFilter
@@ -419,12 +457,16 @@ class UploadViewSet(
 class TagViewSet(viewsets.ReadOnlyModelViewSet):
     queryset = Tag.objects.all().order_by("name")
     serializer_class = serializers.TagSerializer
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
 
 
 class Search(views.APIView):
     max_results = 3
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
 
     def get(self, request, *args, **kwargs):
         query = request.GET["query"]
@@ -489,10 +531,13 @@ class Search(views.APIView):
 
 
 class LicenseViewSet(viewsets.ReadOnlyModelViewSet):
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
     serializer_class = serializers.LicenseSerializer
     queryset = models.License.objects.all().order_by("code")
     lookup_value_regex = ".*"
+    max_page_size = 1000
 
     def get_queryset(self):
         # ensure our licenses are up to date in DB
@@ -514,7 +559,9 @@ class LicenseViewSet(viewsets.ReadOnlyModelViewSet):
 
 
 class OembedView(views.APIView):
-    permission_classes = [common_permissions.ConditionalAuthentication]
+    permission_classes = [oauth_permissions.ScopePermission]
+    required_scope = "libraries"
+    anonymous_policy = "setting"
 
     def get(self, request, *args, **kwargs):
         serializer = serializers.OembedSerializer(data=request.GET)
diff --git a/api/funkwhale_api/musicbrainz/client.py b/api/funkwhale_api/musicbrainz/client.py
index 1355da9438ea6b1a67a4fa659dccd83ddb8e30ce..ae038f9001d9ac896f528d19fe2d49280418c9ca 100644
--- a/api/funkwhale_api/musicbrainz/client.py
+++ b/api/funkwhale_api/musicbrainz/client.py
@@ -40,10 +40,6 @@ class API(object):
             _api.get_recording_by_id, max_age=settings.MUSICBRAINZ_CACHE_DURATION
         )
 
-    class works(object):
-        search = memo(_api.search_works, max_age=settings.MUSICBRAINZ_CACHE_DURATION)
-        get = memo(_api.get_work_by_id, max_age=settings.MUSICBRAINZ_CACHE_DURATION)
-
     class releases(object):
         search = memo(_api.search_releases, max_age=settings.MUSICBRAINZ_CACHE_DURATION)
         get = memo(_api.get_release_by_id, max_age=settings.MUSICBRAINZ_CACHE_DURATION)
diff --git a/api/funkwhale_api/playlists/models.py b/api/funkwhale_api/playlists/models.py
index 1d33388015a80c618628b4923311cab49f15298c..15332c75a2d8ec01d0d8bac3bafa41361bd83c24 100644
--- a/api/funkwhale_api/playlists/models.py
+++ b/api/funkwhale_api/playlists/models.py
@@ -17,7 +17,7 @@ class PlaylistQuerySet(models.QuerySet):
 
     def with_covers(self):
         album_prefetch = models.Prefetch(
-            "album", queryset=music_models.Album.objects.only("cover")
+            "album", queryset=music_models.Album.objects.only("cover", "artist_id")
         )
         track_prefetch = models.Prefetch(
             "track",
@@ -70,7 +70,7 @@ class Playlist(models.Model):
         return self.name
 
     @transaction.atomic
-    def insert(self, plt, index=None):
+    def insert(self, plt, index=None, allow_duplicates=True):
         """
         Given a PlaylistTrack, insert it at the correct index in the playlist,
         and update other tracks index if necessary.
@@ -96,6 +96,10 @@ class Playlist(models.Model):
         if index < 0:
             raise exceptions.ValidationError("Index must be zero or positive")
 
+        if not allow_duplicates:
+            existing_without_current_plt = existing.exclude(pk=plt.pk)
+            self._check_duplicate_add(existing_without_current_plt, [plt.track])
+
         if move:
             # we remove the index temporarily, to avoid integrity errors
             plt.index = None
@@ -125,7 +129,7 @@ class Playlist(models.Model):
         return to_update.update(index=models.F("index") - 1)
 
     @transaction.atomic
-    def insert_many(self, tracks):
+    def insert_many(self, tracks, allow_duplicates=True):
         existing = self.playlist_tracks.select_for_update()
         now = timezone.now()
         total = existing.filter(index__isnull=False).count()
@@ -134,6 +138,10 @@ class Playlist(models.Model):
             raise exceptions.ValidationError(
                 "Playlist would reach the maximum of {} tracks".format(max_tracks)
             )
+
+        if not allow_duplicates:
+            self._check_duplicate_add(existing, tracks)
+
         self.save(update_fields=["modification_date"])
         start = total
         plts = [
@@ -144,6 +152,26 @@ class Playlist(models.Model):
         ]
         return PlaylistTrack.objects.bulk_create(plts)
 
+    def _check_duplicate_add(self, existing_playlist_tracks, tracks_to_add):
+        track_ids = [t.pk for t in tracks_to_add]
+
+        duplicates = existing_playlist_tracks.filter(
+            track__pk__in=track_ids
+        ).values_list("track__pk", flat=True)
+        if duplicates:
+            duplicate_tracks = [t for t in tracks_to_add if t.pk in duplicates]
+            raise exceptions.ValidationError(
+                {
+                    "non_field_errors": [
+                        {
+                            "tracks": duplicate_tracks,
+                            "playlist_name": self.name,
+                            "code": "tracks_already_exist_in_playlist",
+                        }
+                    ]
+                }
+            )
+
 
 class PlaylistTrackQuerySet(models.QuerySet):
     def for_nested_serialization(self, actor=None):
diff --git a/api/funkwhale_api/playlists/serializers.py b/api/funkwhale_api/playlists/serializers.py
index b64996640259c03a6394c1353bea641afb31dcf5..ccdf82f4b94fcb11ce5b3d16f1aa96db47a4e7db 100644
--- a/api/funkwhale_api/playlists/serializers.py
+++ b/api/funkwhale_api/playlists/serializers.py
@@ -24,10 +24,11 @@ class PlaylistTrackSerializer(serializers.ModelSerializer):
 
 class PlaylistTrackWriteSerializer(serializers.ModelSerializer):
     index = serializers.IntegerField(required=False, min_value=0, allow_null=True)
+    allow_duplicates = serializers.BooleanField(required=False)
 
     class Meta:
         model = models.PlaylistTrack
-        fields = ("id", "track", "playlist", "index")
+        fields = ("id", "track", "playlist", "index", "allow_duplicates")
 
     def validate_playlist(self, value):
         if self.context.get("request"):
@@ -47,17 +48,21 @@ class PlaylistTrackWriteSerializer(serializers.ModelSerializer):
     @transaction.atomic
     def create(self, validated_data):
         index = validated_data.pop("index", None)
+        allow_duplicates = validated_data.pop("allow_duplicates", True)
         instance = super().create(validated_data)
-        instance.playlist.insert(instance, index)
+
+        instance.playlist.insert(instance, index, allow_duplicates)
         return instance
 
     @transaction.atomic
     def update(self, instance, validated_data):
         update_index = "index" in validated_data
         index = validated_data.pop("index", None)
+        allow_duplicates = validated_data.pop("allow_duplicates", True)
         super().update(instance, validated_data)
         if update_index:
-            instance.playlist.insert(instance, index)
+            instance.playlist.insert(instance, index, allow_duplicates)
+
         return instance
 
     def get_unique_together_validators(self):
@@ -117,9 +122,21 @@ class PlaylistSerializer(serializers.ModelSerializer):
         except AttributeError:
             return []
 
+        excluded_artists = []
+        try:
+            user = self.context["request"].user
+        except (KeyError, AttributeError):
+            user = None
+        if user and user.is_authenticated:
+            excluded_artists = list(
+                user.content_filters.values_list("target_artist", flat=True)
+            )
+
         covers = []
         max_covers = 5
         for plt in plts:
+            if plt.track.album.artist_id in excluded_artists:
+                continue
             url = plt.track.album.cover.crop["200x200"].url
             if url in covers:
                 continue
@@ -139,3 +156,7 @@ class PlaylistAddManySerializer(serializers.Serializer):
     tracks = serializers.PrimaryKeyRelatedField(
         many=True, queryset=Track.objects.for_nested_serialization()
     )
+    allow_duplicates = serializers.BooleanField(required=False)
+
+    class Meta:
+        fields = "allow_duplicates"
diff --git a/api/funkwhale_api/playlists/views.py b/api/funkwhale_api/playlists/views.py
index 2f536d7a712f47515dccc55a01d7ddc9fba55a47..861dc81755f6007ade9f47df442c92d110646363 100644
--- a/api/funkwhale_api/playlists/views.py
+++ b/api/funkwhale_api/playlists/views.py
@@ -2,11 +2,12 @@ from django.db import transaction
 from django.db.models import Count
 from rest_framework import exceptions, mixins, viewsets
 from rest_framework.decorators import action
-from rest_framework.permissions import IsAuthenticatedOrReadOnly
 from rest_framework.response import Response
 
 from funkwhale_api.common import fields, permissions
 from funkwhale_api.music import utils as music_utils
+from funkwhale_api.users.oauth import permissions as oauth_permissions
+
 from . import filters, models, serializers
 
 
@@ -28,10 +29,11 @@ class PlaylistViewSet(
         .with_duration()
     )
     permission_classes = [
-        permissions.ConditionalAuthentication,
+        oauth_permissions.ScopePermission,
         permissions.OwnerPermission,
-        IsAuthenticatedOrReadOnly,
     ]
+    required_scope = "playlists"
+    anonymous_policy = "setting"
     owner_checks = ["write"]
     filterset_class = filters.PlaylistFilter
     ordering_fields = ("id", "name", "creation_date", "modification_date")
@@ -53,7 +55,10 @@ class PlaylistViewSet(
         serializer = serializers.PlaylistAddManySerializer(data=request.data)
         serializer.is_valid(raise_exception=True)
         try:
-            plts = playlist.insert_many(serializer.validated_data["tracks"])
+            plts = playlist.insert_many(
+                serializer.validated_data["tracks"],
+                serializer.validated_data["allow_duplicates"],
+            )
         except exceptions.ValidationError as e:
             payload = {"playlist": e.detail}
             return Response(payload, status=400)
@@ -101,10 +106,11 @@ class PlaylistTrackViewSet(
     serializer_class = serializers.PlaylistTrackSerializer
     queryset = models.PlaylistTrack.objects.all()
     permission_classes = [
-        permissions.ConditionalAuthentication,
+        oauth_permissions.ScopePermission,
         permissions.OwnerPermission,
-        IsAuthenticatedOrReadOnly,
     ]
+    required_scope = "playlists"
+    anonymous_policy = "setting"
     owner_field = "playlist.user"
     owner_checks = ["write"]
 
diff --git a/api/funkwhale_api/radios/radios.py b/api/funkwhale_api/radios/radios.py
index 8d9eb816a192e6f6d5d3b72f04e1c14e4abb4da1..a0dc36b62adf8d76eb4c65f472ec04f440f56fc2 100644
--- a/api/funkwhale_api/radios/radios.py
+++ b/api/funkwhale_api/radios/radios.py
@@ -1,10 +1,11 @@
 import random
 
 from django.core.exceptions import ValidationError
-from django.db.models import Count
+from django.db import connection
 from rest_framework import serializers
 from taggit.models import Tag
 
+from funkwhale_api.moderation import filters as moderation_filters
 from funkwhale_api.music.models import Artist, Track
 from funkwhale_api.users.models import User
 
@@ -43,8 +44,16 @@ class SessionRadio(SimpleRadio):
         return self.session
 
     def get_queryset(self, **kwargs):
-        qs = Track.objects.annotate(uploads_count=Count("uploads"))
-        return qs.filter(uploads_count__gt=0)
+        qs = Track.objects.all()
+        if not self.session:
+            return qs
+        if not self.session.user:
+            return qs
+        query = moderation_filters.get_filtered_content_query(
+            config=moderation_filters.USER_FILTER_CONFIG["TRACK"],
+            user=self.session.user,
+        )
+        return qs.exclude(query)
 
     def get_queryset_kwargs(self):
         return {}
@@ -55,7 +64,13 @@ class SessionRadio(SimpleRadio):
         if self.session:
             queryset = self.filter_from_session(queryset)
             if kwargs.pop("filter_playable", True):
-                queryset = queryset.playable_by(self.session.user.actor)
+                queryset = queryset.playable_by(
+                    self.session.user.actor if self.session.user else None
+                )
+        queryset = self.filter_queryset(queryset)
+        return queryset
+
+    def filter_queryset(self, queryset):
         return queryset
 
     def filter_from_session(self, queryset):
@@ -118,7 +133,7 @@ class CustomRadio(SessionRadio):
         try:
             user = data["user"]
         except KeyError:
-            user = context["user"]
+            user = context.get("user")
         try:
             assert data["custom_radio"].user == user or data["custom_radio"].is_public
         except KeyError:
@@ -153,6 +168,74 @@ class TagRadio(RelatedObjectRadio):
         return qs.filter(tags__in=[self.session.related_object])
 
 
+def weighted_choice(choices):
+    total = sum(w for c, w in choices)
+    r = random.uniform(0, total)
+    upto = 0
+    for c, w in choices:
+        if upto + w >= r:
+            return c
+        upto += w
+    assert False, "Shouldn't get here"
+
+
+class NextNotFound(Exception):
+    pass
+
+
+@registry.register(name="similar")
+class SimilarRadio(RelatedObjectRadio):
+    model = Track
+
+    def filter_queryset(self, queryset):
+        queryset = super().filter_queryset(queryset)
+        seeds = list(
+            self.session.session_tracks.all()
+            .values_list("track_id", flat=True)
+            .order_by("-id")[:3]
+        ) + [self.session.related_object.pk]
+        for seed in seeds:
+            try:
+                return queryset.filter(pk=self.find_next_id(queryset, seed))
+            except NextNotFound:
+                continue
+
+        return queryset.none()
+
+    def find_next_id(self, queryset, seed):
+        with connection.cursor() as cursor:
+            query = """
+            SELECT next, count(next) AS c
+            FROM (
+                SELECT
+                    track_id,
+                    creation_date,
+                    LEAD(track_id) OVER (
+                        PARTITION by user_id order by creation_date asc
+                    ) AS next
+                FROM history_listening
+                INNER JOIN users_user ON (users_user.id = user_id)
+                WHERE users_user.privacy_level = 'instance' OR users_user.privacy_level = 'everyone' OR user_id = %s
+                ORDER BY creation_date ASC
+            ) t WHERE track_id = %s AND next != %s GROUP BY next ORDER BY c DESC;
+            """
+            cursor.execute(query, [self.session.user_id, seed, seed])
+            next_candidates = list(cursor.fetchall())
+
+        if not next_candidates:
+            raise NextNotFound()
+
+        matching_tracks = list(
+            queryset.filter(pk__in=[c[0] for c in next_candidates]).values_list(
+                "id", flat=True
+            )
+        )
+        next_candidates = [n for n in next_candidates if n[0] in matching_tracks]
+        if not next_candidates:
+            raise NextNotFound()
+        return random.choice([c[0] for c in next_candidates])
+
+
 @registry.register(name="artist")
 class ArtistRadio(RelatedObjectRadio):
     model = Artist
diff --git a/api/funkwhale_api/radios/serializers.py b/api/funkwhale_api/radios/serializers.py
index 9bffbf5b9cd3ce0c04100dcf3a68de008964b416..397452ecc0e5c6646a82ea663fdc6bb099e2f803 100644
--- a/api/funkwhale_api/radios/serializers.py
+++ b/api/funkwhale_api/radios/serializers.py
@@ -70,7 +70,7 @@ class RadioSessionSerializer(serializers.ModelSerializer):
         return data
 
     def create(self, validated_data):
-        validated_data["user"] = self.context["user"]
+        validated_data["user"] = self.context.get("user")
         if validated_data.get("related_object_id"):
             radio = registry[validated_data["radio_type"]]()
             validated_data["related_object"] = radio.get_related_object(
diff --git a/api/funkwhale_api/radios/views.py b/api/funkwhale_api/radios/views.py
index 5df0fe287a28f69513f97640f3790bb0cc031018..3c8f41c91fabdadf759a29587efd8fed77c016f2 100644
--- a/api/funkwhale_api/radios/views.py
+++ b/api/funkwhale_api/radios/views.py
@@ -1,10 +1,12 @@
 from django.db.models import Q
-from rest_framework import mixins, permissions, status, viewsets
+from rest_framework import mixins, status, viewsets
 from rest_framework.decorators import action
 from rest_framework.response import Response
 
 from funkwhale_api.common import permissions as common_permissions
 from funkwhale_api.music.serializers import TrackSerializer
+from funkwhale_api.music import utils as music_utils
+from funkwhale_api.users.oauth import permissions as oauth_permissions
 
 from . import filters, filtersets, models, serializers
 
@@ -20,12 +22,14 @@ class RadioViewSet(
 
     serializer_class = serializers.RadioSerializer
     permission_classes = [
-        permissions.IsAuthenticated,
+        oauth_permissions.ScopePermission,
         common_permissions.OwnerPermission,
     ]
     filterset_class = filtersets.RadioFilter
+    required_scope = "radios"
     owner_field = "user"
     owner_checks = ["write"]
+    anonymous_policy = "setting"
 
     def get_queryset(self):
         queryset = models.Radio.objects.all()
@@ -44,7 +48,9 @@ class RadioViewSet(
     def tracks(self, request, *args, **kwargs):
         radio = self.get_object()
         tracks = radio.get_candidates().for_nested_serialization()
-
+        actor = music_utils.get_actor_from_request(self.request)
+        tracks = tracks.with_playable_uploads(actor)
+        tracks = tracks.playable_by(actor)
         page = self.paginate_queryset(tracks)
         if page is not None:
             serializer = TrackSerializer(page, many=True)
@@ -80,29 +86,55 @@ class RadioSessionViewSet(
 
     serializer_class = serializers.RadioSessionSerializer
     queryset = models.RadioSession.objects.all()
-    permission_classes = [permissions.IsAuthenticated]
+    permission_classes = []
 
     def get_queryset(self):
         queryset = super().get_queryset()
-        return queryset.filter(user=self.request.user)
+        if self.request.user.is_authenticated:
+            return queryset.filter(
+                Q(user=self.request.user)
+                | Q(session_key=self.request.session.session_key)
+            )
+
+        return queryset.filter(session_key=self.request.session.session_key).exclude(
+            session_key=None
+        )
+
+    def perform_create(self, serializer):
+        if (
+            not self.request.user.is_authenticated
+            and not self.request.session.session_key
+        ):
+            self.request.session.create()
+        return serializer.save(
+            user=self.request.user if self.request.user.is_authenticated else None,
+            session_key=self.request.session.session_key,
+        )
 
     def get_serializer_context(self):
         context = super().get_serializer_context()
-        context["user"] = self.request.user
+        context["user"] = (
+            self.request.user if self.request.user.is_authenticated else None
+        )
         return context
 
 
 class RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
     serializer_class = serializers.RadioSessionTrackSerializer
     queryset = models.RadioSessionTrack.objects.all()
-    permission_classes = [permissions.IsAuthenticated]
+    permission_classes = []
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.data)
         serializer.is_valid(raise_exception=True)
         session = serializer.validated_data["session"]
+        if not request.user.is_authenticated and not request.session.session_key:
+            self.request.session.create()
         try:
-            assert request.user == session.user
+            assert (request.user == session.user) or (
+                request.session.session_key == session.session_key
+                and session.session_key
+            )
         except AssertionError:
             return Response(status=status.HTTP_403_FORBIDDEN)
         session.radio.pick()
diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py
index f7926d1fdc09250f049045ea8f72ac9542e1a0f8..88d7ece7c575d29bdcec0e7bbb8a056292ffd7d2 100644
--- a/api/funkwhale_api/subsonic/views.py
+++ b/api/funkwhale_api/subsonic/views.py
@@ -13,6 +13,7 @@ import funkwhale_api
 from funkwhale_api.activity import record
 from funkwhale_api.common import fields, preferences, utils as common_utils
 from funkwhale_api.favorites.models import TrackFavorite
+from funkwhale_api.moderation import filters as moderation_filters
 from funkwhale_api.music import models as music_models
 from funkwhale_api.music import utils
 from funkwhale_api.music import views as music_views
@@ -91,7 +92,7 @@ def get_playlist_qs(request):
 class SubsonicViewSet(viewsets.GenericViewSet):
     content_negotiation_class = negotiation.SubsonicContentNegociation
     authentication_classes = [authentication.SubsonicAuthentication]
-    permissions_classes = [rest_permissions.IsAuthenticated]
+    permission_classes = [rest_permissions.IsAuthenticated]
 
     def dispatch(self, request, *args, **kwargs):
         if not preferences.get("subsonic__enabled"):
@@ -127,7 +128,7 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         detail=False,
         methods=["get", "post"],
         url_name="get_license",
-        permissions_classes=[],
+        permission_classes=[],
         url_path="getLicense",
     )
     def get_license(self, request, *args, **kwargs):
@@ -152,8 +153,14 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         url_path="getArtists",
     )
     def get_artists(self, request, *args, **kwargs):
-        artists = music_models.Artist.objects.all().playable_by(
-            utils.get_actor_from_request(request)
+        artists = (
+            music_models.Artist.objects.all()
+            .exclude(
+                moderation_filters.get_filtered_content_query(
+                    moderation_filters.USER_FILTER_CONFIG["ARTIST"], request.user
+                )
+            )
+            .playable_by(utils.get_actor_from_request(request))
         )
         data = serializers.GetArtistsSerializer(artists).data
         payload = {"artists": data}
@@ -167,8 +174,14 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         url_path="getIndexes",
     )
     def get_indexes(self, request, *args, **kwargs):
-        artists = music_models.Artist.objects.all().playable_by(
-            utils.get_actor_from_request(request)
+        artists = (
+            music_models.Artist.objects.all()
+            .exclude(
+                moderation_filters.get_filtered_content_query(
+                    moderation_filters.USER_FILTER_CONFIG["ARTIST"], request.user
+                )
+            )
+            .playable_by(utils.get_actor_from_request(request))
         )
         data = serializers.GetArtistsSerializer(artists).data
         payload = {"indexes": data}
@@ -237,7 +250,24 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         format = data.get("format", "raw")
         if format == "raw":
             format = None
-        return music_views.handle_serve(upload=upload, user=request.user, format=format)
+
+        max_bitrate = data.get("maxBitRate")
+        try:
+            max_bitrate = min(max(int(max_bitrate), 0), 320) or None
+        except (TypeError, ValueError):
+            max_bitrate = None
+
+        if max_bitrate:
+            max_bitrate = max_bitrate * 1000
+        return music_views.handle_serve(
+            upload=upload,
+            user=request.user,
+            format=format,
+            max_bitrate=max_bitrate,
+            # Subsonic clients don't expect 302 redirection unfortunately,
+            # So we have to proxy media files
+            proxy_media=True,
+        )
 
     @action(detail=False, methods=["get", "post"], url_name="star", url_path="star")
     @find_object(music_models.Track.objects.all())
@@ -273,7 +303,11 @@ class SubsonicViewSet(viewsets.GenericViewSet):
     def get_random_songs(self, request, *args, **kwargs):
         data = request.GET or request.POST
         actor = utils.get_actor_from_request(request)
-        queryset = music_models.Track.objects.all()
+        queryset = music_models.Track.objects.all().exclude(
+            moderation_filters.get_filtered_content_query(
+                moderation_filters.USER_FILTER_CONFIG["TRACK"], request.user
+            )
+        )
         queryset = queryset.playable_by(actor)
         try:
             size = int(data["size"])
@@ -308,8 +342,14 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         url_path="getAlbumList2",
     )
     def get_album_list2(self, request, *args, **kwargs):
-        queryset = music_models.Album.objects.with_tracks_count().order_by(
-            "artist__name"
+        queryset = (
+            music_models.Album.objects.exclude(
+                moderation_filters.get_filtered_content_query(
+                    moderation_filters.USER_FILTER_CONFIG["ALBUM"], request.user
+                )
+            )
+            .with_tracks_count()
+            .order_by("artist__name")
         )
         data = request.GET or request.POST
         filterset = filters.AlbumList2FilterSet(data, queryset=queryset)
diff --git a/api/funkwhale_api/templates/account/email/email_confirmation_message.txt b/api/funkwhale_api/templates/account/email/email_confirmation_message.txt
index 8aec540fe15c602e99505231e2292cb09839930c..8464e057d4f497b4c0af8b7f5c6a6472f1d38116 100644
--- a/api/funkwhale_api/templates/account/email/email_confirmation_message.txt
+++ b/api/funkwhale_api/templates/account/email/email_confirmation_message.txt
@@ -1,8 +1,8 @@
-{% load account %}{% user_display user as user_display %}{% load i18n %}{% autoescape off %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Hello from {{ site_name }}!
+{% load account %}{% user_display user as user_display %}{% load i18n %}{% autoescape off %}{% blocktrans with site_name=funkwhale_site_name site_domain=funkwhale_site_domain %}Hello from {{ site_name }}!
 
 You're receiving this e-mail because user {{ user_display }} at {{ site_domain }} has given yours as an e-mail address to connect their account.
 
 To confirm this is correct, go to {{ funkwhale_url }}/auth/email/confirm?key={{ key }}
 {% endblocktrans %}{% endautoescape %}
-{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you from {{ site_name }}!
+{% blocktrans with site_name=funkwhale_site_name site_domain=funkwhale_site_domain %}Thank you from {{ site_name }}!
 {{ site_domain }}{% endblocktrans %}
diff --git a/api/funkwhale_api/templates/registration/password_reset_email.html b/api/funkwhale_api/templates/registration/password_reset_email.html
index 7a587d7204b1ae31eecc995bcca3d9a7e68a0e4d..0b6b1384d89036f8a3eb3f8b708559e721c8cca4 100644
--- a/api/funkwhale_api/templates/registration/password_reset_email.html
+++ b/api/funkwhale_api/templates/registration/password_reset_email.html
@@ -1,5 +1,5 @@
 {% load i18n %}{% autoescape off %}
-{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
+{% blocktrans with site_name=funkwhale_site_name %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
 
 {% trans "Please go to the following page and choose a new password:" %}
 {{ funkwhale_url }}/auth/password/reset/confirm?uid={{ uid }}&token={{ token }}
@@ -7,6 +7,6 @@
 
 {% trans "Thanks for using our site!" %}
 
-{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
+{% blocktrans with site_name=funkwhale_site_name %}The {{ site_name }} team{% endblocktrans %}
 
 {% endautoescape %}
diff --git a/api/funkwhale_api/users/adapters.py b/api/funkwhale_api/users/adapters.py
index 6d8c365d52be08db4551dc05044dd6cbb63cfa06..77171ff1b03f3c466673db9dfd9d809f6dd9da16 100644
--- a/api/funkwhale_api/users/adapters.py
+++ b/api/funkwhale_api/users/adapters.py
@@ -3,11 +3,22 @@ from django.conf import settings
 from dynamic_preferences.registries import global_preferences_registry
 
 
+def get_email_context():
+    context = {}
+    context["funkwhale_url"] = settings.FUNKWHALE_URL
+    manager = global_preferences_registry.manager()
+    context["funkwhale_site_name"] = (
+        manager["instance__name"] or settings.FUNKWHALE_HOSTNAME
+    )
+    context["funkwhale_site_domain"] = settings.FUNKWHALE_HOSTNAME
+    return context
+
+
 class FunkwhaleAccountAdapter(DefaultAccountAdapter):
     def is_open_for_signup(self, request):
         manager = global_preferences_registry.manager()
         return manager["users__registration_enabled"]
 
     def send_mail(self, template_prefix, email, context):
-        context["funkwhale_url"] = settings.FUNKWHALE_URL
+        context.update(get_email_context())
         return super().send_mail(template_prefix, email, context)
diff --git a/api/funkwhale_api/users/admin.py b/api/funkwhale_api/users/admin.py
index 303f4f9c3d4d575320ad53fcc2813e8c2ae7f456..c11c33bb66ce606de08777e7ac209fca923658d6 100644
--- a/api/funkwhale_api/users/admin.py
+++ b/api/funkwhale_api/users/admin.py
@@ -33,6 +33,20 @@ class MyUserCreationForm(UserCreationForm):
         raise forms.ValidationError(self.error_messages["duplicate_username"])
 
 
+def disable(modeladmin, request, queryset):
+    queryset.exclude(pk=request.user.pk).update(is_active=False)
+
+
+disable.short_description = "Disable login"
+
+
+def enable(modeladmin, request, queryset):
+    queryset.update(is_active=True)
+
+
+enable.short_description = "Enable login"
+
+
 @admin.register(models.User)
 class UserAdmin(AuthUserAdmin):
     form = MyUserChangeForm
@@ -40,6 +54,7 @@ class UserAdmin(AuthUserAdmin):
     list_display = [
         "username",
         "email",
+        "is_active",
         "date_joined",
         "last_login",
         "is_staff",
@@ -53,7 +68,7 @@ class UserAdmin(AuthUserAdmin):
         "permission_library",
         "permission_moderation",
     ]
-
+    actions = [disable, enable]
     fieldsets = (
         (None, {"fields": ("username", "password", "privacy_level")}),
         (
diff --git a/api/funkwhale_api/users/factories.py b/api/funkwhale_api/users/factories.py
index a5b113cf4506f0a8c80074f38f5cf98c98669ce6..e7f046ef3fa21f786038d302355b59bbab494ef9 100644
--- a/api/funkwhale_api/users/factories.py
+++ b/api/funkwhale_api/users/factories.py
@@ -1,7 +1,7 @@
+import pytz
 import factory
 from django.contrib.auth.models import Permission
 from django.utils import timezone
-
 from funkwhale_api.factories import ManyToManyFromList, registry, NoUpdateOnCreate
 
 from . import models
@@ -87,3 +87,49 @@ class UserFactory(factory.django.DjangoModelFactory):
 class SuperUserFactory(UserFactory):
     is_staff = True
     is_superuser = True
+
+
+@registry.register
+class ApplicationFactory(factory.django.DjangoModelFactory):
+    name = factory.Faker("name")
+    redirect_uris = factory.Faker("url")
+    client_type = models.Application.CLIENT_CONFIDENTIAL
+    authorization_grant_type = models.Application.GRANT_AUTHORIZATION_CODE
+    scope = "read"
+
+    class Meta:
+        model = "users.Application"
+
+
+@registry.register
+class GrantFactory(factory.django.DjangoModelFactory):
+    application = factory.SubFactory(ApplicationFactory)
+    scope = factory.SelfAttribute(".application.scope")
+    redirect_uri = factory.SelfAttribute(".application.redirect_uris")
+    user = factory.SubFactory(UserFactory)
+    expires = factory.Faker("future_datetime", end_date="+15m")
+    code = factory.Faker("uuid4")
+
+    class Meta:
+        model = "users.Grant"
+
+
+@registry.register
+class AccessTokenFactory(factory.django.DjangoModelFactory):
+    application = factory.SubFactory(ApplicationFactory)
+    user = factory.SubFactory(UserFactory)
+    expires = factory.Faker("future_datetime", tzinfo=pytz.UTC)
+    token = factory.Faker("uuid4")
+
+    class Meta:
+        model = "users.AccessToken"
+
+
+@registry.register
+class RefreshTokenFactory(factory.django.DjangoModelFactory):
+    application = factory.SubFactory(ApplicationFactory)
+    user = factory.SubFactory(UserFactory)
+    token = factory.Faker("uuid4")
+
+    class Meta:
+        model = "users.RefreshToken"
diff --git a/api/funkwhale_api/users/migrations/0014_oauth.py b/api/funkwhale_api/users/migrations/0014_oauth.py
new file mode 100644
index 0000000000000000000000000000000000000000..696867f68340129c66712450c6dfe36d5c405464
--- /dev/null
+++ b/api/funkwhale_api/users/migrations/0014_oauth.py
@@ -0,0 +1,195 @@
+# Generated by Django 2.0.9 on 2018-12-06 10:08
+
+from django.db import migrations, models
+import django.db.models.deletion
+from django.conf import settings
+import oauth2_provider.generators
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("users", "0013_auto_20181206_1008"),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="AccessToken",
+            fields=[
+                ("id", models.BigAutoField(primary_key=True, serialize=False)),
+                ("expires", models.DateTimeField()),
+                ("scope", models.TextField(blank=True)),
+                ("created", models.DateTimeField(auto_now_add=True)),
+                ("updated", models.DateTimeField(auto_now=True)),
+                ("token", models.CharField(max_length=255, unique=True)),
+            ],
+            options={"abstract": False},
+        ),
+        migrations.CreateModel(
+            name="Application",
+            fields=[
+                ("id", models.BigAutoField(primary_key=True, serialize=False)),
+                (
+                    "client_id",
+                    models.CharField(
+                        db_index=True,
+                        default=oauth2_provider.generators.generate_client_id,
+                        max_length=100,
+                        unique=True,
+                    ),
+                ),
+                (
+                    "redirect_uris",
+                    models.TextField(
+                        blank=True, help_text="Allowed URIs list, space separated"
+                    ),
+                ),
+                (
+                    "client_type",
+                    models.CharField(
+                        choices=[
+                            ("confidential", "Confidential"),
+                            ("public", "Public"),
+                        ],
+                        max_length=32,
+                    ),
+                ),
+                (
+                    "authorization_grant_type",
+                    models.CharField(
+                        choices=[
+                            ("authorization-code", "Authorization code"),
+                            ("implicit", "Implicit"),
+                            ("password", "Resource owner password-based"),
+                            ("client-credentials", "Client credentials"),
+                        ],
+                        max_length=32,
+                    ),
+                ),
+                (
+                    "client_secret",
+                    models.CharField(
+                        blank=True,
+                        db_index=True,
+                        default=oauth2_provider.generators.generate_client_secret,
+                        max_length=255,
+                    ),
+                ),
+                ("name", models.CharField(blank=True, max_length=255)),
+                ("skip_authorization", models.BooleanField(default=False)),
+                ("created", models.DateTimeField(auto_now_add=True)),
+                ("updated", models.DateTimeField(auto_now=True)),
+                (
+                    "user",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="users_application",
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+            options={"abstract": False},
+        ),
+        migrations.CreateModel(
+            name="Grant",
+            fields=[
+                ("id", models.BigAutoField(primary_key=True, serialize=False)),
+                ("code", models.CharField(max_length=255, unique=True)),
+                ("expires", models.DateTimeField()),
+                ("redirect_uri", models.CharField(max_length=255)),
+                ("scope", models.TextField(blank=True)),
+                ("created", models.DateTimeField(auto_now_add=True)),
+                ("updated", models.DateTimeField(auto_now=True)),
+                (
+                    "application",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="users.Application",
+                    ),
+                ),
+                (
+                    "user",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="users_grant",
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+            options={"abstract": False},
+        ),
+        migrations.CreateModel(
+            name="RefreshToken",
+            fields=[
+                ("id", models.BigAutoField(primary_key=True, serialize=False)),
+                ("token", models.CharField(max_length=255)),
+                ("created", models.DateTimeField(auto_now_add=True)),
+                ("updated", models.DateTimeField(auto_now=True)),
+                ("revoked", models.DateTimeField(null=True)),
+                (
+                    "access_token",
+                    models.OneToOneField(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="refresh_token",
+                        to="users.AccessToken",
+                    ),
+                ),
+                (
+                    "application",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="users.Application",
+                    ),
+                ),
+                (
+                    "user",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="users_refreshtoken",
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+            options={"abstract": False},
+        ),
+        migrations.AddField(
+            model_name="accesstoken",
+            name="application",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                to="users.Application",
+            ),
+        ),
+        migrations.AddField(
+            model_name="accesstoken",
+            name="source_refresh_token",
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name="refreshed_access_token",
+                to="users.RefreshToken",
+            ),
+        ),
+        migrations.AddField(
+            model_name="accesstoken",
+            name="user",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="users_accesstoken",
+                to=settings.AUTH_USER_MODEL,
+            ),
+        ),
+        migrations.AlterUniqueTogether(
+            name="refreshtoken", unique_together={("token", "revoked")}
+        ),
+    ]
diff --git a/api/funkwhale_api/users/migrations/0015_application_scope.py b/api/funkwhale_api/users/migrations/0015_application_scope.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fa8e52d75dd66bfd1676c48a7688eac7255361b
--- /dev/null
+++ b/api/funkwhale_api/users/migrations/0015_application_scope.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.1.7 on 2019-03-18 09:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('users', '0014_oauth'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='application',
+            name='scope',
+            field=models.TextField(blank=True),
+        ),
+    ]
diff --git a/api/funkwhale_api/users/models.py b/api/funkwhale_api/users/models.py
index 32e4869a37fbaa1ac313a2e88e7033ac7e9faeca..3748dd634b9abf68ac3ac76810d2be6ea65bf777 100644
--- a/api/funkwhale_api/users/models.py
+++ b/api/funkwhale_api/users/models.py
@@ -18,6 +18,8 @@ from django.utils.encoding import python_2_unicode_compatible
 from django.utils.translation import ugettext_lazy as _
 
 from django_auth_ldap.backend import populate_user as ldap_populate_user
+from oauth2_provider import models as oauth2_models
+from oauth2_provider import validators as oauth2_validators
 from versatileimagefield.fields import VersatileImageField
 from versatileimagefield.image_warmer import VersatileImageFieldWarmer
 
@@ -37,12 +39,37 @@ PERMISSIONS_CONFIGURATION = {
     "moderation": {
         "label": "Moderation",
         "help_text": "Block/mute/remove domains, users and content",
+        "scopes": {
+            "read:instance:policies",
+            "write:instance:policies",
+            "read:instance:accounts",
+            "write:instance:accounts",
+            "read:instance:domains",
+            "write:instance:domains",
+        },
     },
     "library": {
         "label": "Manage library",
         "help_text": "Manage library, delete files, tracks, artists, albums...",
+        "scopes": {
+            "read:instance:edits",
+            "write:instance:edits",
+            "read:instance:libraries",
+            "write:instance:libraries",
+        },
+    },
+    "settings": {
+        "label": "Manage instance-level settings",
+        "help_text": "",
+        "scopes": {
+            "read:instance:settings",
+            "write:instance:settings",
+            "read:instance:users",
+            "write:instance:users",
+            "read:instance:invitations",
+            "write:instance:invitations",
+        },
     },
-    "settings": {"label": "Manage instance-level settings", "help_text": ""},
 }
 
 PERMISSIONS = sorted(PERMISSIONS_CONFIGURATION.keys())
@@ -207,6 +234,16 @@ class User(AbstractUser):
     def full_username(self):
         return "{}@{}".format(self.username, settings.FEDERATION_HOSTNAME)
 
+    @property
+    def avatar_path(self):
+        if not self.avatar:
+            return None
+        try:
+            return self.avatar.path
+        except NotImplementedError:
+            # external storage
+            return self.avatar.name
+
 
 def generate_code(length=10):
     return "".join(
@@ -245,41 +282,91 @@ class Invitation(models.Model):
         return super().save(**kwargs)
 
 
-def get_actor_data(user):
-    username = federation_utils.slugify_username(user.username)
+class Application(oauth2_models.AbstractApplication):
+    scope = models.TextField(blank=True)
+
+    @property
+    def normalized_scopes(self):
+        from .oauth import permissions
+
+        raw_scopes = set(self.scope.split(" ") if self.scope else [])
+        return permissions.normalize(*raw_scopes)
+
+
+# oob schemes are not supported yet in oauth toolkit
+# (https://github.com/jazzband/django-oauth-toolkit/issues/235)
+# so in the meantime, we override their validation to add support
+OOB_SCHEMES = ["urn:ietf:wg:oauth:2.0:oob", "urn:ietf:wg:oauth:2.0:oob:auto"]
+
+
+class CustomRedirectURIValidator(oauth2_validators.RedirectURIValidator):
+    def __call__(self, value):
+        if value in OOB_SCHEMES:
+            return value
+        return super().__call__(value)
+
+
+oauth2_models.RedirectURIValidator = CustomRedirectURIValidator
+
+
+class Grant(oauth2_models.AbstractGrant):
+    pass
+
+
+class AccessToken(oauth2_models.AbstractAccessToken):
+    pass
+
+
+class RefreshToken(oauth2_models.AbstractRefreshToken):
+    pass
+
+
+def get_actor_data(username):
+    slugified_username = federation_utils.slugify_username(username)
     return {
-        "preferred_username": username,
+        "preferred_username": slugified_username,
         "domain": federation_models.Domain.objects.get_or_create(
             name=settings.FEDERATION_HOSTNAME
         )[0],
         "type": "Person",
-        "name": user.username,
+        "name": username,
         "manually_approves_followers": False,
         "fid": federation_utils.full_url(
-            reverse("federation:actors-detail", kwargs={"preferred_username": username})
+            reverse(
+                "federation:actors-detail",
+                kwargs={"preferred_username": slugified_username},
+            )
         ),
         "shared_inbox_url": federation_models.get_shared_inbox_url(),
         "inbox_url": federation_utils.full_url(
-            reverse("federation:actors-inbox", kwargs={"preferred_username": username})
+            reverse(
+                "federation:actors-inbox",
+                kwargs={"preferred_username": slugified_username},
+            )
         ),
         "outbox_url": federation_utils.full_url(
-            reverse("federation:actors-outbox", kwargs={"preferred_username": username})
+            reverse(
+                "federation:actors-outbox",
+                kwargs={"preferred_username": slugified_username},
+            )
         ),
         "followers_url": federation_utils.full_url(
             reverse(
-                "federation:actors-followers", kwargs={"preferred_username": username}
+                "federation:actors-followers",
+                kwargs={"preferred_username": slugified_username},
             )
         ),
         "following_url": federation_utils.full_url(
             reverse(
-                "federation:actors-following", kwargs={"preferred_username": username}
+                "federation:actors-following",
+                kwargs={"preferred_username": slugified_username},
             )
         ),
     }
 
 
 def create_actor(user):
-    args = get_actor_data(user)
+    args = get_actor_data(user.username)
     private, public = keys.get_key_pair()
     args["private_key"] = private.decode("utf-8")
     args["public_key"] = public.decode("utf-8")
@@ -301,3 +388,10 @@ def warm_user_avatar(sender, instance, **kwargs):
         instance_or_queryset=instance, rendition_key_set="square", image_attr="avatar"
     )
     num_created, failed_to_create = user_avatar_warmer.warm()
+
+
+@receiver(models.signals.pre_delete, sender=User)
+def delete_actor(sender, instance, **kwargs):
+    if not instance.actor:
+        return
+    instance.actor.delete()
diff --git a/api/funkwhale_api/users/oauth/__init__.py b/api/funkwhale_api/users/oauth/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/api/funkwhale_api/users/oauth/permissions.py b/api/funkwhale_api/users/oauth/permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebd44a937a6dee21e462d3321dfdf1dfcc7149b8
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/permissions.py
@@ -0,0 +1,123 @@
+from rest_framework import permissions
+from django.core.exceptions import ImproperlyConfigured
+
+from funkwhale_api.common import preferences
+
+from .. import models
+from . import scopes
+
+
+def normalize(*scope_ids):
+    """
+    Given an iterable containing scopes ids such as {read, write:playlists}
+    will return a set containing all the leaf scopes (and no parent scopes)
+    """
+    final = set()
+    for scope_id in scope_ids:
+        try:
+            scope_obj = scopes.SCOPES_BY_ID[scope_id]
+        except KeyError:
+            continue
+
+        if scope_obj.children:
+            final = final | {s.id for s in scope_obj.children}
+        else:
+            final.add(scope_obj.id)
+    return final
+
+
+def should_allow(required_scope, request_scopes):
+    if not required_scope:
+        return True
+
+    if not request_scopes:
+        return False
+
+    return required_scope in normalize(*request_scopes)
+
+
+METHOD_SCOPE_MAPPING = {
+    "get": "read",
+    "post": "write",
+    "patch": "write",
+    "put": "write",
+    "delete": "write",
+}
+
+
+class ScopePermission(permissions.BasePermission):
+    def has_permission(self, request, view):
+
+        if request.method.lower() in ["options", "head"]:
+            return True
+
+        try:
+            scope_config = getattr(view, "required_scope")
+        except AttributeError:
+            raise ImproperlyConfigured(
+                "ScopePermission requires the view to define the required_scope attribute"
+            )
+        anonymous_policy = getattr(view, "anonymous_policy", False)
+        if anonymous_policy not in [True, False, "setting"]:
+            raise ImproperlyConfigured(
+                "{} is not a valid value for anonymous_policy".format(anonymous_policy)
+            )
+        if isinstance(scope_config, str):
+            scope_config = {
+                "read": "read:{}".format(scope_config),
+                "write": "write:{}".format(scope_config),
+            }
+            action = METHOD_SCOPE_MAPPING[request.method.lower()]
+            required_scope = scope_config[action]
+        else:
+            # we have a dict with explicit viewset actions / scopes
+            required_scope = scope_config[view.action]
+
+        token = request.auth
+
+        if isinstance(token, models.AccessToken):
+            return self.has_permission_token(token, required_scope)
+        elif request.user.is_authenticated:
+            user_scopes = scopes.get_from_permissions(**request.user.get_permissions())
+            return should_allow(
+                required_scope=required_scope, request_scopes=user_scopes
+            )
+        elif hasattr(request, "actor") and request.actor:
+            # we use default anonymous scopes
+            user_scopes = scopes.FEDERATION_REQUEST_SCOPES
+            return should_allow(
+                required_scope=required_scope, request_scopes=user_scopes
+            )
+        else:
+            if anonymous_policy is False:
+                return False
+            if anonymous_policy == "setting" and preferences.get(
+                "common__api_authentication_required"
+            ):
+                return False
+
+            # we use default anonymous scopes
+            user_scopes = scopes.ANONYMOUS_SCOPES
+            return should_allow(
+                required_scope=required_scope, request_scopes=user_scopes
+            )
+
+    def has_permission_token(self, token, required_scope):
+
+        if token.is_expired():
+            return False
+
+        if not token.user:
+            return False
+
+        user = token.user
+        user_scopes = scopes.get_from_permissions(**user.get_permissions())
+        token_scopes = set(token.scopes.keys())
+        final_scopes = (
+            user_scopes
+            & normalize(*token_scopes)
+            & token.application.normalized_scopes
+            & scopes.OAUTH_APP_SCOPES
+        )
+
+        return should_allow(required_scope=required_scope, request_scopes=final_scopes)
diff --git a/api/funkwhale_api/users/oauth/scopes.py b/api/funkwhale_api/users/oauth/scopes.py
new file mode 100644
index 0000000000000000000000000000000000000000..61b07098383e832dcacd87f5da11fa843f821b29
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/scopes.py
@@ -0,0 +1,93 @@
+class Scope:
+    def __init__(self, id, label="", children=None):
+        self.id = id
+        self.label = ""
+        self.children = children or []
+
+    def copy(self, prefix):
+        return Scope("{}:{}".format(prefix, self.id))
+
+
+BASE_SCOPES = [
+    Scope(
+        "profile", "Access profile data (email, username, avatar, subsonic password…)"
+    ),
+    Scope("libraries", "Access uploads, libraries, and audio metadata"),
+    Scope("edits", "Browse and submit edits on audio metadata"),
+    Scope("follows", "Access library follows"),
+    Scope("favorites", "Access favorites"),
+    Scope("filters", "Access content filters"),
+    Scope("listenings", "Access listening history"),
+    Scope("radios", "Access radios"),
+    Scope("playlists", "Access playlists"),
+    Scope("notifications", "Access personal notifications"),
+    Scope("security", "Access security settings"),
+    # Privileged scopes that require specific user permissions
+    Scope("instance:settings", "Access instance settings"),
+    Scope("instance:users", "Access local user accounts"),
+    Scope("instance:invitations", "Access invitations"),
+    Scope("instance:edits", "Access instance metadata edits"),
+    Scope(
+        "instance:libraries", "Access instance uploads, libraries and audio metadata"
+    ),
+    Scope("instance:accounts", "Access instance federated accounts"),
+    Scope("instance:domains", "Access instance domains"),
+    Scope("instance:policies", "Access instance moderation policies"),
+]
+SCOPES = [
+    Scope("read", children=[s.copy("read") for s in BASE_SCOPES]),
+    Scope("write", children=[s.copy("write") for s in BASE_SCOPES]),
+]
+
+
+def flatten(*scopes):
+    for scope in scopes:
+        yield scope
+        yield from flatten(*scope.children)
+
+
+SCOPES_BY_ID = {s.id: s for s in flatten(*SCOPES)}
+
+FEDERATION_REQUEST_SCOPES = {"read:libraries"}
+ANONYMOUS_SCOPES = {
+    "read:libraries",
+    "read:playlists",
+    "read:listenings",
+    "read:favorites",
+    "read:radios",
+    "read:edits",
+}
+
+COMMON_SCOPES = ANONYMOUS_SCOPES | {
+    "read:profile",
+    "write:profile",
+    "write:libraries",
+    "write:playlists",
+    "read:follows",
+    "write:follows",
+    "write:favorites",
+    "read:notifications",
+    "write:notifications",
+    "write:radios",
+    "write:edits",
+    "read:filters",
+    "write:filters",
+    "write:listenings",
+}
+
+LOGGED_IN_SCOPES = COMMON_SCOPES | {"read:security", "write:security"}
+
+# We don't allow admin access for oauth apps yet
+OAUTH_APP_SCOPES = COMMON_SCOPES
+
+
+def get_from_permissions(**permissions):
+    from funkwhale_api.users import models
+
+    final = LOGGED_IN_SCOPES
+    for permission_name, value in permissions.items():
+        if value is False:
+            continue
+        config = models.PERMISSIONS_CONFIGURATION[permission_name]
+        final = final | config["scopes"]
+    return final
diff --git a/api/funkwhale_api/users/oauth/serializers.py b/api/funkwhale_api/users/oauth/serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..4788ba220a8077d2fd3c84fd555216c446cd8581
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/serializers.py
@@ -0,0 +1,29 @@
+from rest_framework import serializers
+
+from .. import models
+
+
+class ApplicationSerializer(serializers.ModelSerializer):
+    scopes = serializers.CharField(source="scope")
+
+    class Meta:
+        model = models.Application
+        fields = ["client_id", "name", "scopes", "created", "updated"]
+
+
+class CreateApplicationSerializer(serializers.ModelSerializer):
+    name = serializers.CharField(required=True, max_length=255)
+    scopes = serializers.CharField(source="scope", default="read")
+
+    class Meta:
+        model = models.Application
+        fields = [
+            "client_id",
+            "name",
+            "scopes",
+            "client_secret",
+            "created",
+            "updated",
+            "redirect_uris",
+        ]
+        read_only_fields = ["client_id", "client_secret", "created", "updated"]
diff --git a/api/funkwhale_api/users/oauth/server.py b/api/funkwhale_api/users/oauth/server.py
new file mode 100644
index 0000000000000000000000000000000000000000..f62ebf48a93c438e1f762dc95c2b2d0e85013111
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/server.py
@@ -0,0 +1,25 @@
+import urllib.parse
+import oauthlib.oauth2
+
+
+class OAuth2Server(oauthlib.oauth2.Server):
+    def verify_request(self, uri, *args, **kwargs):
+        valid, request = super().verify_request(uri, *args, **kwargs)
+        if valid:
+            return valid, request
+
+        # maybe the token was given in the querystring?
+        query = urllib.parse.urlparse(request.uri).query
+        token = None
+        if query:
+            parsed_qs = urllib.parse.parse_qs(query)
+            token = parsed_qs.get("token", [])
+            if len(token) > 0:
+                token = token[0]
+
+        if token:
+            valid = self.request_validator.validate_bearer_token(
+                token, request.scopes, request
+            )
+
+        return valid, request
diff --git a/api/funkwhale_api/users/oauth/tasks.py b/api/funkwhale_api/users/oauth/tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..2aaba353a793ccaa563e3ca18af8308f30cafaca
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/tasks.py
@@ -0,0 +1,8 @@
+from funkwhale_api.taskapp import celery
+
+from oauth2_provider import models as oauth2_models
+
+
+@celery.app.task(name="oauth.clear_expired_tokens")
+def clear_expired_tokens():
+    oauth2_models.clear_expired()
diff --git a/api/funkwhale_api/users/oauth/urls.py b/api/funkwhale_api/users/oauth/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..832f9ca1ba6cfd64a673213961ed35942aef3c98
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/urls.py
@@ -0,0 +1,16 @@
+from django.conf.urls import url
+from django.views.decorators.csrf import csrf_exempt
+
+from rest_framework import routers
+
+from . import views
+
+router = routers.SimpleRouter()
+router.register(r"apps", views.ApplicationViewSet, "apps")
+router.register(r"grants", views.GrantViewSet, "grants")
+
+urlpatterns = router.urls + [
+    url("^authorize/$", csrf_exempt(views.AuthorizeView.as_view()), name="authorize"),
+    url("^token/$", views.TokenView.as_view(), name="token"),
+    url("^revoke/$", views.RevokeTokenView.as_view(), name="revoke"),
+]
diff --git a/api/funkwhale_api/users/oauth/views.py b/api/funkwhale_api/users/oauth/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..a8bbb239ca50a22be070904fc73b2a5536e51fa4
--- /dev/null
+++ b/api/funkwhale_api/users/oauth/views.py
@@ -0,0 +1,182 @@
+import json
+import urllib.parse
+
+from django import http
+from django.utils import timezone
+from django.db.models import Q
+from rest_framework import mixins, permissions, views, viewsets
+
+from oauth2_provider import exceptions as oauth2_exceptions
+from oauth2_provider import views as oauth_views
+from oauth2_provider.settings import oauth2_settings
+
+from .. import models
+from .permissions import ScopePermission
+from . import serializers
+
+
+class ApplicationViewSet(
+    mixins.CreateModelMixin,
+    mixins.ListModelMixin,
+    mixins.UpdateModelMixin,
+    mixins.DestroyModelMixin,
+    mixins.RetrieveModelMixin,
+    viewsets.GenericViewSet,
+):
+    anonymous_policy = True
+    required_scope = {
+        "retrieve": None,
+        "create": None,
+        "destroy": "write:security",
+        "update": "write:security",
+        "partial_update": "write:security",
+        "list": "read:security",
+    }
+    lookup_field = "client_id"
+    queryset = models.Application.objects.all().order_by("-created")
+    serializer_class = serializers.ApplicationSerializer
+
+    def get_serializer_class(self):
+        if self.request.method.lower() == "post":
+            return serializers.CreateApplicationSerializer
+        return super().get_serializer_class()
+
+    def perform_create(self, serializer):
+        return serializer.save(
+            client_type=models.Application.CLIENT_CONFIDENTIAL,
+            authorization_grant_type=models.Application.GRANT_AUTHORIZATION_CODE,
+            user=self.request.user if self.request.user.is_authenticated else None,
+        )
+
+    def get_serializer(self, *args, **kwargs):
+        serializer_class = self.get_serializer_class()
+        try:
+            owned = args[0].user == self.request.user
+        except (IndexError, AttributeError):
+            owned = False
+        if owned:
+            serializer_class = serializers.CreateApplicationSerializer
+
+        kwargs["context"] = self.get_serializer_context()
+        return serializer_class(*args, **kwargs)
+
+    def get_queryset(self):
+        qs = super().get_queryset()
+        if self.action in ["list", "destroy", "update", "partial_update"]:
+            qs = qs.filter(user=self.request.user)
+        return qs
+
+
+class GrantViewSet(
+    mixins.RetrieveModelMixin,
+    mixins.DestroyModelMixin,
+    mixins.ListModelMixin,
+    viewsets.GenericViewSet,
+):
+    """
+    This is a viewset that list applications that have access to the request user
+    account, to allow revoking tokens easily.
+    """
+
+    permission_classes = [permissions.IsAuthenticated, ScopePermission]
+    required_scope = "security"
+    lookup_field = "client_id"
+    queryset = models.Application.objects.all().order_by("-created")
+    serializer_class = serializers.ApplicationSerializer
+    pagination_class = None
+
+    def get_queryset(self):
+        now = timezone.now()
+        queryset = super().get_queryset()
+        grants = models.Grant.objects.filter(user=self.request.user, expires__gt=now)
+        access_tokens = models.AccessToken.objects.filter(user=self.request.user)
+        refresh_tokens = models.RefreshToken.objects.filter(
+            user=self.request.user, revoked=None
+        )
+
+        return queryset.filter(
+            Q(pk__in=access_tokens.values("application"))
+            | Q(pk__in=refresh_tokens.values("application"))
+            | Q(pk__in=grants.values("application"))
+        ).distinct()
+
+    def perform_create(self, serializer):
+        return serializer.save(
+            client_type=models.Application.CLIENT_CONFIDENTIAL,
+            authorization_grant_type=models.Application.GRANT_AUTHORIZATION_CODE,
+        )
+
+    def perform_destroy(self, instance):
+        application = instance
+
+        access_tokens = application.accesstoken_set.filter(user=self.request.user)
+        for token in access_tokens:
+            token.revoke()
+
+        refresh_tokens = application.refreshtoken_set.filter(user=self.request.user)
+        for token in refresh_tokens:
+            try:
+                token.revoke()
+            except models.AccessToken.DoesNotExist:
+                token.access_token = None
+                token.revoked = timezone.now()
+                token.save(update_fields=["access_token", "revoked"])
+        grants = application.grant_set.filter(user=self.request.user)
+        grants.delete()
+
+
+class AuthorizeView(views.APIView, oauth_views.AuthorizationView):
+    permission_classes = [permissions.IsAuthenticated]
+    server_class = oauth2_settings.OAUTH2_SERVER_CLASS
+    validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
+    oauthlib_backend_class = oauth2_settings.OAUTH2_BACKEND_CLASS
+    skip_authorization_completely = False
+    oauth2_data = {}
+
+    def form_invalid(self, form):
+        """
+        Return a JSON response instead of a template one
+        """
+        errors = form.errors
+
+        return self.json_payload(errors, status_code=400)
+
+    def form_valid(self, form):
+        try:
+            response = super().form_valid(form)
+
+        except models.Application.DoesNotExist:
+            return self.json_payload({"non_field_errors": ["Invalid application"]}, 400)
+
+        if self.request.is_ajax() and response.status_code == 302:
+            # Web client need this to be able to redirect the user
+            query = urllib.parse.urlparse(response["Location"]).query
+            code = urllib.parse.parse_qs(query)["code"][0]
+            return self.json_payload(
+                {"redirect_uri": response["Location"], "code": code}, status_code=200
+            )
+
+        return response
+
+    def error_response(self, error, application):
+        if isinstance(error, oauth2_exceptions.FatalClientError):
+            return self.json_payload({"detail": error.oauthlib_error.description}, 400)
+        return super().error_response(error, application)
+
+    def json_payload(self, payload, status_code):
+        return http.HttpResponse(
+            json.dumps(payload), status=status_code, content_type="application/json"
+        )
+
+    def handle_no_permission(self):
+        return self.json_payload(
+            {"detail": "Authentication credentials were not provided."}, 401
+        )
+
+
+class TokenView(oauth_views.TokenView):
+    pass
+
+
+class RevokeTokenView(oauth_views.RevokeTokenView):
+    pass
diff --git a/api/funkwhale_api/users/permissions.py b/api/funkwhale_api/users/permissions.py
deleted file mode 100644
index 02c1198e8cb208a201bd257e910bce3c2d53174b..0000000000000000000000000000000000000000
--- a/api/funkwhale_api/users/permissions.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from rest_framework.permissions import BasePermission
-
-
-class HasUserPermission(BasePermission):
-    """
-    Ensure the request user has the proper permissions.
-
-    Usage:
-
-    class MyView(APIView):
-        permission_classes = [HasUserPermission]
-        required_permissions = ['federation']
-    """
-
-    def has_permission(self, request, view):
-        if not hasattr(request, "user") or not request.user:
-            return False
-        if request.user.is_anonymous:
-            return False
-        operator = getattr(view, "permission_operator", "and")
-        return request.user.has_permissions(
-            *view.required_permissions, operator=operator
-        )
diff --git a/api/funkwhale_api/users/serializers.py b/api/funkwhale_api/users/serializers.py
index c75604f6eb94ea97b26247604b13bf2c01fa6dfe..a45d414b4d9b6eaad6308aff70710df1f3e825c2 100644
--- a/api/funkwhale_api/users/serializers.py
+++ b/api/funkwhale_api/users/serializers.py
@@ -1,6 +1,5 @@
 import re
 
-from django.conf import settings
 from django.core import validators
 from django.utils.deconstruct import deconstructible
 from django.utils.translation import gettext_lazy as _
@@ -12,6 +11,7 @@ from versatileimagefield.serializers import VersatileImageFieldSerializer
 
 from funkwhale_api.activity import serializers as activity_serializers
 from funkwhale_api.common import serializers as common_serializers
+from . import adapters
 from . import models
 
 
@@ -94,6 +94,7 @@ class UserWriteSerializer(serializers.ModelSerializer):
 class UserReadSerializer(serializers.ModelSerializer):
 
     permissions = serializers.SerializerMethodField()
+    full_username = serializers.SerializerMethodField()
     avatar = avatar_field
 
     class Meta:
@@ -101,6 +102,7 @@ class UserReadSerializer(serializers.ModelSerializer):
         fields = [
             "id",
             "username",
+            "full_username",
             "name",
             "email",
             "is_staff",
@@ -114,6 +116,10 @@ class UserReadSerializer(serializers.ModelSerializer):
     def get_permissions(self, o):
         return o.get_permissions()
 
+    def get_full_username(self, o):
+        if o.actor:
+            return o.actor.full_username
+
 
 class MeSerializer(UserReadSerializer):
     quota_status = serializers.SerializerMethodField()
@@ -127,4 +133,4 @@ class MeSerializer(UserReadSerializer):
 
 class PasswordResetSerializer(PRS):
     def get_email_options(self):
-        return {"extra_email_context": {"funkwhale_url": settings.FUNKWHALE_URL}}
+        return {"extra_email_context": adapters.get_email_context()}
diff --git a/api/funkwhale_api/users/views.py b/api/funkwhale_api/users/views.py
index 2393882e725ada35c6d1890c82e04a685f60221f..8cbb23bd11fbc445feda2782ac77da8242d4e8c8 100644
--- a/api/funkwhale_api/users/views.py
+++ b/api/funkwhale_api/users/views.py
@@ -11,6 +11,7 @@ from . import models, serializers
 
 class RegisterView(BaseRegisterView):
     serializer_class = serializers.RegisterSerializer
+    permission_classes = []
 
     def create(self, request, *args, **kwargs):
         invitation_code = request.data.get("invitation")
@@ -27,6 +28,8 @@ class UserViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
     queryset = models.User.objects.all()
     serializer_class = serializers.UserWriteSerializer
     lookup_field = "username"
+    lookup_value_regex = r"[a-zA-Z0-9-_.]+"
+    required_scope = "profile"
 
     @action(methods=["get"], detail=False)
     def me(self, request, *args, **kwargs):
@@ -34,7 +37,12 @@ class UserViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
         serializer = serializers.MeSerializer(request.user)
         return Response(serializer.data)
 
-    @action(methods=["get", "post", "delete"], url_path="subsonic-token", detail=True)
+    @action(
+        methods=["get", "post", "delete"],
+        required_scope="security",
+        url_path="subsonic-token",
+        detail=True,
+    )
     def subsonic_token(self, request, *args, **kwargs):
         if not self.request.user.username == kwargs.get("username"):
             return Response(status=403)
diff --git a/api/requirements/base.txt b/api/requirements/base.txt
index c2fc95a6f3371772e9371bda64a5fdd941cb9f05..c72c20374ecbdb1f72ed0a3d0f4371339e0a90b7 100644
--- a/api/requirements/base.txt
+++ b/api/requirements/base.txt
@@ -1,5 +1,5 @@
 # Bleeding edge Django
-django>=2.1,<2.2
+django>=2.2.1,<2.3
 
 # Configuration
 django-environ>=0.4,<0.5
@@ -9,46 +9,43 @@ Pillow>=5.4,<5.5
 
 # For user registration, either via email or social
 # Well-built with regular release cycles!
-django-allauth>=0.36,<0.37
+django-allauth>=0.39,<0.40
 
 
 # Python-PostgreSQL Database Adapter
-psycopg2-binary>=2.7,<=2.8
+psycopg2-binary>=2.8,<=2.9
 
 # Time zones support
-pytz==2018.9
+pytz==2019.1
 
 # Redis support
 django-redis>=4.10,<4.11
-redis>=3.0,<3.1
-kombu>=4.2.2,<4.3
+redis>=3.2,<3.3
+kombu>=4.5,<4.6
 
-celery>=4.2,<4.3
+celery>=4.3,<4.4
 
 
 # Your custom requirements go here
-django-cors-headers>=2.1,<2.2
+django-cors-headers>=2.5.3,<2.6
 musicbrainzngs==0.6
 djangorestframework>=3.9,<3.10
 djangorestframework-jwt>=1.11,<1.12
 pendulum>=2,<3
 persisting-theory>=0.2,<0.3
-django-versatileimagefield>=1.9,<1.10
-django-filter>=2.0,<2.1
+django-versatileimagefield>=1.10,<1.11
+django-filter>=2.1,<2.2
 django-rest-auth>=0.9,<0.10
-beautifulsoup4>=4.6,<4.7
-Markdown>=2.6,<2.7
-ipython>=6,<7
+ipython>=7,<8
 mutagen>=1.42,<1.43
 
 
-django-taggit>=0.23,<0.24
+django-taggit>=0.24,<0.25
 pymemoize==1.0.3
 
 django-dynamic-preferences>=1.7,<1.8
-raven>=6.5,<7
+raven>=6.10,<7
 python-magic==0.4.15
-ffmpeg-python==0.1.10
 # XXX: until https://github.com/django/channels/issues/1240 is fixed
 channels==2.1.6
 channels_redis>=2.3,<2.4
@@ -58,9 +55,17 @@ cryptography>=2,<3
 # requests-http-signature==0.0.3
 # clone until the branch is merged and released upstream
 git+https://github.com/EliotBerriot/requests-http-signature.git@signature-header-support
-django-cleanup==2.1.0
+django-cleanup==3.2.0
 
 # for LDAP authentication
-python-ldap==3.1.0
+python-ldap==3.2.0
 django-auth-ldap==1.7.0
-pydub==0.23.0
+pydub==0.23.1
+
+pyld==1.0.4
+aiohttp==3.5.4
+autobahn>=19.3.3
+
+django-oauth-toolkit==1.2
+django-storages==1.7.1
+boto3<3
diff --git a/api/requirements/local.txt b/api/requirements/local.txt
index 60724fc959a0b666d8b15cb39d333e6d61f89866..dcedb43e75c0073424c31608d3510f7000ae9acc 100644
--- a/api/requirements/local.txt
+++ b/api/requirements/local.txt
@@ -11,3 +11,6 @@ django-debug-toolbar>=1.11,<1.12
 ipdb==0.11
 black
 profiling
+
+asynctest==0.12.2
+aioresponses==0.6.0
diff --git a/api/setup.cfg b/api/setup.cfg
index a3c0e746864b1eb9bd92d7d9077c63490cebe2f6..431c4f1ee58f6ad5c7ac70cba9dd34081700c4ad 100644
--- a/api/setup.cfg
+++ b/api/setup.cfg
@@ -24,3 +24,4 @@ env =
     WEAK_PASSWORDS=True
     CREATE_IMAGE_THUMBNAILS=False
     FORCE_HTTPS_URLS=False
+    FUNKWHALE_SPA_HTML_ROOT=http://noop/
diff --git a/api/tests/common/test_decorators.py b/api/tests/common/test_decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..f8fef79045f744f965f16723dc071503148d7283
--- /dev/null
+++ b/api/tests/common/test_decorators.py
@@ -0,0 +1,122 @@
+import pytest
+
+from rest_framework import viewsets
+
+from funkwhale_api.common import decorators
+from funkwhale_api.common import models
+from funkwhale_api.common import mutations
+from funkwhale_api.common import serializers
+from funkwhale_api.common import signals
+from funkwhale_api.common import tasks
+from funkwhale_api.music import models as music_models
+from funkwhale_api.music import licenses
+
+
+class V(viewsets.ModelViewSet):
+    queryset = music_models.Track.objects.all()
+    mutations = decorators.mutations_route(types=["update"])
+    permission_classes = []
+
+
+def test_mutations_route_list(factories, api_request):
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](target=track, type="update", payload="")
+    factories["common.Mutation"](target=track, type="noop", payload="")
+
+    view = V.as_view({"get": "mutations"})
+    expected = {
+        "next": None,
+        "previous": None,
+        "count": 1,
+        "results": [serializers.APIMutationSerializer(mutation).data],
+    }
+
+    request = api_request.get("/")
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+@pytest.mark.parametrize("is_approved", [False, True])
+def test_mutations_route_create_success(factories, api_request, is_approved, mocker):
+    licenses.load(licenses.LICENSES)
+    on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
+    user = factories["users.User"](permission_library=True)
+    actor = user.create_actor()
+    track = factories["music.Track"](title="foo", local=True)
+    view = V.as_view({"post": "mutations"})
+
+    request = api_request.post(
+        "/",
+        {
+            "type": "update",
+            "payload": {"title": "bar", "unknown": "test", "license": "cc-by-nc-4.0"},
+            "summary": "hello",
+            "is_approved": is_approved,
+        },
+        format="json",
+    )
+    setattr(request, "user", user)
+    setattr(request, "session", {})
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 201
+
+    mutation = models.Mutation.objects.get_for_target(track).latest("id")
+
+    assert mutation.type == "update"
+    assert mutation.payload == {"title": "bar", "license": "cc-by-nc-4.0"}
+    assert mutation.created_by == actor
+    assert mutation.is_approved is is_approved
+    assert mutation.is_applied is None
+    assert mutation.target == track
+    assert mutation.summary == "hello"
+
+    if is_approved:
+        on_commit.assert_any_call(tasks.apply_mutation.delay, mutation_id=mutation.pk)
+    expected = serializers.APIMutationSerializer(mutation).data
+    assert response.data == expected
+    on_commit.assert_any_call(
+        signals.mutation_created.send, mutation=mutation, sender=None
+    )
+
+
+def test_mutations_route_create_no_auth(factories, api_request):
+    track = factories["music.Track"](title="foo")
+    view = V.as_view({"post": "mutations"})
+
+    request = api_request.post("/", {}, format="json")
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 401
+
+
+@pytest.mark.parametrize("is_approved", [False, True])
+def test_mutations_route_create_no_perm(factories, api_request, mocker, is_approved):
+    track = factories["music.Track"](title="foo")
+    view = V.as_view({"post": "mutations"})
+    user = factories["users.User"]()
+    actor = user.create_actor()
+    has_perm = mocker.patch.object(mutations.registry, "has_perm", return_value=False)
+    request = api_request.post(
+        "/",
+        {
+            "type": "update",
+            "payload": {"title": "bar", "unknown": "test"},
+            "summary": "hello",
+            "is_approved": is_approved,
+        },
+        format="json",
+    )
+    setattr(request, "user", user)
+    setattr(request, "session", {})
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 403
+    has_perm.assert_called_once_with(
+        actor=actor,
+        obj=track,
+        type="update",
+        perm="approve" if is_approved else "suggest",
+    )
diff --git a/api/tests/common/test_filters.py b/api/tests/common/test_filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e89dfa37c1dc2800569aca928b9452e0b2d29fe
--- /dev/null
+++ b/api/tests/common/test_filters.py
@@ -0,0 +1,38 @@
+import pytest
+
+from funkwhale_api.common import filters
+
+
+@pytest.mark.parametrize(
+    "value, expected",
+    [
+        (True, True),
+        ("True", True),
+        ("true", True),
+        ("1", True),
+        ("yes", True),
+        (False, False),
+        ("False", False),
+        ("false", False),
+        ("0", False),
+        ("no", False),
+        ("None", None),
+        ("none", None),
+        ("Null", None),
+        ("null", None),
+    ],
+)
+def test_mutation_filter_is_approved(value, expected, factories):
+    mutations = {
+        True: factories["common.Mutation"](is_approved=True, payload={}),
+        False: factories["common.Mutation"](is_approved=False, payload={}),
+        None: factories["common.Mutation"](is_approved=None, payload={}),
+    }
+
+    qs = mutations[True].__class__.objects.all()
+
+    filterset = filters.MutationFilter(
+        {"q": "is_approved:{}".format(value)}, queryset=qs
+    )
+
+    assert list(filterset.qs) == [mutations[expected]]
diff --git a/api/tests/common/test_models.py b/api/tests/common/test_models.py
new file mode 100644
index 0000000000000000000000000000000000000000..25c9befda809de508864b39f7bdc551f6600b14b
--- /dev/null
+++ b/api/tests/common/test_models.py
@@ -0,0 +1,17 @@
+import pytest
+
+from django.urls import reverse
+
+from funkwhale_api.federation import utils as federation_utils
+
+
+@pytest.mark.parametrize(
+    "model,factory_args,namespace",
+    [("common.Mutation", {"created_by__local": True}, "federation:edits-detail")],
+)
+def test_mutation_fid_is_populated(factories, model, factory_args, namespace):
+    instance = factories[model](**factory_args, fid=None, payload={})
+
+    assert instance.fid == federation_utils.full_url(
+        reverse(namespace, kwargs={"uuid": instance.uuid})
+    )
diff --git a/api/tests/common/test_mutations.py b/api/tests/common/test_mutations.py
new file mode 100644
index 0000000000000000000000000000000000000000..3c0d869a116fd832b9927e1b4c7c1da51b4a88e2
--- /dev/null
+++ b/api/tests/common/test_mutations.py
@@ -0,0 +1,141 @@
+import pytest
+
+from funkwhale_api.common import mutations
+
+from rest_framework import serializers
+
+
+@pytest.fixture
+def mutations_registry():
+    return mutations.Registry()
+
+
+def test_apply_mutation(mutations_registry, db):
+    class Obj:
+        pass
+
+    obj = Obj()
+
+    @mutations_registry.connect("foo", Obj)
+    class S(mutations.MutationSerializer):
+        foo = serializers.ChoiceField(choices=["bar", "baz"])
+
+        def apply(self, obj, validated_data):
+            setattr(obj, "foo", validated_data["foo"])
+
+    with pytest.raises(mutations.ConfNotFound):
+        mutations_registry.apply("foo", object(), payload={"foo": "nope"})
+
+    with pytest.raises(serializers.ValidationError):
+        mutations_registry.apply("foo", obj, payload={"foo": "nope"})
+
+    mutations_registry.apply("foo", obj, payload={"foo": "bar"})
+
+    assert obj.foo == "bar"
+
+
+def test_apply_update_mutation(factories, mutations_registry, mocker):
+    user = factories["users.User"](email="hello@test.email")
+    get_update_previous_state = mocker.patch.object(
+        mutations, "get_update_previous_state"
+    )
+
+    @mutations_registry.connect("update", user.__class__)
+    class S(mutations.UpdateMutationSerializer):
+        class Meta:
+            model = user.__class__
+            fields = ["username", "email"]
+
+    previous_state = mutations_registry.apply(
+        "update", user, payload={"username": "foo"}
+    )
+    assert previous_state == get_update_previous_state.return_value
+    get_update_previous_state.assert_called_once_with(
+        user, "username", serialized_relations={}
+    )
+    user.refresh_from_db()
+
+    assert user.username == "foo"
+    assert user.email == "hello@test.email"
+
+
+def test_db_serialize_update_mutation(factories, mutations_registry, mocker):
+    user = factories["users.User"](email="hello@test.email", with_actor=True)
+
+    class S(mutations.UpdateMutationSerializer):
+        serialized_relations = {"actor": "full_username"}
+
+        class Meta:
+            model = user.__class__
+            fields = ["actor"]
+
+    expected = {"actor": user.actor.full_username}
+    assert S().db_serialize({"actor": user.actor}) == expected
+
+
+def test_is_valid_mutation(factories, mutations_registry):
+    user = factories["users.User"].build()
+
+    @mutations_registry.connect("update", user.__class__)
+    class S(mutations.UpdateMutationSerializer):
+        class Meta:
+            model = user.__class__
+            fields = ["email"]
+
+    with pytest.raises(serializers.ValidationError):
+        mutations_registry.is_valid("update", user, payload={"email": "foo"})
+    mutations_registry.is_valid("update", user, payload={"email": "foo@bar.com"})
+
+
+@pytest.mark.parametrize("perm", ["approve", "suggest"])
+def test_permissions(perm, factories, mutations_registry, mocker):
+    actor = factories["federation.Actor"].build()
+    user = factories["users.User"].build()
+
+    class S(mutations.UpdateMutationSerializer):
+        class Meta:
+            model = user.__class__
+            fields = ["email"]
+
+    mutations_registry.connect("update", user.__class__)(S)
+
+    assert mutations_registry.has_perm(perm, "update", obj=user, actor=actor) is False
+
+    checker = mocker.Mock(return_value=True)
+    mutations_registry.connect("update", user.__class__, perm_checkers={perm: checker})(
+        S
+    )
+
+    assert mutations_registry.has_perm(perm, "update", obj=user, actor=actor) is True
+    checker.assert_called_once_with(obj=user, actor=actor)
+
+
+def test_model_apply(factories, mocker, now):
+    target = factories["music.Artist"]()
+    mutation = factories["common.Mutation"](type="noop", target=target, payload="hello")
+
+    apply = mocker.patch.object(
+        mutations.registry, "apply", return_value={"previous": "state"}
+    )
+
+    mutation.apply()
+    apply.assert_called_once_with(type="noop", obj=target, payload="hello")
+    mutation.refresh_from_db()
+
+    assert mutation.is_applied is True
+    assert mutation.previous_state == {"previous": "state"}
+    assert mutation.applied_date == now
+
+
+def test_get_previous_state(factories):
+    obj = factories["music.Track"]()
+    expected = {
+        "title": {"value": obj.title},
+        "album": {"value": obj.album.pk, "repr": str(obj.album)},
+    }
+    assert (
+        mutations.get_update_previous_state(
+            obj, "title", "album", serialized_relations={"album": "pk"}
+        )
+        == expected
+    )
diff --git a/api/tests/common/test_pagination.py b/api/tests/common/test_pagination.py
new file mode 100644
index 0000000000000000000000000000000000000000..cacbe740c7ddae374ae502ca1ae1a2867edab27b
--- /dev/null
+++ b/api/tests/common/test_pagination.py
@@ -0,0 +1,29 @@
+import pytest
+
+from funkwhale_api.common import pagination
+
+
+@pytest.mark.parametrize(
+    "view_max_page_size, view_default_page_size, request_page_size, expected",
+    [
+        (50, 50, None, 50),
+        (50, 25, None, 25),
+        (25, None, None, 25),
+        (50, 25, 100, 50),
+        (50, None, 100, 50),
+        (50, 25, 33, 33),
+    ],
+)
+def test_funkwhale_pagination_uses_view_page_size(
+    view_max_page_size, view_default_page_size, request_page_size, expected, mocker
+):
+    p = pagination.FunkwhalePagination()
+
+    p.view = mocker.Mock(
+        max_page_size=view_max_page_size, default_page_size=view_default_page_size
+    )
+    query = {}
+    if request_page_size:
+        query["page_size"] = request_page_size
+    request = mocker.Mock(query_params=query)
+    assert p.get_page_size(request) == expected
diff --git a/api/tests/common/test_search.py b/api/tests/common/test_search.py
index e5be7bc900f0d215f27909603390dd115fbb68d8..8872298025658d27ec174470ffd193ca6f64c321 100644
--- a/api/tests/common/test_search.py
+++ b/api/tests/common/test_search.py
@@ -1,6 +1,7 @@
 import pytest
 
 from django.db.models import Q
+from django import forms
 
 from funkwhale_api.common import search
 from funkwhale_api.music import models as music_models
@@ -45,6 +46,24 @@ def test_search_config_query(query, expected):
     assert cleaned["search_query"] == expected
 
 
+def test_search_config_query_filter_field_handler():
+    s = search.SearchConfig(
+        filter_fields={"account": {"handler": lambda v: Q(hello="world")}}
+    )
+
+    cleaned = s.clean("account:noop")
+    assert cleaned["filter_query"] == Q(hello="world")
+
+
+def test_search_config_query_filter_field():
+    s = search.SearchConfig(
+        filter_fields={"account": {"to": "noop", "field": forms.BooleanField()}}
+    )
+
+    cleaned = s.clean("account:true")
+    assert cleaned["filter_query"] == Q(noop=True)
+
+
 @pytest.mark.parametrize(
     "query,expected",
     [
diff --git a/api/tests/common/test_tasks.py b/api/tests/common/test_tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..f097c44231af27de220df3889cf7f1db2fe48ea0
--- /dev/null
+++ b/api/tests/common/test_tasks.py
@@ -0,0 +1,65 @@
+import pytest
+
+from funkwhale_api.common import serializers
+from funkwhale_api.common import signals
+from funkwhale_api.common import tasks
+
+
+def test_apply_migration(factories, mocker):
+    mutation = factories["common.Mutation"](payload={})
+    apply = mocker.patch.object(mutation.__class__, "apply")
+    tasks.apply_mutation(mutation_id=mutation.pk)
+
+    apply.assert_called_once_with()
+
+
+def test_broadcast_mutation_created(factories, mocker):
+    mutation = factories["common.Mutation"](payload={})
+    factories["common.Mutation"](payload={}, is_approved=True)
+    group_send = mocker.patch("funkwhale_api.common.channels.group_send")
+    expected = serializers.APIMutationSerializer(mutation).data
+
+    signals.mutation_created.send(sender=None, mutation=mutation)
+    group_send.assert_called_with(
+        "instance_activity",
+        {
+            "type": "event.send",
+            "text": "",
+            "data": {
+                "type": "mutation.created",
+                "mutation": expected,
+                "pending_review_count": 1,
+            },
+        },
+    )
+
+
+def test_broadcast_mutation_updated(factories, mocker):
+    mutation = factories["common.Mutation"](payload={}, is_approved=True)
+    factories["common.Mutation"](payload={})
+    group_send = mocker.patch("funkwhale_api.common.channels.group_send")
+    expected = serializers.APIMutationSerializer(mutation).data
+
+    signals.mutation_updated.send(
+        sender=None, mutation=mutation, old_is_approved=False, new_is_approved=True
+    )
+    group_send.assert_called_with(
+        "instance_activity",
+        {
+            "type": "event.send",
+            "text": "",
+            "data": {
+                "type": "mutation.updated",
+                "mutation": expected,
+                "old_is_approved": False,
+                "new_is_approved": True,
+                "pending_review_count": 1,
+            },
+        },
+    )
+
+
+def test_cannot_apply_already_applied_migration(factories):
+    mutation = factories["common.Mutation"](payload={}, is_applied=True)
+    with pytest.raises(mutation.__class__.DoesNotExist):
+        tasks.apply_mutation(mutation_id=mutation.pk)
diff --git a/api/tests/common/test_utils.py b/api/tests/common/test_utils.py
index c5c4a8e239b9e24f1699b3d29b36e2d0b720e0f8..ea64ed9d2834f8d97aee7425fb223548ffab1b52 100644
--- a/api/tests/common/test_utils.py
+++ b/api/tests/common/test_utils.py
@@ -1,3 +1,5 @@
+import pytest
+
 from funkwhale_api.common import utils
 
 
@@ -42,3 +44,44 @@ def test_update_prefix(factories):
         old = n.fid
         n.refresh_from_db()
         assert n.fid == old.replace("http://", "https://")
+
+
+@pytest.mark.parametrize(
+    "conf, mock_args, data, expected",
+    [
+        (
+            ["field1", "field2"],
+            {"field1": "foo", "field2": "test"},
+            {"field1": "bar"},
+            {"field1": "bar"},
+        ),
+        (
+            ["field1", "field2"],
+            {"field1": "foo", "field2": "test"},
+            {"field1": "foo"},
+            {},
+        ),
+        (
+            ["field1", "field2"],
+            {"field1": "foo", "field2": "test"},
+            {"field1": "foo", "field2": "test"},
+            {},
+        ),
+        (
+            ["field1", "field2"],
+            {"field1": "foo", "field2": "test"},
+            {"field1": "bar", "field2": "test1"},
+            {"field1": "bar", "field2": "test1"},
+        ),
+        (
+            [("field1", "Hello"), ("field2", "World")],
+            {"Hello": "foo", "World": "test"},
+            {"field1": "bar", "field2": "test1"},
+            {"Hello": "bar", "World": "test1"},
+        ),
+    ],
+)
+def test_get_updated_fields(conf, mock_args, data, expected, mocker):
+    obj = mocker.Mock(**mock_args)
+
+    assert utils.get_updated_fields(conf, data, obj) == expected
diff --git a/api/tests/common/test_views.py b/api/tests/common/test_views.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2b53b41f620ac80caa5d5835ef3afdb02c1bd60
--- /dev/null
+++ b/api/tests/common/test_views.py
@@ -0,0 +1,165 @@
+import pytest
+from django.urls import reverse
+
+from funkwhale_api.common import serializers
+from funkwhale_api.common import signals
+from funkwhale_api.common import tasks
+
+
+def test_can_detail_mutation(logged_in_api_client, factories):
+    mutation = factories["common.Mutation"](
+        payload={}, target=factories["music.Artist"]()
+    )
+    url = reverse("api:v1:mutations-detail", kwargs={"uuid": mutation.uuid})
+
+    response = logged_in_api_client.get(url)
+
+    expected = serializers.APIMutationSerializer(mutation).data
+
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+def test_can_list_mutations(logged_in_api_client, factories):
+    mutation = factories["common.Mutation"](
+        payload={}, target=factories["music.Artist"]()
+    )
+    url = reverse("api:v1:mutations-list")
+
+    response = logged_in_api_client.get(url)
+
+    expected = serializers.APIMutationSerializer(mutation).data
+
+    assert response.status_code == 200
+    assert response.data["results"] == [expected]
+
+
+def test_can_destroy_mutation_creator(logged_in_api_client, factories):
+    actor = logged_in_api_client.user.create_actor()
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](
+        target=track, type="update", payload={}, created_by=actor
+    )
+    url = reverse("api:v1:mutations-detail", kwargs={"uuid": mutation.uuid})
+
+    response = logged_in_api_client.delete(url)
+
+    assert response.status_code == 204
+
+
+def test_can_destroy_mutation_not_creator(logged_in_api_client, factories):
+    logged_in_api_client.user.create_actor()
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](type="update", target=track, payload={})
+    url = reverse("api:v1:mutations-detail", kwargs={"uuid": mutation.uuid})
+
+    response = logged_in_api_client.delete(url)
+
+    assert response.status_code == 403
+
+    mutation.refresh_from_db()
+
+
+def test_can_destroy_mutation_has_perm(logged_in_api_client, factories, mocker):
+    actor = logged_in_api_client.user.create_actor()
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](target=track, type="update", payload={})
+    has_perm = mocker.patch(
+        "funkwhale_api.common.mutations.registry.has_perm", return_value=True
+    )
+    url = reverse("api:v1:mutations-detail", kwargs={"uuid": mutation.uuid})
+
+    response = logged_in_api_client.delete(url)
+
+    assert response.status_code == 204
+    has_perm.assert_called_once_with(
+        obj=mutation.target, type=mutation.type, perm="approve", actor=actor
+    )
+
+
+@pytest.mark.parametrize("endpoint, expected", [("approve", True), ("reject", False)])
+def test_can_approve_reject_mutation_with_perm(
+    endpoint, expected, logged_in_api_client, factories, mocker
+):
+    on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
+    actor = logged_in_api_client.user.create_actor()
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](target=track, type="update", payload={})
+    has_perm = mocker.patch(
+        "funkwhale_api.common.mutations.registry.has_perm", return_value=True
+    )
+    url = reverse(
+        "api:v1:mutations-{}".format(endpoint), kwargs={"uuid": mutation.uuid}
+    )
+
+    response = logged_in_api_client.post(url)
+
+    assert response.status_code == 200
+    has_perm.assert_called_once_with(
+        obj=mutation.target, type=mutation.type, perm="approve", actor=actor
+    )
+
+    if expected:
+        on_commit.assert_any_call(tasks.apply_mutation.delay, mutation_id=mutation.id)
+    mutation.refresh_from_db()
+
+    assert mutation.is_approved == expected
+    assert mutation.approved_by == actor
+
+    on_commit.assert_any_call(
+        signals.mutation_updated.send,
+        mutation=mutation,
+        sender=None,
+        new_is_approved=expected,
+        old_is_approved=None,
+    )
+
+
+@pytest.mark.parametrize("endpoint, expected", [("approve", True), ("reject", False)])
+def test_cannot_approve_reject_applied_mutation(
+    endpoint, expected, logged_in_api_client, factories, mocker
+):
+    on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
+    logged_in_api_client.user.create_actor()
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](
+        target=track, type="update", payload={}, is_applied=True
+    )
+    mocker.patch("funkwhale_api.common.mutations.registry.has_perm", return_value=True)
+    url = reverse(
+        "api:v1:mutations-{}".format(endpoint), kwargs={"uuid": mutation.uuid}
+    )
+
+    response = logged_in_api_client.post(url)
+
+    assert response.status_code == 403
+    on_commit.assert_not_called()
+
+    mutation.refresh_from_db()
+
+    assert mutation.is_approved is None
+    assert mutation.approved_by is None
+
+
+@pytest.mark.parametrize("endpoint, expected", [("approve", True), ("reject", False)])
+def test_cannot_approve_reject_without_perm(
+    endpoint, expected, logged_in_api_client, factories, mocker
+):
+    on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
+    logged_in_api_client.user.create_actor()
+    track = factories["music.Track"]()
+    mutation = factories["common.Mutation"](target=track, type="update", payload={})
+    mocker.patch("funkwhale_api.common.mutations.registry.has_perm", return_value=False)
+    url = reverse(
+        "api:v1:mutations-{}".format(endpoint), kwargs={"uuid": mutation.uuid}
+    )
+
+    response = logged_in_api_client.post(url)
+
+    assert response.status_code == 403
+    on_commit.assert_not_called()
+
+    mutation.refresh_from_db()
+
+    assert mutation.is_approved is None
+    assert mutation.approved_by is None
diff --git a/api/tests/conftest.py b/api/tests/conftest.py
index 03dbdfa4e53caf36cf40e37c639378ab4517516e..a1baedcc66b47b8518d89a12f11706f69306b03b 100644
--- a/api/tests/conftest.py
+++ b/api/tests/conftest.py
@@ -22,12 +22,16 @@ from django.db import connection
 from django.db.migrations.executor import MigrationExecutor
 from django.db.models import QuerySet
 
+from aioresponses import aioresponses
 from dynamic_preferences.registries import global_preferences_registry
 from rest_framework import fields as rest_fields
 from rest_framework.test import APIClient, APIRequestFactory
 
 from funkwhale_api.activity import record
-from funkwhale_api.users.permissions import HasUserPermission
+from funkwhale_api.federation import actors
+
+
+pytest_plugins = "aiohttp.pytest_plugin"
 
 
 class FunkwhaleProvider(internet_provider.Provider):
@@ -312,16 +316,6 @@ def authenticated_actor(factories, mocker):
     yield actor
 
 
-@pytest.fixture
-def assert_user_permission():
-    def inner(view, permissions, operator="and"):
-        assert HasUserPermission in view.permission_classes
-        assert getattr(view, "permission_operator", "and") == operator
-        assert set(view.required_permissions) == set(permissions)
-
-    return inner
-
-
 @pytest.fixture
 def to_api_date():
     def inner(value):
@@ -396,6 +390,7 @@ def stdout():
 
 @pytest.fixture
 def spa_html(r_mock, settings):
+    settings.FUNKWHALE_SPA_HTML_ROOT = "http://noop/"
     yield r_mock.get(
         settings.FUNKWHALE_SPA_HTML_ROOT + "index.html", text="<head></head>"
     )
@@ -416,3 +411,14 @@ def migrator(transactional_db):
 def rsa_small_key(settings):
     # smaller size for faster generation, since it's CPU hungry
     settings.RSA_KEY_SIZE = 512
+
+
+@pytest.fixture(autouse=True)
+def a_responses():
+    with aioresponses() as m:
+        yield m
+
+
+@pytest.fixture
+def service_actor(db):
+    return actors.get_service_actor()
diff --git a/api/tests/favorites/test_favorites.py b/api/tests/favorites/test_favorites.py
index 7e8d1d3fdd14f5e082329873bfe25a6c7c550bfc..190c7918439f4acd73dce5b4e9d599ad3d979673 100644
--- a/api/tests/favorites/test_favorites.py
+++ b/api/tests/favorites/test_favorites.py
@@ -17,12 +17,14 @@ def test_user_can_add_favorite(factories):
     assert f.user == user
 
 
-def test_user_can_get_his_favorites(api_request, factories, logged_in_client, client):
+def test_user_can_get_his_favorites(
+    api_request, factories, logged_in_api_client, client
+):
     r = api_request.get("/")
-    favorite = factories["favorites.TrackFavorite"](user=logged_in_client.user)
+    favorite = factories["favorites.TrackFavorite"](user=logged_in_api_client.user)
     factories["favorites.TrackFavorite"]()
     url = reverse("api:v1:favorites:tracks-list")
-    response = logged_in_client.get(url, {"user": logged_in_client.user.pk})
+    response = logged_in_api_client.get(url, {"user": logged_in_api_client.user.pk})
     expected = [
         {
             "user": users_serializers.UserBasicSerializer(
@@ -40,21 +42,21 @@ def test_user_can_get_his_favorites(api_request, factories, logged_in_client, cl
 
 
 def test_user_can_retrieve_all_favorites_at_once(
-    api_request, factories, logged_in_client, client
+    api_request, factories, logged_in_api_client, client
 ):
-    favorite = factories["favorites.TrackFavorite"](user=logged_in_client.user)
+    favorite = factories["favorites.TrackFavorite"](user=logged_in_api_client.user)
     factories["favorites.TrackFavorite"]()
     url = reverse("api:v1:favorites:tracks-all")
-    response = logged_in_client.get(url, {"user": logged_in_client.user.pk})
+    response = logged_in_api_client.get(url, {"user": logged_in_api_client.user.pk})
     expected = [{"track": favorite.track.id, "id": favorite.id}]
     assert response.status_code == 200
     assert response.data["results"] == expected
 
 
-def test_user_can_add_favorite_via_api(factories, logged_in_client, activity_muted):
+def test_user_can_add_favorite_via_api(factories, logged_in_api_client, activity_muted):
     track = factories["music.Track"]()
     url = reverse("api:v1:favorites:tracks-list")
-    response = logged_in_client.post(url, {"track": track.pk})
+    response = logged_in_api_client.post(url, {"track": track.pk})
 
     favorite = TrackFavorite.objects.latest("id")
     expected = {
@@ -66,15 +68,15 @@ def test_user_can_add_favorite_via_api(factories, logged_in_client, activity_mut
 
     assert expected == parsed_json
     assert favorite.track == track
-    assert favorite.user == logged_in_client.user
+    assert favorite.user == logged_in_api_client.user
 
 
 def test_adding_favorites_calls_activity_record(
-    factories, logged_in_client, activity_muted
+    factories, logged_in_api_client, activity_muted
 ):
     track = factories["music.Track"]()
     url = reverse("api:v1:favorites:tracks-list")
-    response = logged_in_client.post(url, {"track": track.pk})
+    response = logged_in_api_client.post(url, {"track": track.pk})
 
     favorite = TrackFavorite.objects.latest("id")
     expected = {
@@ -86,27 +88,27 @@ def test_adding_favorites_calls_activity_record(
 
     assert expected == parsed_json
     assert favorite.track == track
-    assert favorite.user == logged_in_client.user
+    assert favorite.user == logged_in_api_client.user
 
     activity_muted.assert_called_once_with(favorite)
 
 
-def test_user_can_remove_favorite_via_api(logged_in_client, factories, client):
-    favorite = factories["favorites.TrackFavorite"](user=logged_in_client.user)
+def test_user_can_remove_favorite_via_api(logged_in_api_client, factories):
+    favorite = factories["favorites.TrackFavorite"](user=logged_in_api_client.user)
     url = reverse("api:v1:favorites:tracks-detail", kwargs={"pk": favorite.pk})
-    response = client.delete(url, {"track": favorite.track.pk})
+    response = logged_in_api_client.delete(url, {"track": favorite.track.pk})
     assert response.status_code == 204
     assert TrackFavorite.objects.count() == 0
 
 
 @pytest.mark.parametrize("method", ["delete", "post"])
 def test_user_can_remove_favorite_via_api_using_track_id(
-    method, factories, logged_in_client
+    method, factories, logged_in_api_client
 ):
-    favorite = factories["favorites.TrackFavorite"](user=logged_in_client.user)
+    favorite = factories["favorites.TrackFavorite"](user=logged_in_api_client.user)
 
     url = reverse("api:v1:favorites:tracks-remove")
-    response = getattr(logged_in_client, method)(
+    response = getattr(logged_in_api_client, method)(
         url, json.dumps({"track": favorite.track.pk}), content_type="application/json"
     )
 
@@ -122,11 +124,11 @@ def test_url_require_auth(url, method, db, preferences, client):
     assert response.status_code == 401
 
 
-def test_can_filter_tracks_by_favorites(factories, logged_in_client):
-    favorite = factories["favorites.TrackFavorite"](user=logged_in_client.user)
+def test_can_filter_tracks_by_favorites(factories, logged_in_api_client):
+    favorite = factories["favorites.TrackFavorite"](user=logged_in_api_client.user)
 
     url = reverse("api:v1:tracks-list")
-    response = logged_in_client.get(url, data={"favorites": True})
+    response = logged_in_api_client.get(url, data={"favorites": True})
 
     parsed_json = json.loads(response.content.decode("utf-8"))
     assert parsed_json["count"] == 1
diff --git a/api/tests/favorites/test_filters.py b/api/tests/favorites/test_filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..e5eaca39ebcf9c265cff93dbed9466c5e93b4ca5
--- /dev/null
+++ b/api/tests/favorites/test_filters.py
@@ -0,0 +1,30 @@
+from funkwhale_api.favorites import filters
+from funkwhale_api.favorites import models
+
+
+def test_track_favorite_filter_track_artist(factories, mocker, queryset_equal_list):
+    factories["favorites.TrackFavorite"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_fav = factories["favorites.TrackFavorite"](track__artist=cf.target_artist)
+    qs = models.TrackFavorite.objects.all()
+    filterset = filters.TrackFavoriteFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_fav]
+
+
+def test_track_favorite_filter_track_album_artist(
+    factories, mocker, queryset_equal_list
+):
+    factories["favorites.TrackFavorite"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_fav = factories["favorites.TrackFavorite"](
+        track__album__artist=cf.target_artist
+    )
+    qs = models.TrackFavorite.objects.all()
+    filterset = filters.TrackFavoriteFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_fav]
diff --git a/api/tests/federation/test_activity.py b/api/tests/federation/test_activity.py
index a1eedeb4930b400a7d2ab03ddc8848225290a484..aaeebbb87c594084bc404df077fb83b2e4a5bc2f 100644
--- a/api/tests/federation/test_activity.py
+++ b/api/tests/federation/test_activity.py
@@ -14,6 +14,9 @@ from funkwhale_api.federation import (
 
 
 def test_receive_validates_basic_attributes_and_stores_activity(factories, now, mocker):
+    mocker.patch.object(
+        activity.InboxRouter, "get_matching_handlers", return_value=True
+    )
     mocked_dispatch = mocker.patch("funkwhale_api.common.utils.on_commit")
     local_to_actor = factories["users.User"]().create_actor()
     local_cc_actor = factories["users.User"]().create_actor()
@@ -48,6 +51,9 @@ def test_receive_validates_basic_attributes_and_stores_activity(factories, now,
 
 def test_receive_calls_should_reject(factories, now, mocker):
     should_reject = mocker.patch.object(activity, "should_reject", return_value=True)
+    mocker.patch.object(
+        activity.InboxRouter, "get_matching_handlers", return_value=True
+    )
     local_to_actor = factories["users.User"]().create_actor()
     remote_actor = factories["federation.Actor"]()
     a = {
@@ -60,30 +66,61 @@ def test_receive_calls_should_reject(factories, now, mocker):
 
     copy = activity.receive(activity=a, on_behalf_of=remote_actor)
     should_reject.assert_called_once_with(
-        id=a["id"], actor_id=remote_actor.fid, payload=a
+        fid=a["id"], actor_id=remote_actor.fid, payload=a
     )
     assert copy is None
 
 
+def test_receive_skips_if_no_matching_route(factories, now, mocker):
+    get_matching_handlers = mocker.patch.object(
+        activity.InboxRouter, "get_matching_handlers", return_value=[]
+    )
+    local_to_actor = factories["users.User"]().create_actor()
+    remote_actor = factories["federation.Actor"]()
+    a = {
+        "@context": [],
+        "actor": remote_actor.fid,
+        "type": "Noop",
+        "id": "https://test.activity",
+        "to": [local_to_actor.fid, remote_actor.fid],
+    }
+
+    copy = activity.receive(activity=a, on_behalf_of=remote_actor)
+    get_matching_handlers.assert_called_once_with(a)
+    assert copy is None
+    assert models.Activity.objects.count() == 0
+
+
+def test_match_route_ignore_payload_issues():
+    payload = {"object": "http://hello"}
+    assert activity.match_route({"object.type": "Test"}, payload) is False
+
+
 @pytest.mark.parametrize(
     "params, policy_kwargs, expected",
     [
-        ({"id": "https://ok.test"}, {"target_domain__name": "notok.test"}, False),
+        ({"fid": "https://ok.test"}, {"target_domain__name": "notok.test"}, False),
         (
-            {"id": "https://ok.test"},
+            {"fid": "https://ok.test"},
             {"target_domain__name": "ok.test", "is_active": False},
             False,
         ),
         (
-            {"id": "https://ok.test"},
+            {"fid": "https://ok.test"},
             {"target_domain__name": "ok.test", "block_all": False},
             False,
         ),
         # id match blocked domain
-        ({"id": "http://notok.test"}, {"target_domain__name": "notok.test"}, True),
+        ({"fid": "http://notok.test"}, {"target_domain__name": "notok.test"}, True),
+        # actor id match blocked domain
+        (
+            {"fid": "http://ok.test", "actor_id": "https://notok.test"},
+            {"target_domain__name": "notok.test"},
+            True,
+        ),
         # actor id match blocked domain
         (
-            {"id": "http://ok.test", "actor_id": "https://notok.test"},
+            {"fid": None, "actor_id": "https://notok.test"},
             {"target_domain__name": "notok.test"},
             True,
         ),
@@ -91,7 +128,7 @@ def test_receive_calls_should_reject(factories, now, mocker):
         (
             {
                 "payload": {"type": "Library"},
-                "id": "http://ok.test",
+                "fid": "http://ok.test",
                 "actor_id": "http://notok.test",
             },
             {
@@ -399,6 +436,53 @@ def test_prepare_deliveries_and_inbox_items(factories):
         assert inbox_item.type == "to"
 
 
+def test_prepare_deliveries_and_inbox_items_instances_with_followers(factories):
+
+    domain1 = factories["federation.Domain"](with_service_actor=True)
+    domain2 = factories["federation.Domain"](with_service_actor=True)
+    library = factories["music.Library"](actor__local=True)
+
+    factories["federation.LibraryFollow"](
+        target=library, actor__local=True, approved=True
+    ).actor
+    library_follower_remote = factories["federation.LibraryFollow"](
+        target=library, actor__domain=domain1, approved=True
+    ).actor
+
+    followed_actor = factories["federation.Actor"](local=True)
+    factories["federation.Follow"](
+        target=followed_actor, actor__local=True, approved=True
+    ).actor
+    actor_follower_remote = factories["federation.Follow"](
+        target=followed_actor, actor__domain=domain2, approved=True
+    ).actor
+
+    recipients = [activity.PUBLIC_ADDRESS, {"type": "instances_with_followers"}]
+
+    inbox_items, deliveries, urls = activity.prepare_deliveries_and_inbox_items(
+        recipients, "to"
+    )
+
+    expected_deliveries = sorted(
+        [
+            models.Delivery(
+                inbox_url=library_follower_remote.domain.service_actor.inbox_url
+            ),
+            models.Delivery(
+                inbox_url=actor_follower_remote.domain.service_actor.inbox_url
+            ),
+        ],
+        key=lambda v: v.inbox_url,
+    )
+    assert inbox_items == []
+    assert len(expected_deliveries) == len(deliveries)
+
+    for delivery, expected_delivery in zip(
+        sorted(deliveries, key=lambda v: v.inbox_url), expected_deliveries
+    ):
+        assert delivery.inbox_url == expected_delivery.inbox_url
+
+
 def test_should_rotate_actor_key(settings, cache, now):
     actor_id = 42
     settings.ACTOR_KEY_ROTATION_DELAY = 10
diff --git a/api/tests/federation/test_actors.py b/api/tests/federation/test_actors.py
index a416cd78f3289e5f48acb3466eb3145777d34467..6e5cf93225ad7de0bd55ccb11395c4d9f910065f 100644
--- a/api/tests/federation/test_actors.py
+++ b/api/tests/federation/test_actors.py
@@ -14,7 +14,10 @@ def test_actor_fetching(r_mock):
     assert r == payload
 
 
-def test_get_actor(factories, r_mock):
+def test_get_actor(factories, r_mock, mocker):
+    update_domain_nodeinfo = mocker.patch(
+        "funkwhale_api.federation.tasks.update_domain_nodeinfo"
+    )
     actor = factories["federation.Actor"].build()
     payload = serializers.ActorSerializer(actor).data
     r_mock.get(actor.fid, json=payload)
@@ -22,6 +25,7 @@ def test_get_actor(factories, r_mock):
 
     assert new_actor.pk is not None
     assert serializers.ActorSerializer(new_actor).data == payload
+    update_domain_nodeinfo.assert_called_once_with(domain_name=new_actor.domain_id)
 
 
 def test_get_actor_use_existing(factories, preferences, mocker):
@@ -46,3 +50,15 @@ def test_get_actor_refresh(factories, preferences, mocker):
     assert new_actor == actor
     assert new_actor.last_fetch_date > actor.last_fetch_date
     assert new_actor.preferred_username == "New me"
+
+
+def test_get_service_actor(db, settings):
+    settings.FEDERATION_HOSTNAME = "test.hello"
+    settings.FEDERATION_SERVICE_ACTOR_USERNAME = "bob"
+    actor = actors.get_service_actor()
+
+    assert actor.preferred_username == "bob"
+    assert actor.domain.name == "test.hello"
+    assert actor.private_key is not None
+    assert actor.type == "Service"
+    assert actor.public_key is not None
diff --git a/api/tests/federation/test_api_filters.py b/api/tests/federation/test_api_filters.py
index c6e70b6178cd35bf8ad3752f0c8aa1204de20e7f..4cbf4293a3c3a82bda4fb42d3936dc8b41ea0e8c 100644
--- a/api/tests/federation/test_api_filters.py
+++ b/api/tests/federation/test_api_filters.py
@@ -1,3 +1,4 @@
+from funkwhale_api.federation import fields
 from funkwhale_api.federation import filters
 from funkwhale_api.federation import models
 
@@ -7,3 +8,17 @@ def test_inbox_item_filter_before(factories):
     f = filters.InboxItemFilter({"before": 12}, queryset=models.InboxItem.objects.all())
 
     assert str(f.qs.query) == str(expected.query)
+
+
+def test_domain_from_url_filter(factories):
+    found = [
+        factories["music.Artist"](fid="http://domain/test1"),
+        factories["music.Artist"](fid="https://domain/test2"),
+    ]
+    factories["music.Artist"](fid="http://domain2/test1")
+    factories["music.Artist"](fid="https://otherdomain/test2")
+
+    queryset = found[0].__class__.objects.all().order_by("id")
+    field = fields.DomainFromURLFilter()
+    result = field.filter(queryset, "domain")
+    assert list(result) == found
diff --git a/api/tests/federation/test_api_views.py b/api/tests/federation/test_api_views.py
index 75579d39a2d11d4ac2a1c4207ab30efdb477d470..c34c5e99aa1ec74ee2bbdd32bb33142297f54ff9 100644
--- a/api/tests/federation/test_api_views.py
+++ b/api/tests/federation/test_api_views.py
@@ -167,3 +167,15 @@ def test_user_can_update_read_status_of_inbox_item(factories, logged_in_api_clie
     ii.refresh_from_db()
 
     assert ii.is_read is True
+
+
+def test_can_detail_fetch(logged_in_api_client, factories):
+    fetch = factories["federation.Fetch"](url="http://test.object")
+    url = reverse("api:v1:federation:fetches-detail", kwargs={"pk": fetch.pk})
+
+    response = logged_in_api_client.get(url)
+
+    expected = api_serializers.FetchSerializer(fetch).data
+
+    assert response.status_code == 200
+    assert response.data == expected
diff --git a/api/tests/federation/test_authentication.py b/api/tests/federation/test_authentication.py
index 7af7089f66c19bcadbb77a98e3c4eac253cf4382..4e837e64177be9919881d0b5fe6adef94bbdaf6f 100644
--- a/api/tests/federation/test_authentication.py
+++ b/api/tests/federation/test_authentication.py
@@ -1,14 +1,16 @@
 import pytest
 
-from funkwhale_api.federation import authentication, exceptions, keys
+from funkwhale_api.federation import authentication, exceptions, keys, jsonld
 
 
 def test_authenticate(factories, mocker, api_request):
     private, public = keys.get_key_pair()
+    factories["federation.Domain"](name="test.federation", nodeinfo_fetch_date=None)
     actor_url = "https://test.federation/actor"
     mocker.patch(
         "funkwhale_api.federation.actors.get_actor_data",
         return_value={
+            "@context": jsonld.get_default_context(),
             "id": actor_url,
             "type": "Person",
             "outbox": "https://test.com",
@@ -22,6 +24,10 @@ def test_authenticate(factories, mocker, api_request):
             },
         },
     )
+    update_domain_nodeinfo = mocker.patch(
+        "funkwhale_api.federation.tasks.update_domain_nodeinfo"
+    )
+
     signed_request = factories["federation.SignedRequest"](
         auth__key=private, auth__key_id=actor_url + "#main-key", auth__headers=["date"]
     )
@@ -40,6 +46,7 @@ def test_authenticate(factories, mocker, api_request):
     assert user.is_anonymous is True
     assert actor.public_key == public.decode("utf-8")
     assert actor.fid == actor_url
+    update_domain_nodeinfo.assert_called_once_with(domain_name="test.federation")
 
 
 def test_authenticate_skips_blocked_domain(factories, api_request):
@@ -99,6 +106,7 @@ def test_authenticate_ignore_inactive_policy(factories, api_request, mocker):
     mocker.patch(
         "funkwhale_api.federation.actors.get_actor_data",
         return_value={
+            "@context": jsonld.get_default_context(),
             "id": actor_url,
             "type": "Person",
             "outbox": "https://test.com",
@@ -136,6 +144,7 @@ def test_autenthicate_supports_blind_key_rotation(factories, mocker, api_request
     mocker.patch(
         "funkwhale_api.federation.actors.get_actor_data",
         return_value={
+            "@context": jsonld.get_default_context(),
             "id": actor_url,
             "type": "Person",
             "outbox": "https://test.com",
diff --git a/api/tests/federation/test_contexts.py b/api/tests/federation/test_contexts.py
new file mode 100644
index 0000000000000000000000000000000000000000..a0134d909527a7eef987ae7daf7b2b9fbe3f4133
--- /dev/null
+++ b/api/tests/federation/test_contexts.py
@@ -0,0 +1,32 @@
+import pytest
+
+from funkwhale_api.federation import contexts
+
+
+@pytest.mark.parametrize(
+    "ns, property, expected",
+    [
+        ("AS", "followers", "https://www.w3.org/ns/activitystreams#followers"),
+        ("AS", "following", "https://www.w3.org/ns/activitystreams#following"),
+        ("SEC", "owner", "https://w3id.org/security#owner"),
+        ("SEC", "publicKey", "https://w3id.org/security#publicKey"),
+    ],
+)
+def test_context_ns(ns, property, expected):
+    ns = getattr(contexts, ns)
+    id = getattr(ns, property)
+    assert id == expected
+
+
+def test_raise_on_wrong_attr():
+    ns = contexts.AS
+    with pytest.raises(AttributeError):
+        ns.noop
+
+
+@pytest.mark.parametrize(
+    "property, expected",
+    [("publicKey", "_:publicKey"), ("cover", "_:cover"), ("hello", "_:hello")],
+)
+def test_noop_context(property, expected):
+    assert getattr(contexts.NOOP, property) == expected
diff --git a/api/tests/federation/test_decorators.py b/api/tests/federation/test_decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa50f5674a699378cb879e2764759e063bd29823
--- /dev/null
+++ b/api/tests/federation/test_decorators.py
@@ -0,0 +1,83 @@
+from rest_framework import viewsets
+
+from funkwhale_api.music import models as music_models
+
+from funkwhale_api.federation import api_serializers
+from funkwhale_api.federation import decorators
+from funkwhale_api.federation import models
+from funkwhale_api.federation import tasks
+
+
+class V(viewsets.ModelViewSet):
+    queryset = music_models.Track.objects.all()
+    fetches = decorators.fetches_route()
+    permission_classes = []
+
+
+def test_fetches_route_create(factories, api_request, mocker):
+    on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
+    user = factories["users.User"]()
+    actor = user.create_actor()
+    track = factories["music.Track"]()
+    view = V.as_view({"post": "fetches"})
+
+    request = api_request.post("/", format="json")
+    setattr(request, "user", user)
+    setattr(request, "session", {})
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 201
+
+    fetch = models.Fetch.objects.get_for_object(track).latest("id")
+    on_commit.assert_called_once_with(tasks.fetch.delay, fetch_id=fetch.pk)
+
+    assert fetch.url == track.fid
+    assert fetch.object == track
+    assert fetch.status == "pending"
+    assert fetch.actor == actor
+
+    expected = api_serializers.FetchSerializer(fetch).data
+    assert response.data == expected
+
+
+def test_fetches_route_create_local(factories, api_request, mocker, settings):
+    user = factories["users.User"]()
+    user.create_actor()
+    track = factories["music.Track"](
+        fid="https://{}/test".format(settings.FEDERATION_HOSTNAME)
+    )
+    view = V.as_view({"post": "fetches"})
+
+    request = api_request.post("/", format="json")
+    setattr(request, "user", user)
+    setattr(request, "session", {})
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 400
+
+
+def test_fetches_route_list(factories, api_request, mocker):
+    user = factories["users.User"]()
+    user.create_actor()
+    track = factories["music.Track"]()
+    fetches = [
+        factories["federation.Fetch"](object=track),
+        factories["federation.Fetch"](object=track),
+    ]
+    view = V.as_view({"get": "fetches"})
+
+    request = api_request.get("/", format="json")
+    setattr(request, "user", user)
+    setattr(request, "session", {})
+    expected = {
+        "next": None,
+        "previous": None,
+        "count": 2,
+        "results": api_serializers.FetchSerializer(reversed(fetches), many=True).data,
+    }
+
+    request = api_request.get("/")
+    response = view(request, pk=track.pk)
+
+    assert response.status_code == 200
+    assert response.data == expected
diff --git a/api/tests/federation/test_jsonld.py b/api/tests/federation/test_jsonld.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad201b7486e9c10e9d93f486c5f7876f52dd392d
--- /dev/null
+++ b/api/tests/federation/test_jsonld.py
@@ -0,0 +1,361 @@
+import pytest
+
+from rest_framework import serializers
+
+from funkwhale_api.federation import contexts
+from funkwhale_api.federation import jsonld
+
+
+def test_expand_no_external_request():
+    payload = {
+        "id": "https://noop/federation/actors/demo",
+        "outbox": "https://noop/federation/actors/demo/outbox",
+        "inbox": "https://noop/federation/actors/demo/inbox",
+        "preferredUsername": "demo",
+        "type": "Person",
+        "name": "demo",
+        "followers": "https://noop/federation/actors/demo/followers",
+        "following": "https://noop/federation/actors/demo/following",
+        "manuallyApprovesFollowers": False,
+        "@context": [
+            "https://www.w3.org/ns/activitystreams",
+            "https://w3id.org/security/v1",
+            {},
+        ],
+        "publicKey": {
+            "owner": "https://noop/federation/actors/demo",
+            "publicKeyPem": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxPDd/oXx0ClJ2BuBZ937AiERjvoroEpNebg34Cdl6FYsb2Auib8b\nCQjdjLjK/1ag35lmqmsECqtoDYWOo4tGilZJW47TWmXfcvCMH2Sw9FqdOlzpV1RI\nm8kc0Lu1CC2xOTctqIwSH7kDDnS4+S5hSxRdMTeNQNoirncY1CXa9TmJR1lE2HWz\n+B05ewzMrSen3l3fJLQFoI2GVbbjj+tvILKBL1oG5MtYieYqjt2sqtqy/OpWUAC7\nlRERRzd4t5xPBKykWkBCAOh80pvPue5V4s+xUMr7ioKTcm6pq+pNBta5w0hUYIcT\nMefQOnNuR4J0meIqiDLcrglGAmM6AVFwYwIDAQAB\n-----END RSA PUBLIC KEY-----\n",  # noqa
+            "id": "https://noop/federation/actors/demo#main-key",
+        },
+        "endpoints": {"sharedInbox": "https://noop/federation/shared/inbox"},
+    }
+
+    expected = {
+        contexts.AS.endpoints: [
+            {contexts.AS.sharedInbox: [{"@id": "https://noop/federation/shared/inbox"}]}
+        ],
+        contexts.AS.followers: [
+            {"@id": "https://noop/federation/actors/demo/followers"}
+        ],
+        contexts.AS.following: [
+            {"@id": "https://noop/federation/actors/demo/following"}
+        ],
+        "@id": "https://noop/federation/actors/demo",
+        "http://www.w3.org/ns/ldp#inbox": [
+            {"@id": "https://noop/federation/actors/demo/inbox"}
+        ],
+        contexts.AS.manuallyApprovesFollowers: [{"@value": False}],
+        contexts.AS.name: [{"@value": "demo"}],
+        contexts.AS.outbox: [{"@id": "https://noop/federation/actors/demo/outbox"}],
+        contexts.AS.preferredUsername: [{"@value": "demo"}],
+        contexts.SEC.publicKey: [
+            {
+                "@id": "https://noop/federation/actors/demo#main-key",
+                contexts.SEC.owner: [{"@id": "https://noop/federation/actors/demo"}],
+                contexts.SEC.publicKeyPem: [
+                    {
+                        "@value": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxPDd/oXx0ClJ2BuBZ937AiERjvoroEpNebg34Cdl6FYsb2Auib8b\nCQjdjLjK/1ag35lmqmsECqtoDYWOo4tGilZJW47TWmXfcvCMH2Sw9FqdOlzpV1RI\nm8kc0Lu1CC2xOTctqIwSH7kDDnS4+S5hSxRdMTeNQNoirncY1CXa9TmJR1lE2HWz\n+B05ewzMrSen3l3fJLQFoI2GVbbjj+tvILKBL1oG5MtYieYqjt2sqtqy/OpWUAC7\nlRERRzd4t5xPBKykWkBCAOh80pvPue5V4s+xUMr7ioKTcm6pq+pNBta5w0hUYIcT\nMefQOnNuR4J0meIqiDLcrglGAmM6AVFwYwIDAQAB\n-----END RSA PUBLIC KEY-----\n"  # noqa
+                    }
+                ],
+            }
+        ],
+        "@type": [contexts.AS.Person],
+    }
+
+    doc = jsonld.expand(payload)
+
+    assert doc == expected
+
+
+def test_expand_remote_doc(r_mock):
+    url = "https://noop/federation/actors/demo"
+    payload = {
+        "id": url,
+        "outbox": "https://noop/federation/actors/demo/outbox",
+        "inbox": "https://noop/federation/actors/demo/inbox",
+        "preferredUsername": "demo",
+        "type": "Person",
+        "name": "demo",
+        "followers": "https://noop/federation/actors/demo/followers",
+        "following": "https://noop/federation/actors/demo/following",
+        "manuallyApprovesFollowers": False,
+        "@context": [
+            "https://www.w3.org/ns/activitystreams",
+            "https://w3id.org/security/v1",
+            {},
+        ],
+        "publicKey": {
+            "owner": "https://noop/federation/actors/demo",
+            "publicKeyPem": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxPDd/oXx0ClJ2BuBZ937AiERjvoroEpNebg34Cdl6FYsb2Auib8b\nCQjdjLjK/1ag35lmqmsECqtoDYWOo4tGilZJW47TWmXfcvCMH2Sw9FqdOlzpV1RI\nm8kc0Lu1CC2xOTctqIwSH7kDDnS4+S5hSxRdMTeNQNoirncY1CXa9TmJR1lE2HWz\n+B05ewzMrSen3l3fJLQFoI2GVbbjj+tvILKBL1oG5MtYieYqjt2sqtqy/OpWUAC7\nlRERRzd4t5xPBKykWkBCAOh80pvPue5V4s+xUMr7ioKTcm6pq+pNBta5w0hUYIcT\nMefQOnNuR4J0meIqiDLcrglGAmM6AVFwYwIDAQAB\n-----END RSA PUBLIC KEY-----\n",  # noqa
+            "id": "https://noop/federation/actors/demo#main-key",
+        },
+        "endpoints": {"sharedInbox": "https://noop/federation/shared/inbox"},
+    }
+    r_mock.get(url, json=payload)
+
+    expected = {
+        contexts.AS.endpoints: [
+            {contexts.AS.sharedInbox: [{"@id": "https://noop/federation/shared/inbox"}]}
+        ],
+        contexts.AS.followers: [
+            {"@id": "https://noop/federation/actors/demo/followers"}
+        ],
+        contexts.AS.following: [
+            {"@id": "https://noop/federation/actors/demo/following"}
+        ],
+        "@id": "https://noop/federation/actors/demo",
+        "http://www.w3.org/ns/ldp#inbox": [
+            {"@id": "https://noop/federation/actors/demo/inbox"}
+        ],
+        contexts.AS.manuallyApprovesFollowers: [{"@value": False}],
+        contexts.AS.name: [{"@value": "demo"}],
+        contexts.AS.outbox: [{"@id": "https://noop/federation/actors/demo/outbox"}],
+        contexts.AS.preferredUsername: [{"@value": "demo"}],
+        contexts.SEC.publicKey: [
+            {
+                "@id": "https://noop/federation/actors/demo#main-key",
+                contexts.SEC.owner: [{"@id": "https://noop/federation/actors/demo"}],
+                contexts.SEC.publicKeyPem: [
+                    {
+                        "@value": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxPDd/oXx0ClJ2BuBZ937AiERjvoroEpNebg34Cdl6FYsb2Auib8b\nCQjdjLjK/1ag35lmqmsECqtoDYWOo4tGilZJW47TWmXfcvCMH2Sw9FqdOlzpV1RI\nm8kc0Lu1CC2xOTctqIwSH7kDDnS4+S5hSxRdMTeNQNoirncY1CXa9TmJR1lE2HWz\n+B05ewzMrSen3l3fJLQFoI2GVbbjj+tvILKBL1oG5MtYieYqjt2sqtqy/OpWUAC7\nlRERRzd4t5xPBKykWkBCAOh80pvPue5V4s+xUMr7ioKTcm6pq+pNBta5w0hUYIcT\nMefQOnNuR4J0meIqiDLcrglGAmM6AVFwYwIDAQAB\n-----END RSA PUBLIC KEY-----\n"  # noqa
+                    }
+                ],
+            }
+        ],
+        "@type": [contexts.AS.Person],
+    }
+
+    doc = jsonld.expand(url)
+
+    assert doc == expected
+
+
+async def test_fetch_many(a_responses):
+    doc = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop/federation/actors/demo",
+        "type": "Person",
+        "followers": "https://noop/federation/actors/demo/followers",
+    }
+    followers_doc = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop/federation/actors/demo/followers",
+        "type": "Collection",
+    }
+
+    a_responses.get(doc["id"], payload=doc)
+    a_responses.get(followers_doc["id"], payload=followers_doc)
+    fetched = await jsonld.fetch_many(doc["id"], followers_doc["id"])
+    assert fetched == {followers_doc["id"]: followers_doc, doc["id"]: doc}
+
+
+def test_dereference():
+
+    followers_doc = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop/federation/actors/demo/followers",
+        "type": "Collection",
+    }
+
+    actor_doc = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop/federation/actors/demo",
+        "type": "Person",
+        "followers": "https://noop/federation/actors/demo/followers",
+    }
+
+    store = {followers_doc["id"]: followers_doc, actor_doc["id"]: actor_doc}
+
+    payload = {
+        "followers": {"@id": followers_doc["id"]},
+        "actor": [
+            {"@id": actor_doc["id"], "hello": "world"},
+            {"somethingElse": [{"@id": actor_doc["id"]}]},
+        ],
+    }
+    expected = {
+        "followers": followers_doc,
+        "actor": [actor_doc, {"somethingElse": [actor_doc]}],
+    }
+
+    assert jsonld.dereference(payload, store) == expected
+
+
+def test_prepare_for_serializer():
+    config = {
+        "followers": {
+            "property": contexts.AS.followers,
+            "keep": "first",
+            "attr": "@id",
+        },
+        "name": {"property": contexts.AS.name, "keep": "first", "attr": "@value"},
+        "keys": {"property": contexts.SEC.publicKey, "type": "raw"},
+    }
+
+    payload = {
+        "@id": "https://noop/federation/actors/demo",
+        "@type": [contexts.AS.Person],
+        contexts.AS.followers: [
+            {"@id": "https://noop/federation/actors/demo/followers"}
+        ],
+        contexts.AS.name: [{"@value": "demo"}],
+        contexts.SEC.publicKey: [
+            {"@id": "https://noop/federation/actors/demo#main-key1"},
+            {"@id": "https://noop/federation/actors/demo#main-key2"},
+        ],
+    }
+
+    expected = {
+        "id": "https://noop/federation/actors/demo",
+        "type": contexts.AS.Person,
+        "followers": "https://noop/federation/actors/demo/followers",
+        "name": "demo",
+        "keys": [
+            {"@id": "https://noop/federation/actors/demo#main-key1"},
+            {"@id": "https://noop/federation/actors/demo#main-key2"},
+        ],
+    }
+
+    assert jsonld.prepare_for_serializer(payload, config) == expected
+
+
+def test_prepare_for_serializer_fallback():
+    config = {
+        "name": {"property": contexts.AS.name, "keep": "first", "attr": "@value"},
+        "album": {"property": contexts.FW.Album, "keep": "first"},
+        "noop_album": {"property": contexts.NOOP.Album, "keep": "first"},
+    }
+    fallbacks = {"album": ["noop_album"]}
+
+    payload = {
+        "@id": "https://noop/federation/actors/demo",
+        "@type": [contexts.AS.Person],
+        contexts.AS.name: [{"@value": "demo"}],
+        contexts.NOOP.Album: [{"@id": "https://noop/federation/album/demo"}],
+    }
+
+    expected = {
+        "id": "https://noop/federation/actors/demo",
+        "type": contexts.AS.Person,
+        "name": "demo",
+        "album": {"@id": "https://noop/federation/album/demo"},
+        "noop_album": {"@id": "https://noop/federation/album/demo"},
+    }
+
+    assert (
+        jsonld.prepare_for_serializer(payload, config, fallbacks=fallbacks) == expected
+    )
+
+
+def test_jsonld_serializer_fallback():
+    class TestSerializer(jsonld.JsonLdSerializer):
+        id = serializers.URLField()
+        type = serializers.CharField()
+        name = serializers.CharField()
+        username = serializers.CharField()
+        total = serializers.IntegerField()
+
+        class Meta:
+            jsonld_fallbacks = {"total": ["total_fallback"]}
+            jsonld_mapping = {
+                "name": {
+                    "property": contexts.AS.name,
+                    "keep": "first",
+                    "attr": "@value",
+                },
+                "username": {
+                    "property": contexts.AS.preferredUsername,
+                    "keep": "first",
+                    "attr": "@value",
+                },
+                "total": {
+                    "property": contexts.AS.totalItems,
+                    "keep": "first",
+                    "attr": "@value",
+                },
+                "total_fallback": {
+                    "property": contexts.NOOP.count,
+                    "keep": "first",
+                    "attr": "@value",
+                },
+            }
+
+    payload = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop.url/federation/actors/demo",
+        "type": "Person",
+        "name": "Hello",
+        "preferredUsername": "World",
+        "count": 42,
+    }
+
+    serializer = TestSerializer(data=payload)
+    assert serializer.is_valid(raise_exception=True)
+
+    assert serializer.validated_data == {
+        "type": contexts.AS.Person,
+        "id": payload["id"],
+        "name": payload["name"],
+        "username": payload["preferredUsername"],
+        "total": 42,
+    }
+
+
+def test_jsonld_serializer_dereference(a_responses):
+    class TestSerializer(jsonld.JsonLdSerializer):
+        id = serializers.URLField()
+        type = serializers.CharField()
+        followers = serializers.JSONField()
+
+        class Meta:
+            jsonld_mapping = {
+                "followers": {"property": contexts.AS.followers, "dereference": True}
+            }
+
+    payload = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop.url/federation/actors/demo",
+        "type": "Person",
+        "followers": "https://noop.url/federation/actors/demo/followers",
+    }
+
+    followers_doc = {
+        "@context": ["https://www.w3.org/ns/activitystreams", {}],
+        "id": "https://noop.url/federation/actors/demo/followers",
+        "type": "Collection",
+    }
+
+    a_responses.get(followers_doc["id"], payload=followers_doc)
+    serializer = TestSerializer(data=payload)
+
+    assert serializer.is_valid(raise_exception=True)
+    assert serializer.validated_data == {
+        "type": contexts.AS.Person,
+        "id": payload["id"],
+        "followers": [followers_doc],
+    }
+
+
+@pytest.mark.parametrize(
+    "doc, ctx, expected",
+    [
+        (
+            {"@context": [{}], "hello": "world"},
+            "http://test",
+            {"@context": [{}, "http://test"], "hello": "world"},
+        ),
+        (
+            {"@context": {"key": "value"}, "hello": "world"},
+            "http://test",
+            {"@context": [{"key": "value"}, "http://test"], "hello": "world"},
+        ),
+        (
+            {"@context": "http://as", "hello": "world"},
+            "http://test",
+            {"@context": ["http://as", "http://test"], "hello": "world"},
+        ),
+    ],
+)
+def test_insert_context(doc, ctx, expected):
+    jsonld.insert_context(ctx, doc)
+    assert doc == expected
diff --git a/api/tests/federation/test_models.py b/api/tests/federation/test_models.py
index 6eeebd660ad12db40f7882ae753bd72acead92b2..d6f862bb356300e9d93fb02c0300f266eef0a6bf 100644
--- a/api/tests/federation/test_models.py
+++ b/api/tests/federation/test_models.py
@@ -134,3 +134,42 @@ def test_actor_stats(factories):
     actor = factories["federation.Actor"]()
 
     assert actor.get_stats() == expected
+
+
+def test_actor_can_manage_false(mocker, factories):
+    obj = mocker.Mock()
+    actor = factories["federation.Actor"]()
+
+    assert actor.can_manage(obj) is False
+
+
+def test_actor_can_manage_attributed_to(mocker, factories):
+    actor = factories["federation.Actor"]()
+    obj = mocker.Mock(attributed_to_id=actor.pk)
+
+    assert actor.can_manage(obj) is True
+
+
+def test_actor_can_manage_domain_not_service_actor(mocker, factories):
+    actor = factories["federation.Actor"]()
+    obj = mocker.Mock(fid="https://{}/hello".format(actor.domain_id))
+
+    assert actor.can_manage(obj) is False
+
+
+def test_actor_can_manage_domain_service_actor(mocker, factories):
+    actor = factories["federation.Actor"]()
+    actor.domain.service_actor = actor
+    actor.domain.save()
+    obj = mocker.Mock(fid="https://{}/hello".format(actor.domain_id))
+
+    assert actor.can_manage(obj) is True
+
+
+def test_can_create_fetch_for_object(factories):
+    track = factories["music.Track"](fid="http://test.domain")
+    fetch = factories["federation.Fetch"](object=track)
+    assert fetch.url == "http://test.domain"
+    assert fetch.status == "pending"
+    assert fetch.detail == {}
+    assert fetch.object == track
diff --git a/api/tests/federation/test_routes.py b/api/tests/federation/test_routes.py
index 7232b746cfa0768992ced9ca0bec818c58246bfa..56834d55f472a5ce9e3d49ee6e96486bf59bd673 100644
--- a/api/tests/federation/test_routes.py
+++ b/api/tests/federation/test_routes.py
@@ -1,6 +1,6 @@
 import pytest
 
-from funkwhale_api.federation import routes, serializers
+from funkwhale_api.federation import actors, contexts, jsonld, routes, serializers
 
 
 @pytest.mark.parametrize(
@@ -13,6 +13,9 @@ from funkwhale_api.federation import routes, serializers
         ({"type": "Delete", "object.type": "Library"}, routes.inbox_delete_library),
         ({"type": "Delete", "object.type": "Audio"}, routes.inbox_delete_audio),
         ({"type": "Undo", "object.type": "Follow"}, routes.inbox_undo_follow),
+        ({"type": "Update", "object.type": "Artist"}, routes.inbox_update_artist),
+        ({"type": "Update", "object.type": "Album"}, routes.inbox_update_album),
+        ({"type": "Update", "object.type": "Track"}, routes.inbox_update_track),
     ],
 )
 def test_inbox_routes(route, handler):
@@ -34,6 +37,7 @@ def test_inbox_routes(route, handler):
         ({"type": "Delete", "object.type": "Library"}, routes.outbox_delete_library),
         ({"type": "Delete", "object.type": "Audio"}, routes.outbox_delete_audio),
         ({"type": "Undo", "object.type": "Follow"}, routes.outbox_undo_follow),
+        ({"type": "Update", "object.type": "Track"}, routes.outbox_update_track),
     ],
 )
 def test_outbox_routes(route, handler):
@@ -113,6 +117,44 @@ def test_inbox_follow_library_manual_approve(factories, mocker):
     mocked_outbox_dispatch.assert_not_called()
 
 
+def test_inbox_follow_library_already_approved(factories, mocker):
+    """Cf #830, out of sync follows"""
+    mocked_outbox_dispatch = mocker.patch(
+        "funkwhale_api.federation.activity.OutboxRouter.dispatch"
+    )
+
+    local_actor = factories["users.User"]().create_actor()
+    remote_actor = factories["federation.Actor"]()
+    library = factories["music.Library"](actor=local_actor, privacy_level="me")
+    ii = factories["federation.InboxItem"](actor=local_actor)
+    existing_follow = factories["federation.LibraryFollow"](
+        target=library, actor=remote_actor, approved=True
+    )
+    payload = {
+        "type": "Follow",
+        "id": "https://test.follow",
+        "actor": remote_actor.fid,
+        "object": library.fid,
+    }
+
+    result = routes.inbox_follow(
+        payload,
+        context={"actor": remote_actor, "inbox_items": [ii], "raise_exception": True},
+    )
+    follow = library.received_follows.latest("id")
+
+    assert result["object"] == library
+    assert result["related_object"] == follow
+
+    assert follow.fid == payload["id"]
+    assert follow.actor == remote_actor
+    assert follow.approved is True
+    assert follow.uuid != existing_follow.uuid
+    mocked_outbox_dispatch.assert_called_once_with(
+        {"type": "Accept"}, context={"follow": follow}
+    )
+
+
 def test_outbox_accept(factories, mocker):
     remote_actor = factories["federation.Actor"]()
     follow = factories["federation.LibraryFollow"](actor=remote_actor)
@@ -190,6 +232,7 @@ def test_inbox_create_audio(factories, mocker):
     activity = factories["federation.Activity"]()
     upload = factories["music.Upload"](bitrate=42, duration=55)
     payload = {
+        "@context": jsonld.get_default_context(),
         "type": "Create",
         "actor": upload.library.actor.fid,
         "object": serializers.UploadSerializer(upload).data,
@@ -404,3 +447,115 @@ def test_outbox_delete_follow_library(factories):
     assert activity["actor"] == follow.actor
     assert activity["object"] == follow
     assert activity["related_object"] == follow.target
+
+
+def test_handle_library_entry_update_can_manage(factories, mocker):
+    update_library_entity = mocker.patch(
+        "funkwhale_api.music.tasks.update_library_entity"
+    )
+    activity = factories["federation.Activity"]()
+    obj = factories["music.Artist"]()
+    actor = factories["federation.Actor"]()
+    mocker.patch.object(actor, "can_manage", return_value=False)
+    data = serializers.ArtistSerializer(obj).data
+    data["name"] = "New name"
+    payload = {"type": "Update", "actor": actor, "object": data}
+
+    routes.inbox_update_artist(
+        payload, context={"actor": actor, "raise_exception": True, "activity": activity}
+    )
+
+    update_library_entity.assert_not_called()
+
+
+def test_inbox_update_artist(factories, mocker):
+    update_library_entity = mocker.patch(
+        "funkwhale_api.music.tasks.update_library_entity"
+    )
+    activity = factories["federation.Activity"]()
+    obj = factories["music.Artist"](attributed=True)
+    actor = obj.attributed_to
+    data = serializers.ArtistSerializer(obj).data
+    data["name"] = "New name"
+    payload = {"type": "Update", "actor": actor, "object": data}
+
+    routes.inbox_update_artist(
+        payload, context={"actor": actor, "raise_exception": True, "activity": activity}
+    )
+
+    update_library_entity.assert_called_once_with(obj, {"name": "New name"})
+
+
+def test_outbox_update_artist(factories):
+    artist = factories["music.Artist"]()
+    activity = list(routes.outbox_update_artist({"artist": artist}))[0]
+    expected = serializers.ActivitySerializer(
+        {"type": "Update", "object": serializers.ArtistSerializer(artist).data}
+    ).data
+
+    expected["to"] = [contexts.AS.Public, {"type": "instances_with_followers"}]
+
+    assert dict(activity["payload"]) == dict(expected)
+    assert activity["actor"] == actors.get_service_actor()
+
+
+def test_inbox_update_album(factories, mocker):
+    update_library_entity = mocker.patch(
+        "funkwhale_api.music.tasks.update_library_entity"
+    )
+    activity = factories["federation.Activity"]()
+    obj = factories["music.Album"](attributed=True)
+    actor = obj.attributed_to
+    data = serializers.AlbumSerializer(obj).data
+    data["name"] = "New title"
+    payload = {"type": "Update", "actor": actor, "object": data}
+
+    routes.inbox_update_album(
+        payload, context={"actor": actor, "raise_exception": True, "activity": activity}
+    )
+
+    update_library_entity.assert_called_once_with(obj, {"title": "New title"})
+
+
+def test_outbox_update_album(factories):
+    album = factories["music.Album"]()
+    activity = list(routes.outbox_update_album({"album": album}))[0]
+    expected = serializers.ActivitySerializer(
+        {"type": "Update", "object": serializers.AlbumSerializer(album).data}
+    ).data
+
+    expected["to"] = [contexts.AS.Public, {"type": "instances_with_followers"}]
+
+    assert dict(activity["payload"]) == dict(expected)
+    assert activity["actor"] == actors.get_service_actor()
+
+
+def test_inbox_update_track(factories, mocker):
+    update_library_entity = mocker.patch(
+        "funkwhale_api.music.tasks.update_library_entity"
+    )
+    activity = factories["federation.Activity"]()
+    obj = factories["music.Track"](attributed=True)
+    actor = obj.attributed_to
+    data = serializers.TrackSerializer(obj).data
+    data["name"] = "New title"
+    payload = {"type": "Update", "actor": actor, "object": data}
+
+    routes.inbox_update_track(
+        payload, context={"actor": actor, "raise_exception": True, "activity": activity}
+    )
+
+    update_library_entity.assert_called_once_with(obj, {"title": "New title"})
+
+
+def test_outbox_update_track(factories):
+    track = factories["music.Track"]()
+    activity = list(routes.outbox_update_track({"track": track}))[0]
+    expected = serializers.ActivitySerializer(
+        {"type": "Update", "object": serializers.TrackSerializer(track).data}
+    ).data
+
+    expected["to"] = [contexts.AS.Public, {"type": "instances_with_followers"}]
+
+    assert dict(activity["payload"]) == dict(expected)
+    assert activity["actor"] == actors.get_service_actor()
diff --git a/api/tests/federation/test_serializers.py b/api/tests/federation/test_serializers.py
index 207a8fbe5e21f8e0fd29f53b41350bc7a91d18e3..5e3259e18facd0a57c30bc765492697f39642c71 100644
--- a/api/tests/federation/test_serializers.py
+++ b/api/tests/federation/test_serializers.py
@@ -5,52 +5,63 @@ import uuid
 from django.core.paginator import Paginator
 from django.utils import timezone
 
-from funkwhale_api.federation import models, serializers, utils
+from funkwhale_api.federation import keys
+from funkwhale_api.federation import jsonld
+from funkwhale_api.federation import models
+from funkwhale_api.federation import serializers
+from funkwhale_api.federation import utils
+from funkwhale_api.music import licenses
 
 
 def test_actor_serializer_from_ap(db):
+    private, public = keys.get_key_pair()
+    actor_url = "https://test.federation/actor"
     payload = {
-        "id": "https://test.federation/user",
+        "@context": jsonld.get_default_context_fw(),
+        "id": actor_url,
         "type": "Person",
-        "following": "https://test.federation/user/following",
-        "followers": "https://test.federation/user/followers",
-        "inbox": "https://test.federation/user/inbox",
-        "outbox": "https://test.federation/user/outbox",
-        "preferredUsername": "user",
-        "name": "Real User",
+        "outbox": "https://test.com/outbox",
+        "inbox": "https://test.com/inbox",
+        "following": "https://test.com/following",
+        "followers": "https://test.com/followers",
+        "preferredUsername": "test",
+        "name": "Test",
         "summary": "Hello world",
-        "url": "https://test.federation/@user",
-        "manuallyApprovesFollowers": False,
+        "manuallyApprovesFollowers": True,
         "publicKey": {
-            "id": "https://test.federation/user#main-key",
-            "owner": "https://test.federation/user",
-            "publicKeyPem": "yolo",
+            "publicKeyPem": public.decode("utf-8"),
+            "owner": actor_url,
+            "id": actor_url + "#main-key",
         },
-        "endpoints": {"sharedInbox": "https://test.federation/inbox"},
+        "endpoints": {"sharedInbox": "https://noop.url/federation/shared/inbox"},
     }
 
     serializer = serializers.ActorSerializer(data=payload)
     assert serializer.is_valid(raise_exception=True)
+    actor = serializer.save()
 
-    actor = serializer.build()
-
-    assert actor.fid == payload["id"]
+    assert actor.fid == actor_url
+    assert actor.url is None
     assert actor.inbox_url == payload["inbox"]
-    assert actor.outbox_url == payload["outbox"]
     assert actor.shared_inbox_url == payload["endpoints"]["sharedInbox"]
-    assert actor.followers_url == payload["followers"]
+    assert actor.outbox_url == payload["outbox"]
     assert actor.following_url == payload["following"]
-    assert actor.public_key == payload["publicKey"]["publicKeyPem"]
+    assert actor.followers_url == payload["followers"]
+    assert actor.followers_url == payload["followers"]
+    assert actor.type == "Person"
     assert actor.preferred_username == payload["preferredUsername"]
     assert actor.name == payload["name"]
-    assert actor.domain.pk == "test.federation"
     assert actor.summary == payload["summary"]
-    assert actor.type == "Person"
-    assert actor.manually_approves_followers == payload["manuallyApprovesFollowers"]
+    assert actor.fid == actor_url
+    assert actor.manually_approves_followers is True
+    assert actor.private_key is None
+    assert actor.public_key == payload["publicKey"]["publicKeyPem"]
+    assert actor.domain_id == "test.federation"
 
 
 def test_actor_serializer_only_mandatory_field_from_ap(db):
     payload = {
+        "@context": jsonld.get_default_context(),
         "id": "https://test.federation/user",
         "type": "Person",
         "following": "https://test.federation/user/following",
@@ -78,11 +89,7 @@ def test_actor_serializer_only_mandatory_field_from_ap(db):
 
 def test_actor_serializer_to_ap():
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "id": "https://test.federation/user",
         "type": "Person",
         "following": "https://test.federation/user/following",
@@ -147,11 +154,7 @@ def test_follow_serializer_to_ap(factories):
     serializer = serializers.FollowSerializer(follow)
 
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "id": follow.get_federation_id(),
         "type": "Follow",
         "actor": follow.actor.fid,
@@ -208,11 +211,7 @@ def test_accept_follow_serializer_representation(factories):
     follow = factories["federation.Follow"](approved=None)
 
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "id": follow.get_federation_id() + "/accept",
         "type": "Accept",
         "actor": follow.target.fid,
@@ -228,11 +227,7 @@ def test_accept_follow_serializer_save(factories):
     follow = factories["federation.Follow"](approved=None)
 
     data = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context_fw(),
         "id": follow.get_federation_id() + "/accept",
         "type": "Accept",
         "actor": follow.target.fid,
@@ -252,11 +247,7 @@ def test_accept_follow_serializer_validates_on_context(factories):
     follow = factories["federation.Follow"](approved=None)
     impostor = factories["federation.Actor"]()
     data = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context_fw(),
         "id": follow.get_federation_id() + "/accept",
         "type": "Accept",
         "actor": impostor.url,
@@ -276,11 +267,7 @@ def test_undo_follow_serializer_representation(factories):
     follow = factories["federation.Follow"](approved=True)
 
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "id": follow.get_federation_id() + "/undo",
         "type": "Undo",
         "actor": follow.actor.fid,
@@ -296,11 +283,7 @@ def test_undo_follow_serializer_save(factories):
     follow = factories["federation.Follow"](approved=True)
 
     data = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context_fw(),
         "id": follow.get_federation_id() + "/undo",
         "type": "Undo",
         "actor": follow.actor.fid,
@@ -319,11 +302,7 @@ def test_undo_follow_serializer_validates_on_context(factories):
     follow = factories["federation.Follow"](approved=True)
     impostor = factories["federation.Actor"]()
     data = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context_fw(),
         "id": follow.get_federation_id() + "/undo",
         "type": "Undo",
         "actor": impostor.url,
@@ -351,14 +330,11 @@ def test_paginated_collection_serializer(factories):
         "page_size": 2,
     }
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "type": "Collection",
         "id": conf["id"],
         "actor": actor.fid,
+        "attributedTo": actor.fid,
         "totalItems": len(uploads),
         "current": conf["id"] + "?page=1",
         "last": conf["id"] + "?page=3",
@@ -372,10 +348,12 @@ def test_paginated_collection_serializer(factories):
 
 def test_paginated_collection_serializer_validation():
     data = {
+        "@context": jsonld.get_default_context_fw(),
         "type": "Collection",
         "id": "https://test.federation/test",
         "totalItems": 5,
         "actor": "http://test.actor",
+        "attributedTo": "http://test.actor",
         "first": "https://test.federation/test?page=1",
         "last": "https://test.federation/test?page=1",
         "items": [],
@@ -386,16 +364,18 @@ def test_paginated_collection_serializer_validation():
     assert serializer.is_valid(raise_exception=True) is True
     assert serializer.validated_data["totalItems"] == 5
     assert serializer.validated_data["id"] == data["id"]
-    assert serializer.validated_data["actor"] == data["actor"]
+    assert serializer.validated_data["attributedTo"] == data["actor"]
 
 
 def test_collection_page_serializer_validation():
     base = "https://test.federation/test"
     data = {
+        "@context": jsonld.get_default_context(),
         "type": "CollectionPage",
         "id": base + "?page=2",
         "totalItems": 5,
         "actor": "https://test.actor",
+        "attributedTo": "https://test.actor",
         "items": [],
         "first": "https://test.federation/test?page=1",
         "last": "https://test.federation/test?page=3",
@@ -409,7 +389,7 @@ def test_collection_page_serializer_validation():
     assert serializer.is_valid(raise_exception=True) is True
     assert serializer.validated_data["totalItems"] == 5
     assert serializer.validated_data["id"] == data["id"]
-    assert serializer.validated_data["actor"] == data["actor"]
+    assert serializer.validated_data["attributedTo"] == data["actor"]
     assert serializer.validated_data["items"] == []
     assert serializer.validated_data["prev"] == data["prev"]
     assert serializer.validated_data["next"] == data["next"]
@@ -418,9 +398,10 @@ def test_collection_page_serializer_validation():
 
 def test_collection_page_serializer_can_validate_child():
     data = {
+        "@context": jsonld.get_default_context(),
         "type": "CollectionPage",
         "id": "https://test.page?page=2",
-        "actor": "https://test.actor",
+        "attributedTo": "https://test.actor",
         "first": "https://test.page?page=1",
         "last": "https://test.page?page=3",
         "partOf": "https://test.page",
@@ -448,14 +429,11 @@ def test_collection_page_serializer(factories):
         "page": Paginator(uploads, 2).page(2),
     }
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "type": "CollectionPage",
         "id": conf["id"] + "?page=2",
         "actor": actor.fid,
+        "attributedTo": actor.fid,
         "totalItems": len(uploads),
         "partOf": conf["id"],
         "prev": conf["id"] + "?page=1",
@@ -483,17 +461,14 @@ def test_music_library_serializer_to_ap(factories):
     factories["music.Upload"](import_status="finished")
     serializer = serializers.LibrarySerializer(library)
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "audience": "https://www.w3.org/ns/activitystreams#Public",
         "type": "Library",
         "id": library.fid,
         "name": library.name,
         "summary": library.description,
         "actor": library.actor.fid,
+        "attributedTo": library.actor.fid,
         "totalItems": 0,
         "current": library.fid + "?page=1",
         "last": library.fid + "?page=1",
@@ -510,18 +485,14 @@ def test_music_library_serializer_from_public(factories, mocker):
         "funkwhale_api.federation.utils.retrieve_ap_object", return_value=actor
     )
     data = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "audience": "https://www.w3.org/ns/activitystreams#Public",
         "name": "Hello",
         "summary": "World",
         "type": "Library",
         "id": "https://library.id",
         "followers": "https://library.id/followers",
-        "actor": actor.fid,
+        "attributedTo": actor.fid,
         "totalItems": 12,
         "first": "https://library.id?page=1",
         "last": "https://library.id?page=2",
@@ -542,6 +513,7 @@ def test_music_library_serializer_from_public(factories, mocker):
 
     retrieve.assert_called_once_with(
         actor.fid,
+        actor=None,
         queryset=actor.__class__,
         serializer_class=serializers.ActorSerializer,
     )
@@ -553,18 +525,14 @@ def test_music_library_serializer_from_private(factories, mocker):
         "funkwhale_api.federation.utils.retrieve_ap_object", return_value=actor
     )
     data = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context_fw(),
         "audience": "",
         "name": "Hello",
         "summary": "World",
         "type": "Library",
         "id": "https://library.id",
         "followers": "https://library.id/followers",
-        "actor": actor.fid,
+        "attributedTo": actor.fid,
         "totalItems": 12,
         "first": "https://library.id?page=1",
         "last": "https://library.id?page=2",
@@ -584,13 +552,14 @@ def test_music_library_serializer_from_private(factories, mocker):
     assert library.followers_url == data["followers"]
     retrieve.assert_called_once_with(
         actor.fid,
+        actor=None,
         queryset=actor.__class__,
         serializer_class=serializers.ActorSerializer,
     )
 
 
 def test_activity_pub_artist_serializer_to_ap(factories):
-    artist = factories["music.Artist"]()
+    artist = factories["music.Artist"](attributed=True)
     expected = {
         "@context": serializers.AP_CONTEXT,
         "type": "Artist",
@@ -598,6 +567,7 @@ def test_activity_pub_artist_serializer_to_ap(factories):
         "name": artist.name,
         "musicbrainzId": artist.mbid,
         "published": artist.creation_date.isoformat(),
+        "attributedTo": artist.attributed_to.fid,
     }
     serializer = serializers.ArtistSerializer(artist)
 
@@ -605,7 +575,7 @@ def test_activity_pub_artist_serializer_to_ap(factories):
 
 
 def test_activity_pub_album_serializer_to_ap(factories):
-    album = factories["music.Album"]()
+    album = factories["music.Album"](attributed=True)
 
     expected = {
         "@context": serializers.AP_CONTEXT,
@@ -625,6 +595,7 @@ def test_activity_pub_album_serializer_to_ap(factories):
                 album.artist, context={"include_ap_context": False}
             ).data
         ],
+        "attributedTo": album.attributed_to.fid,
     }
     serializer = serializers.AlbumSerializer(album)
 
@@ -633,7 +604,7 @@ def test_activity_pub_album_serializer_to_ap(factories):
 
 def test_activity_pub_track_serializer_to_ap(factories):
     track = factories["music.Track"](
-        license="cc-by-4.0", copyright="test", disc_number=3
+        license="cc-by-4.0", copyright="test", disc_number=3, attributed=True
     )
     expected = {
         "@context": serializers.AP_CONTEXT,
@@ -654,17 +625,24 @@ def test_activity_pub_track_serializer_to_ap(factories):
         "album": serializers.AlbumSerializer(
             track.album, context={"include_ap_context": False}
         ).data,
+        "attributedTo": track.attributed_to.fid,
     }
     serializer = serializers.TrackSerializer(track)
 
     assert serializer.data == expected
 
 
-def test_activity_pub_track_serializer_from_ap(factories, r_mock):
+def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
+    track_attributed_to = factories["federation.Actor"]()
+    album_attributed_to = factories["federation.Actor"]()
+    album_artist_attributed_to = factories["federation.Actor"]()
+    artist_attributed_to = factories["federation.Actor"]()
+
     activity = factories["federation.Activity"]()
     published = timezone.now()
     released = timezone.now().date()
     data = {
+        "@context": jsonld.get_default_context(),
         "type": "Track",
         "id": "http://hello.track",
         "published": published.isoformat(),
@@ -672,6 +650,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock):
         "name": "Black in back",
         "position": 5,
         "disc": 1,
+        "attributedTo": track_attributed_to.fid,
         "album": {
             "type": "Album",
             "id": "http://hello.album",
@@ -679,6 +658,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock):
             "musicbrainzId": str(uuid.uuid4()),
             "published": published.isoformat(),
             "released": released.isoformat(),
+            "attributedTo": album_attributed_to.fid,
             "cover": {
                 "type": "Link",
                 "href": "https://cover.image/test.png",
@@ -691,6 +671,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock):
                     "name": "John Smith",
                     "musicbrainzId": str(uuid.uuid4()),
                     "published": published.isoformat(),
+                    "attributedTo": album_artist_attributed_to.fid,
                 }
             ],
         },
@@ -700,6 +681,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock):
                 "id": "http://hello.trackartist",
                 "name": "Bob Smith",
                 "musicbrainzId": str(uuid.uuid4()),
+                "attributedTo": artist_attributed_to.fid,
                 "published": published.isoformat(),
             }
         ],
@@ -719,28 +701,32 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock):
     assert track.position == data["position"]
     assert track.disc_number == data["disc"]
     assert track.creation_date == published
+    assert track.attributed_to == track_attributed_to
     assert str(track.mbid) == data["musicbrainzId"]
 
     assert album.from_activity == activity
     assert album.cover.read() == b"coucou"
-    assert album.cover.path.endswith(".png")
+    assert album.cover_path.endswith(".png")
     assert album.title == data["album"]["name"]
     assert album.fid == data["album"]["id"]
     assert str(album.mbid) == data["album"]["musicbrainzId"]
     assert album.creation_date == published
     assert album.release_date == released
+    assert album.attributed_to == album_attributed_to
 
     assert artist.from_activity == activity
     assert artist.name == data["artists"][0]["name"]
     assert artist.fid == data["artists"][0]["id"]
     assert str(artist.mbid) == data["artists"][0]["musicbrainzId"]
     assert artist.creation_date == published
+    assert artist.attributed_to == artist_attributed_to
 
     assert album_artist.from_activity == activity
     assert album_artist.name == data["album"]["artists"][0]["name"]
     assert album_artist.fid == data["album"]["artists"][0]["id"]
     assert str(album_artist.mbid) == data["album"]["artists"][0]["musicbrainzId"]
     assert album_artist.creation_date == published
+    assert album_artist.attributed_to == album_artist_attributed_to
 
 
 def test_activity_pub_upload_serializer_from_ap(factories, mocker, r_mock):
@@ -866,11 +852,7 @@ def test_activity_pub_audio_serializer_to_ap(factories):
 
 def test_local_actor_serializer_to_ap(factories):
     expected = {
-        "@context": [
-            "https://www.w3.org/ns/activitystreams",
-            "https://w3id.org/security/v1",
-            {},
-        ],
+        "@context": jsonld.get_default_context(),
         "id": "https://test.federation/user",
         "type": "Person",
         "following": "https://test.federation/user/following",
@@ -928,3 +910,16 @@ def test_activity_serializer_validate_recipients_empty(db):
 
     with pytest.raises(serializers.serializers.ValidationError):
         s.validate_recipients({"cc": []})
+
+
+def test_track_serializer_update_license(factories):
+    licenses.load(licenses.LICENSES)
+
+    obj = factories["music.Track"](license=None)
+
+    serializer = serializers.TrackSerializer()
+    serializer.update(obj, {"license": "http://creativecommons.org/licenses/by/2.0/"})
+
+    obj.refresh_from_db()
+
+    assert obj.license_id == "cc-by-2.0"
diff --git a/api/tests/federation/test_tasks.py b/api/tests/federation/test_tasks.py
index 21aa181f8730489baf4bfd14be786ab4ba1e6b8d..7c29d4698ebbbbc8cd0ccef6a4046603dadf6c76 100644
--- a/api/tests/federation/test_tasks.py
+++ b/api/tests/federation/test_tasks.py
@@ -5,7 +5,11 @@ import pytest
 
 from django.utils import timezone
 
+from funkwhale_api.federation import jsonld
+from funkwhale_api.federation import models
+from funkwhale_api.federation import serializers
 from funkwhale_api.federation import tasks
+from funkwhale_api.federation import utils
 
 
 def test_clean_federation_music_cache_if_no_listen(preferences, factories):
@@ -22,10 +26,10 @@ def test_clean_federation_music_cache_if_no_listen(preferences, factories):
     # local upload, should not be cleaned
     upload4 = factories["music.Upload"](library__actor__local=True, accessed_date=None)
 
-    path1 = upload1.audio_file.path
-    path2 = upload2.audio_file.path
-    path3 = upload3.audio_file.path
-    path4 = upload4.audio_file.path
+    path1 = upload1.audio_file_path
+    path2 = upload2.audio_file_path
+    path3 = upload3.audio_file_path
+    path4 = upload4.audio_file_path
 
     tasks.clean_music_cache()
 
@@ -62,7 +66,7 @@ def test_clean_federation_music_cache_orphaned(settings, preferences, factories)
     upload.refresh_from_db()
 
     assert bool(upload.audio_file) is True
-    assert os.path.exists(upload.audio_file.path) is True
+    assert os.path.exists(upload.audio_file_path) is True
     assert os.path.exists(remove_path) is False
 
 
@@ -83,16 +87,21 @@ def test_handle_in(factories, mocker, now, queryset_equal_list):
     )
 
 
-def test_dispatch_outbox(factories, mocker):
+@pytest.mark.parametrize(
+    "type, call_handlers", [("Noop", False), ("Update", False), ("Follow", True)]
+)
+def test_dispatch_outbox(factories, mocker, type, call_handlers):
     mocked_inbox = mocker.patch("funkwhale_api.federation.tasks.dispatch_inbox.delay")
     mocked_deliver_to_remote = mocker.patch(
         "funkwhale_api.federation.tasks.deliver_to_remote.delay"
     )
-    activity = factories["federation.Activity"](actor__local=True)
+    activity = factories["federation.Activity"](actor__local=True, type=type)
     factories["federation.InboxItem"](activity=activity)
     delivery = factories["federation.Delivery"](activity=activity)
     tasks.dispatch_outbox(activity_id=activity.pk)
-    mocked_inbox.assert_called_once_with(activity_id=activity.pk, call_handlers=False)
+    mocked_inbox.assert_called_once_with(
+        activity_id=activity.pk, call_handlers=call_handlers
+    )
     mocked_deliver_to_remote.assert_called_once_with(delivery_id=delivery.pk)
 
 
@@ -162,23 +171,42 @@ def test_fetch_nodeinfo(factories, r_mock, now):
     assert tasks.fetch_nodeinfo("test.test") == {"hello": "world"}
 
 
-def test_update_domain_nodeinfo(factories, mocker, now):
-    domain = factories["federation.Domain"]()
-    mocker.patch.object(tasks, "fetch_nodeinfo", return_value={"hello": "world"})
+def test_update_domain_nodeinfo(factories, mocker, now, service_actor):
+    domain = factories["federation.Domain"](nodeinfo_fetch_date=None)
+    actor = factories["federation.Actor"](fid="https://actor.id")
+    retrieve_ap_object = mocker.spy(utils, "retrieve_ap_object")
+
+    mocker.patch.object(
+        tasks,
+        "fetch_nodeinfo",
+        return_value={"hello": "world", "metadata": {"actorId": "https://actor.id"}},
+    )
 
     assert domain.nodeinfo == {}
     assert domain.nodeinfo_fetch_date is None
+    assert domain.service_actor is None
 
     tasks.update_domain_nodeinfo(domain_name=domain.name)
 
     domain.refresh_from_db()
 
     assert domain.nodeinfo_fetch_date == now
-    assert domain.nodeinfo == {"status": "ok", "payload": {"hello": "world"}}
+    assert domain.nodeinfo == {
+        "status": "ok",
+        "payload": {"hello": "world", "metadata": {"actorId": "https://actor.id"}},
+    }
+    assert domain.service_actor == actor
+
+    retrieve_ap_object.assert_called_once_with(
+        "https://actor.id",
+        actor=service_actor,
+        queryset=models.Actor,
+        serializer_class=serializers.ActorSerializer,
+    )
 
 
 def test_update_domain_nodeinfo_error(factories, r_mock, now):
-    domain = factories["federation.Domain"]()
+    domain = factories["federation.Domain"](nodeinfo_fetch_date=None)
     wellknown_url = "https://{}/.well-known/nodeinfo".format(domain.name)
 
     r_mock.get(wellknown_url, status_code=500)
@@ -194,6 +222,31 @@ def test_update_domain_nodeinfo_error(factories, r_mock, now):
     }
 
 
+def test_refresh_nodeinfo_known_nodes(settings, factories, mocker, now):
+    settings.NODEINFO_REFRESH_DELAY = 666
+
+    refreshed = [
+        factories["federation.Domain"](nodeinfo_fetch_date=None),
+        factories["federation.Domain"](
+            nodeinfo_fetch_date=now
+            - datetime.timedelta(seconds=settings.NODEINFO_REFRESH_DELAY + 1)
+        ),
+    ]
+    factories["federation.Domain"](
+        nodeinfo_fetch_date=now
+        - datetime.timedelta(seconds=settings.NODEINFO_REFRESH_DELAY - 1)
+    )
+
+    update_domain_nodeinfo = mocker.patch.object(tasks.update_domain_nodeinfo, "delay")
+
+    tasks.refresh_nodeinfo_known_nodes()
+
+    assert update_domain_nodeinfo.call_count == len(refreshed)
+
+    for d in refreshed:
+        update_domain_nodeinfo.assert_any_call(domain_name=d.name)
+
+
 def test_handle_purge_actors(factories, mocker):
     to_purge = factories["federation.Actor"]()
     keeped = [
@@ -285,3 +338,60 @@ def test_rotate_actor_key(factories, settings, mocker):
 
     assert actor.public_key == "public"
     assert actor.private_key == "private"
+
+
+def test_fetch_skipped(factories, r_mock):
+    url = "https://fetch.object"
+    fetch = factories["federation.Fetch"](url=url)
+    payload = {"@context": jsonld.get_default_context(), "type": "Unhandled"}
+    r_mock.get(url, json=payload)
+
+    tasks.fetch(fetch_id=fetch.pk)
+
+    fetch.refresh_from_db()
+
+    assert fetch.status == "skipped"
+    assert fetch.detail["reason"] == "unhandled_type"
+
+
+@pytest.mark.parametrize(
+    "r_mock_args, expected_error_code",
+    [
+        ({"json": {"type": "Unhandled"}}, "invalid_jsonld"),
+        ({"json": {"@context": jsonld.get_default_context()}}, "invalid_jsonld"),
+        ({"text": "invalidjson"}, "invalid_json"),
+        ({"status_code": 404}, "http"),
+        ({"status_code": 500}, "http"),
+    ],
+)
+def test_fetch_errored(factories, r_mock_args, expected_error_code, r_mock):
+    url = "https://fetch.object"
+    fetch = factories["federation.Fetch"](url=url)
+    r_mock.get(url, **r_mock_args)
+
+    tasks.fetch(fetch_id=fetch.pk)
+
+    fetch.refresh_from_db()
+
+    assert fetch.status == "errored"
+    assert fetch.detail["error_code"] == expected_error_code
+
+
+def test_fetch_success(factories, r_mock, mocker):
+    artist = factories["music.Artist"]()
+    fetch = factories["federation.Fetch"](url=artist.fid)
+    payload = serializers.ArtistSerializer(artist).data
+    init = mocker.spy(serializers.ArtistSerializer, "__init__")
+    save = mocker.spy(serializers.ArtistSerializer, "save")
+
+    r_mock.get(artist.fid, json=payload)
+
+    tasks.fetch(fetch_id=fetch.pk)
+
+    fetch.refresh_from_db()
+    payload["@context"].append("https://funkwhale.audio/ns")
+    assert fetch.status == "finished"
+    assert init.call_count == 1
+    assert init.call_args[0][1] == artist
+    assert init.call_args[1]["data"] == payload
+    assert save.call_count == 1
diff --git a/api/tests/federation/test_utils.py b/api/tests/federation/test_utils.py
index a8d02cdb9cc30ae7468a01bbc5b787ce1da73b2e..9aa850728ef969ee8a7e764050e3846650d21358 100644
--- a/api/tests/federation/test_utils.py
+++ b/api/tests/federation/test_utils.py
@@ -56,7 +56,7 @@ def test_extract_headers_from_meta():
 def test_retrieve_ap_object(db, r_mock):
     fid = "https://some.url"
     m = r_mock.get(fid, json={"hello": "world"})
-    result = utils.retrieve_ap_object(fid)
+    result = utils.retrieve_ap_object(fid, actor=None)
 
     assert result == {"hello": "world"}
     assert m.request_history[-1].headers["Accept"] == "application/activity+json"
@@ -69,7 +69,7 @@ def test_retrieve_ap_object_honor_instance_policy_domain(factories):
     fid = "https://{}/test".format(domain.name)
 
     with pytest.raises(exceptions.BlockedActorOrDomain):
-        utils.retrieve_ap_object(fid)
+        utils.retrieve_ap_object(fid, actor=None)
 
 
 def test_retrieve_ap_object_honor_instance_policy_different_url_and_id(
@@ -82,7 +82,7 @@ def test_retrieve_ap_object_honor_instance_policy_different_url_and_id(
     r_mock.get(fid, json={"id": "http://{}/test".format(domain.name)})
 
     with pytest.raises(exceptions.BlockedActorOrDomain):
-        utils.retrieve_ap_object(fid)
+        utils.retrieve_ap_object(fid, actor=None)
 
 
 def test_retrieve_with_actor(r_mock, factories):
@@ -99,7 +99,7 @@ def test_retrieve_with_actor(r_mock, factories):
 def test_retrieve_with_queryset(factories):
     actor = factories["federation.Actor"]()
 
-    assert utils.retrieve_ap_object(actor.fid, queryset=actor.__class__)
+    assert utils.retrieve_ap_object(actor.fid, actor=None, queryset=actor.__class__)
 
 
 def test_retrieve_with_serializer(db, r_mock):
@@ -109,6 +109,6 @@ def test_retrieve_with_serializer(db, r_mock):
 
     fid = "https://some.url"
     r_mock.get(fid, json={"hello": "world"})
-    result = utils.retrieve_ap_object(fid, serializer_class=S)
+    result = utils.retrieve_ap_object(fid, actor=None, serializer_class=S)
 
     assert result == {"persisted": "object"}
diff --git a/api/tests/federation/test_views.py b/api/tests/federation/test_views.py
index 2caa7856a10c81ba13aaf024a7f155d0bb074c9e..93ce05b8ebde3b88cbd1c5528ce4db6579256d7f 100644
--- a/api/tests/federation/test_views.py
+++ b/api/tests/federation/test_views.py
@@ -2,7 +2,7 @@ import pytest
 from django.core.paginator import Paginator
 from django.urls import reverse
 
-from funkwhale_api.federation import serializers, webfinger
+from funkwhale_api.federation import actors, serializers, webfinger
 
 
 def test_wellknown_webfinger_validates_resource(db, api_client, settings, mocker):
@@ -54,6 +54,19 @@ def test_local_actor_detail(factories, api_client):
     assert response.data == serializer.data
 
 
+def test_service_actor_detail(factories, api_client):
+    actor = actors.get_service_actor()
+    url = reverse(
+        "federation:actors-detail",
+        kwargs={"preferred_username": actor.preferred_username},
+    )
+    serializer = serializers.ActorSerializer(actor)
+    response = api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data == serializer.data
+
+
 def test_local_actor_inbox_post_requires_auth(factories, api_client):
     user = factories["users.User"](with_actor=True)
     url = reverse(
@@ -80,6 +93,35 @@ def test_local_actor_inbox_post(factories, api_client, mocker, authenticated_act
     )
 
 
+def test_local_actor_inbox_post_receive(
+    factories, api_client, mocker, authenticated_actor
+):
+    payload = {
+        "to": [
+            "https://test.server/federation/music/libraries/956af6c9-1eb9-4117-8d17-b15e7b34afeb/followers"
+        ],
+        "type": "Create",
+        "actor": authenticated_actor.fid,
+        "object": {
+            "id": "https://test.server/federation/music/uploads/fe564a47-b1d4-4596-bf96-008ccf407672",
+            "type": "Audio",
+        },
+        "@context": [
+            "https://www.w3.org/ns/activitystreams",
+            "https://w3id.org/security/v1",
+            {},
+        ],
+    }
+    user = factories["users.User"](with_actor=True)
+    url = reverse(
+        "federation:actors-inbox",
+        kwargs={"preferred_username": user.actor.preferred_username},
+    )
+    response = api_client.post(url, payload, format="json")
+
+    assert response.status_code == 200
+
+
 def test_shared_inbox_post(factories, api_client, mocker, authenticated_actor):
     patched_receive = mocker.patch("funkwhale_api.federation.activity.receive")
     url = reverse("federation:shared-inbox")
@@ -161,3 +203,75 @@ def test_music_library_retrieve_page_follow(
     response = api_client.get(url, {"page": 1})
 
     assert response.status_code == expected
+
+
+@pytest.mark.parametrize(
+    "factory, serializer_class, namespace",
+    [
+        ("music.Artist", serializers.ArtistSerializer, "artists"),
+        ("music.Album", serializers.AlbumSerializer, "albums"),
+        ("music.Track", serializers.TrackSerializer, "tracks"),
+    ],
+)
+def test_music_local_entity_detail(
+    factories, api_client, factory, serializer_class, namespace, settings
+):
+    obj = factories[factory](fid="http://{}/1".format(settings.FEDERATION_HOSTNAME))
+    url = reverse(
+        "federation:music:{}-detail".format(namespace), kwargs={"uuid": obj.uuid}
+    )
+    response = api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data == serializer_class(obj).data
+
+
+@pytest.mark.parametrize(
+    "factory, namespace",
+    [("music.Artist", "artists"), ("music.Album", "albums"), ("music.Track", "tracks")],
+)
+def test_music_non_local_entity_detail(
+    factories, api_client, factory, namespace, settings
+):
+    obj = factories[factory](fid="http://wrong-domain/1")
+    url = reverse(
+        "federation:music:{}-detail".format(namespace), kwargs={"uuid": obj.uuid}
+    )
+    response = api_client.get(url)
+
+    assert response.status_code == 404
+
+
+@pytest.mark.parametrize(
+    "privacy_level, expected", [("me", 404), ("instance", 404), ("everyone", 200)]
+)
+def test_music_upload_detail(factories, api_client, privacy_level, expected):
+    upload = factories["music.Upload"](
+        library__privacy_level=privacy_level,
+        library__actor__local=True,
+        import_status="finished",
+    )
+    url = reverse("federation:music:uploads-detail", kwargs={"uuid": upload.uuid})
+    response = api_client.get(url)
+
+    assert response.status_code == expected
+    if expected == 200:
+        assert response.data == serializers.UploadSerializer(upload).data
+
+
+@pytest.mark.parametrize("privacy_level", ["me", "instance"])
+def test_music_upload_detail_private_approved_follow(
+    factories, api_client, authenticated_actor, privacy_level
+):
+    upload = factories["music.Upload"](
+        library__privacy_level=privacy_level,
+        library__actor__local=True,
+        import_status="finished",
+    )
+    factories["federation.LibraryFollow"](
+        actor=authenticated_actor, target=upload.library, approved=True
+    )
+    url = reverse("federation:music:uploads-detail", kwargs={"uuid": upload.uuid})
+    response = api_client.get(url)
+
+    assert response.status_code == 200
diff --git a/api/tests/history/test_filters.py b/api/tests/history/test_filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..257d46bf0c0b311ff57c0b71f90d32b0beea38c1
--- /dev/null
+++ b/api/tests/history/test_filters.py
@@ -0,0 +1,28 @@
+from funkwhale_api.history import filters
+from funkwhale_api.history import models
+
+
+def test_listening_filter_track_artist(factories, mocker, queryset_equal_list):
+    factories["history.Listening"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_listening = factories["history.Listening"](track__artist=cf.target_artist)
+    qs = models.Listening.objects.all()
+    filterset = filters.ListeningFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_listening]
+
+
+def test_listening_filter_track_album_artist(factories, mocker, queryset_equal_list):
+    factories["history.Listening"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_listening = factories["history.Listening"](
+        track__album__artist=cf.target_artist
+    )
+    qs = models.Listening.objects.all()
+    filterset = filters.ListeningFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_listening]
diff --git a/api/tests/instance/test_nodeinfo.py b/api/tests/instance/test_nodeinfo.py
index a5bdc70933c696faae1297540532b594453d110b..233b388d43895ed3138c22126d48210ef520a47a 100644
--- a/api/tests/instance/test_nodeinfo.py
+++ b/api/tests/instance/test_nodeinfo.py
@@ -1,5 +1,7 @@
 import funkwhale_api
 from funkwhale_api.instance import nodeinfo
+from funkwhale_api.federation import actors
+from funkwhale_api.music import utils as music_utils
 
 
 def test_nodeinfo_dump(preferences, mocker):
@@ -23,6 +25,7 @@ def test_nodeinfo_dump(preferences, mocker):
         "openRegistrations": preferences["users__registration_enabled"],
         "usage": {"users": {"total": 1, "activeHalfyear": 12, "activeMonth": 13}},
         "metadata": {
+            "actorId": actors.get_service_actor().fid,
             "private": preferences["instance__nodeinfo_private"],
             "shortDescription": preferences["instance__short_description"],
             "longDescription": preferences["instance__long_description"],
@@ -44,6 +47,7 @@ def test_nodeinfo_dump(preferences, mocker):
                 "favorites": {"tracks": {"total": stats["track_favorites"]}},
                 "listenings": {"total": stats["listenings"]},
             },
+            "supportedUploadExtensions": music_utils.SUPPORTED_EXTENSIONS,
         },
     }
     assert nodeinfo.get() == expected
@@ -60,6 +64,7 @@ def test_nodeinfo_dump_stats_disabled(preferences, mocker):
         "openRegistrations": preferences["users__registration_enabled"],
         "usage": {"users": {"total": 0, "activeHalfyear": 0, "activeMonth": 0}},
         "metadata": {
+            "actorId": actors.get_service_actor().fid,
             "private": preferences["instance__nodeinfo_private"],
             "shortDescription": preferences["instance__short_description"],
             "longDescription": preferences["instance__long_description"],
@@ -73,6 +78,7 @@ def test_nodeinfo_dump_stats_disabled(preferences, mocker):
                     "common__api_authentication_required"
                 ],
             },
+            "supportedUploadExtensions": music_utils.SUPPORTED_EXTENSIONS,
         },
     }
     assert nodeinfo.get() == expected
diff --git a/api/tests/instance/test_views.py b/api/tests/instance/test_views.py
index 6dd4f6345afebaf91dc001d0b408fb31ae83bbda..0b3b7b79ad2e57716159a5fd12396068ef04bdd8 100644
--- a/api/tests/instance/test_views.py
+++ b/api/tests/instance/test_views.py
@@ -1,13 +1,5 @@
-import pytest
 from django.urls import reverse
 
-from funkwhale_api.instance import views
-
-
-@pytest.mark.parametrize("view,permissions", [(views.AdminSettings, ["settings"])])
-def test_permissions(assert_user_permission, view, permissions):
-    assert_user_permission(view, permissions)
-
 
 def test_nodeinfo_endpoint(db, api_client, mocker):
     payload = {"test": "test"}
diff --git a/api/tests/manage/test_serializers.py b/api/tests/manage/test_serializers.py
index 53bc2504b2487e018448755f4cd25b9438108efe..65c75c2c331cc013761d3ee00c22a985e21c2b21 100644
--- a/api/tests/manage/test_serializers.py
+++ b/api/tests/manage/test_serializers.py
@@ -40,7 +40,7 @@ def test_user_update_permission(factories):
 
 
 def test_manage_domain_serializer(factories, now):
-    domain = factories["federation.Domain"]()
+    domain = factories["federation.Domain"](nodeinfo_fetch_date=None)
     setattr(domain, "actors_count", 42)
     setattr(domain, "outbox_activities_count", 23)
     expected = {
@@ -257,3 +257,221 @@ def test_instance_policy_serializer_purges_target_actor(
 
     assert getattr(policy, param) is False
     assert on_commit.call_count == 0
+
+
+def test_manage_artist_serializer(factories, now):
+    artist = factories["music.Artist"](attributed=True)
+    track = factories["music.Track"](artist=artist)
+    album = factories["music.Album"](artist=artist)
+    expected = {
+        "id": artist.id,
+        "domain": artist.domain_name,
+        "is_local": artist.is_local,
+        "fid": artist.fid,
+        "name": artist.name,
+        "mbid": artist.mbid,
+        "creation_date": artist.creation_date.isoformat().split("+")[0] + "Z",
+        "albums": [serializers.ManageNestedAlbumSerializer(album).data],
+        "tracks": [serializers.ManageNestedTrackSerializer(track).data],
+        "attributed_to": serializers.ManageBaseActorSerializer(
+            artist.attributed_to
+        ).data,
+    }
+    s = serializers.ManageArtistSerializer(artist)
+
+    assert s.data == expected
+
+
+def test_manage_nested_track_serializer(factories, now):
+    track = factories["music.Track"]()
+    expected = {
+        "id": track.id,
+        "domain": track.domain_name,
+        "is_local": track.is_local,
+        "fid": track.fid,
+        "title": track.title,
+        "mbid": track.mbid,
+        "creation_date": track.creation_date.isoformat().split("+")[0] + "Z",
+        "position": track.position,
+        "disc_number": track.disc_number,
+        "copyright": track.copyright,
+        "license": track.license,
+    }
+    s = serializers.ManageNestedTrackSerializer(track)
+
+    assert s.data == expected
+
+
+def test_manage_nested_album_serializer(factories, now):
+    album = factories["music.Album"]()
+    setattr(album, "tracks_count", 44)
+    expected = {
+        "id": album.id,
+        "domain": album.domain_name,
+        "is_local": album.is_local,
+        "fid": album.fid,
+        "title": album.title,
+        "mbid": album.mbid,
+        "creation_date": album.creation_date.isoformat().split("+")[0] + "Z",
+        "release_date": album.release_date.isoformat(),
+        "cover": {
+            "original": album.cover.url,
+            "square_crop": album.cover.crop["400x400"].url,
+            "medium_square_crop": album.cover.crop["200x200"].url,
+            "small_square_crop": album.cover.crop["50x50"].url,
+        },
+        "tracks_count": 44,
+    }
+    s = serializers.ManageNestedAlbumSerializer(album)
+
+    assert s.data == expected
+
+
+def test_manage_nested_artist_serializer(factories, now):
+    artist = factories["music.Artist"]()
+    expected = {
+        "id": artist.id,
+        "domain": artist.domain_name,
+        "is_local": artist.is_local,
+        "fid": artist.fid,
+        "name": artist.name,
+        "mbid": artist.mbid,
+        "creation_date": artist.creation_date.isoformat().split("+")[0] + "Z",
+    }
+    s = serializers.ManageNestedArtistSerializer(artist)
+
+    assert s.data == expected
+
+
+def test_manage_album_serializer(factories, now):
+    album = factories["music.Album"](attributed=True)
+    track = factories["music.Track"](album=album)
+    expected = {
+        "id": album.id,
+        "domain": album.domain_name,
+        "is_local": album.is_local,
+        "fid": album.fid,
+        "title": album.title,
+        "mbid": album.mbid,
+        "creation_date": album.creation_date.isoformat().split("+")[0] + "Z",
+        "release_date": album.release_date.isoformat(),
+        "cover": {
+            "original": album.cover.url,
+            "square_crop": album.cover.crop["400x400"].url,
+            "medium_square_crop": album.cover.crop["200x200"].url,
+            "small_square_crop": album.cover.crop["50x50"].url,
+        },
+        "artist": serializers.ManageNestedArtistSerializer(album.artist).data,
+        "tracks": [serializers.ManageNestedTrackSerializer(track).data],
+        "attributed_to": serializers.ManageBaseActorSerializer(
+            album.attributed_to
+        ).data,
+    }
+    s = serializers.ManageAlbumSerializer(album)
+
+    assert s.data == expected
+
+
+def test_manage_track_serializer(factories, now):
+    track = factories["music.Track"](attributed=True)
+    setattr(track, "uploads_count", 44)
+    expected = {
+        "id": track.id,
+        "domain": track.domain_name,
+        "is_local": track.is_local,
+        "fid": track.fid,
+        "title": track.title,
+        "mbid": track.mbid,
+        "disc_number": track.disc_number,
+        "position": track.position,
+        "copyright": track.copyright,
+        "license": track.license,
+        "creation_date": track.creation_date.isoformat().split("+")[0] + "Z",
+        "artist": serializers.ManageNestedArtistSerializer(track.artist).data,
+        "album": serializers.ManageTrackAlbumSerializer(track.album).data,
+        "attributed_to": serializers.ManageBaseActorSerializer(
+            track.attributed_to
+        ).data,
+        "uploads_count": 44,
+    }
+    s = serializers.ManageTrackSerializer(track)
+
+    assert s.data == expected
+
+
+def test_manage_library_serializer(factories, now):
+    library = factories["music.Library"]()
+    setattr(library, "followers_count", 42)
+    setattr(library, "_uploads_count", 44)
+    expected = {
+        "id": library.id,
+        "fid": library.fid,
+        "url": library.url,
+        "uuid": str(library.uuid),
+        "followers_url": library.followers_url,
+        "domain": library.domain_name,
+        "is_local": library.is_local,
+        "name": library.name,
+        "description": library.description,
+        "privacy_level": library.privacy_level,
+        "creation_date": library.creation_date.isoformat().split("+")[0] + "Z",
+        "actor": serializers.ManageBaseActorSerializer(library.actor).data,
+        "uploads_count": 44,
+        "followers_count": 42,
+    }
+    s = serializers.ManageLibrarySerializer(library)
+
+    assert s.data == expected
+
+
+def test_manage_upload_serializer(factories, now):
+    upload = factories["music.Upload"]()
+
+    expected = {
+        "id": upload.id,
+        "fid": upload.fid,
+        "audio_file": upload.audio_file.url,
+        "listen_url": upload.listen_url,
+        "uuid": str(upload.uuid),
+        "domain": upload.domain_name,
+        "is_local": upload.is_local,
+        "duration": upload.duration,
+        "size": upload.size,
+        "bitrate": upload.bitrate,
+        "mimetype": upload.mimetype,
+        "source": upload.source,
+        "filename": upload.filename,
+        "metadata": upload.metadata,
+        "creation_date": upload.creation_date.isoformat().split("+")[0] + "Z",
+        "modification_date": upload.modification_date.isoformat().split("+")[0] + "Z",
+        "accessed_date": None,
+        "import_date": None,
+        "import_metadata": upload.import_metadata,
+        "import_status": upload.import_status,
+        "import_reference": upload.import_reference,
+        "import_details": upload.import_details,
+        "library": serializers.ManageNestedLibrarySerializer(upload.library).data,
+        "track": serializers.ManageNestedTrackSerializer(upload.track).data,
+    }
+    s = serializers.ManageUploadSerializer(upload)
+
+    assert s.data == expected
+
+
+@pytest.mark.parametrize(
+    "factory, serializer_class",
+    [
+        ("music.Track", serializers.ManageTrackActionSerializer),
+        ("music.Album", serializers.ManageAlbumActionSerializer),
+        ("music.Artist", serializers.ManageArtistActionSerializer),
+        ("music.Library", serializers.ManageLibraryActionSerializer),
+        ("music.Upload", serializers.ManageUploadActionSerializer),
+    ],
+)
+def test_action_serializer_delete(factory, serializer_class, factories):
+    objects = factories[factory].create_batch(size=5)
+    s = serializer_class(queryset=None)
+
+    s.handle_delete(objects[0].__class__.objects.all())
+
+    assert objects[0].__class__.objects.count() == 0
diff --git a/api/tests/manage/test_views.py b/api/tests/manage/test_views.py
index 6402fb6505cdd1ff66d833631a55903ab4924687..e3d136a0e841ab5e49c9dd782083d5f3b9c5cf2a 100644
--- a/api/tests/manage/test_views.py
+++ b/api/tests/manage/test_views.py
@@ -1,39 +1,8 @@
-import pytest
 from django.urls import reverse
 
 from funkwhale_api.federation import models as federation_models
 from funkwhale_api.federation import tasks as federation_tasks
-from funkwhale_api.manage import serializers, views
-
-
-@pytest.mark.parametrize(
-    "view,permissions,operator",
-    [
-        (views.ManageUploadViewSet, ["library"], "and"),
-        (views.ManageUserViewSet, ["settings"], "and"),
-        (views.ManageInvitationViewSet, ["settings"], "and"),
-        (views.ManageDomainViewSet, ["moderation"], "and"),
-        (views.ManageActorViewSet, ["moderation"], "and"),
-        (views.ManageInstancePolicyViewSet, ["moderation"], "and"),
-    ],
-)
-def test_permissions(assert_user_permission, view, permissions, operator):
-    assert_user_permission(view, permissions, operator)
-
-
-@pytest.mark.skip(reason="Refactoring in progress")
-def test_upload_view(factories, superuser_api_client):
-    uploads = factories["music.Upload"].create_batch(size=5)
-    qs = uploads[0].__class__.objects.order_by("-creation_date")
-    url = reverse("api:v1:manage:library:uploads-list")
-
-    response = superuser_api_client.get(url, {"sort": "-creation_date"})
-    expected = serializers.ManageUploadSerializer(
-        qs, many=True, context={"request": response.wsgi_request}
-    ).data
-
-    assert response.data["count"] == len(uploads)
-    assert response.data["results"] == expected
+from funkwhale_api.manage import serializers
 
 
 def test_user_view(factories, superuser_api_client, mocker):
@@ -92,12 +61,16 @@ def test_domain_detail(factories, superuser_api_client):
     assert response.data["name"] == d.pk
 
 
-def test_domain_create(superuser_api_client):
+def test_domain_create(superuser_api_client, mocker):
+    update_domain_nodeinfo = mocker.patch(
+        "funkwhale_api.federation.tasks.update_domain_nodeinfo"
+    )
     url = reverse("api:v1:manage:federation:domains-list")
     response = superuser_api_client.post(url, {"name": "test.federation"})
 
     assert response.status_code == 201
     assert federation_models.Domain.objects.filter(pk="test.federation").exists()
+    update_domain_nodeinfo.assert_called_once_with(domain_name="test.federation")
 
 
 def test_domain_nodeinfo(factories, superuser_api_client, mocker):
@@ -159,3 +132,223 @@ def test_instance_policy_create(superuser_api_client, factories):
 
     policy = domain.instance_policy
     assert policy.actor == actor
+
+
+def test_artist_list(factories, superuser_api_client, settings):
+    artist = factories["music.Artist"]()
+    url = reverse("api:v1:manage:library:artists-list")
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+
+    assert response.data["count"] == 1
+    assert response.data["results"][0]["id"] == artist.id
+
+
+def test_artist_detail(factories, superuser_api_client):
+    artist = factories["music.Artist"]()
+    url = reverse("api:v1:manage:library:artists-detail", kwargs={"pk": artist.pk})
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data["id"] == artist.id
+
+
+def test_artist_detail_stats(factories, superuser_api_client):
+    artist = factories["music.Artist"]()
+    url = reverse("api:v1:manage:library:artists-stats", kwargs={"pk": artist.pk})
+    response = superuser_api_client.get(url)
+    expected = {
+        "libraries": 0,
+        "uploads": 0,
+        "listenings": 0,
+        "playlists": 0,
+        "mutations": 0,
+        "track_favorites": 0,
+        "media_total_size": 0,
+        "media_downloaded_size": 0,
+    }
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+def test_artist_delete(factories, superuser_api_client):
+    artist = factories["music.Artist"]()
+    url = reverse("api:v1:manage:library:artists-detail", kwargs={"pk": artist.pk})
+    response = superuser_api_client.delete(url)
+
+    assert response.status_code == 204
+
+
+def test_album_list(factories, superuser_api_client, settings):
+    album = factories["music.Album"]()
+    factories["music.Album"]()
+    url = reverse("api:v1:manage:library:albums-list")
+    response = superuser_api_client.get(
+        url, {"q": 'artist:"{}"'.format(album.artist.name)}
+    )
+
+    assert response.status_code == 200
+
+    assert response.data["count"] == 1
+    assert response.data["results"][0]["id"] == album.id
+
+
+def test_album_detail(factories, superuser_api_client):
+    album = factories["music.Album"]()
+    url = reverse("api:v1:manage:library:albums-detail", kwargs={"pk": album.pk})
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data["id"] == album.id
+
+
+def test_album_detail_stats(factories, superuser_api_client):
+    album = factories["music.Album"]()
+    url = reverse("api:v1:manage:library:albums-stats", kwargs={"pk": album.pk})
+    response = superuser_api_client.get(url)
+    expected = {
+        "libraries": 0,
+        "uploads": 0,
+        "listenings": 0,
+        "playlists": 0,
+        "mutations": 0,
+        "track_favorites": 0,
+        "media_total_size": 0,
+        "media_downloaded_size": 0,
+    }
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+def test_album_delete(factories, superuser_api_client):
+    album = factories["music.Album"]()
+    url = reverse("api:v1:manage:library:albums-detail", kwargs={"pk": album.pk})
+    response = superuser_api_client.delete(url)
+
+    assert response.status_code == 204
+
+
+def test_track_list(factories, superuser_api_client, settings):
+    track = factories["music.Track"]()
+    url = reverse("api:v1:manage:library:tracks-list")
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+
+    assert response.data["count"] == 1
+    assert response.data["results"][0]["id"] == track.id
+
+
+def test_track_detail(factories, superuser_api_client):
+    track = factories["music.Track"]()
+    url = reverse("api:v1:manage:library:tracks-detail", kwargs={"pk": track.pk})
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data["id"] == track.id
+
+
+def test_track_detail_stats(factories, superuser_api_client):
+    track = factories["music.Track"]()
+    url = reverse("api:v1:manage:library:tracks-stats", kwargs={"pk": track.pk})
+    response = superuser_api_client.get(url)
+    expected = {
+        "libraries": 0,
+        "uploads": 0,
+        "listenings": 0,
+        "playlists": 0,
+        "mutations": 0,
+        "track_favorites": 0,
+        "media_total_size": 0,
+        "media_downloaded_size": 0,
+    }
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+def test_track_delete(factories, superuser_api_client):
+    track = factories["music.Track"]()
+    url = reverse("api:v1:manage:library:tracks-detail", kwargs={"pk": track.pk})
+    response = superuser_api_client.delete(url)
+
+    assert response.status_code == 204
+
+
+def test_library_list(factories, superuser_api_client, settings):
+    library = factories["music.Library"]()
+    url = reverse("api:v1:manage:library:libraries-list")
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+
+    assert response.data["count"] == 1
+    assert response.data["results"][0]["id"] == library.id
+
+
+def test_library_detail(factories, superuser_api_client):
+    library = factories["music.Library"]()
+    url = reverse(
+        "api:v1:manage:library:libraries-detail", kwargs={"uuid": library.uuid}
+    )
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data["id"] == library.id
+
+
+def test_library_detail_stats(factories, superuser_api_client):
+    library = factories["music.Library"]()
+    url = reverse(
+        "api:v1:manage:library:libraries-stats", kwargs={"uuid": library.uuid}
+    )
+    response = superuser_api_client.get(url)
+    expected = {
+        "uploads": 0,
+        "followers": 0,
+        "tracks": 0,
+        "albums": 0,
+        "artists": 0,
+        "media_total_size": 0,
+        "media_downloaded_size": 0,
+    }
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+def test_library_delete(factories, superuser_api_client):
+    library = factories["music.Library"]()
+    url = reverse(
+        "api:v1:manage:library:libraries-detail", kwargs={"uuid": library.uuid}
+    )
+    response = superuser_api_client.delete(url)
+
+    assert response.status_code == 204
+
+
+def test_upload_list(factories, superuser_api_client, settings):
+    upload = factories["music.Upload"]()
+    url = reverse("api:v1:manage:library:uploads-list")
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+
+    assert response.data["count"] == 1
+    assert response.data["results"][0]["id"] == upload.id
+
+
+def test_upload_detail(factories, superuser_api_client):
+    upload = factories["music.Upload"]()
+    url = reverse("api:v1:manage:library:uploads-detail", kwargs={"uuid": upload.uuid})
+    response = superuser_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data["id"] == upload.id
+
+
+def test_upload_delete(factories, superuser_api_client):
+    upload = factories["music.Upload"]()
+    url = reverse("api:v1:manage:library:uploads-detail", kwargs={"uuid": upload.uuid})
+    response = superuser_api_client.delete(url)
+
+    assert response.status_code == 204
diff --git a/api/tests/moderation/__init__.py b/api/tests/moderation/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/api/tests/moderation/test_filters.py b/api/tests/moderation/test_filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb1dab95a309cf5a8c001989e1a164ed30d9c2a2
--- /dev/null
+++ b/api/tests/moderation/test_filters.py
@@ -0,0 +1,68 @@
+from funkwhale_api.moderation import filters
+from funkwhale_api.music import models as music_models
+
+
+def test_hidden_defaults_to_true(factories, queryset_equal_list, mocker):
+    user = factories["users.User"]()
+    artist = factories["music.Artist"]()
+    hidden_artist = factories["music.Artist"]()
+    factories["moderation.UserFilter"](target_artist=hidden_artist, user=user)
+
+    class FS(filters.HiddenContentFilterSet):
+        class Meta:
+            hidden_content_fields_mapping = {"target_artist": ["pk"]}
+
+    filterset = FS(
+        data={},
+        queryset=music_models.Artist.objects.all(),
+        request=mocker.Mock(user=user),
+    )
+    assert filterset.data["hidden"] is False
+    queryset = filterset.filter_hidden_content(
+        music_models.Artist.objects.all(), "", False
+    )
+
+    assert queryset == [artist]
+
+
+def test_hidden_false(factories, queryset_equal_list, mocker):
+    user = factories["users.User"]()
+    factories["music.Artist"]()
+    hidden_artist = factories["music.Artist"]()
+    factories["moderation.UserFilter"](target_artist=hidden_artist, user=user)
+
+    class FS(filters.HiddenContentFilterSet):
+        class Meta:
+            hidden_content_fields_mapping = {"target_artist": ["pk"]}
+
+    filterset = FS(
+        data={},
+        queryset=music_models.Artist.objects.all(),
+        request=mocker.Mock(user=user),
+    )
+
+    queryset = filterset.filter_hidden_content(
+        music_models.Artist.objects.all(), "", True
+    )
+
+    assert queryset == [hidden_artist]
+
+
+def test_hidden_anonymous(factories, queryset_equal_list, mocker, anonymous_user):
+    artist = factories["music.Artist"]()
+
+    class FS(filters.HiddenContentFilterSet):
+        class Meta:
+            hidden_content_fields_mapping = {"target_artist": ["pk"]}
+
+    filterset = FS(
+        data={},
+        queryset=music_models.Artist.objects.all(),
+        request=mocker.Mock(user=anonymous_user),
+    )
+
+    queryset = filterset.filter_hidden_content(
+        music_models.Artist.objects.all(), "", True
+    )
+
+    assert queryset == [artist]
diff --git a/api/tests/moderation/test_serializers.py b/api/tests/moderation/test_serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..a38214143db36f97aa349f712681a3dab2fcbf1b
--- /dev/null
+++ b/api/tests/moderation/test_serializers.py
@@ -0,0 +1,30 @@
+from funkwhale_api.moderation import serializers
+
+
+def test_user_filter_serializer_repr(factories):
+    artist = factories["music.Artist"]()
+    content_filter = factories["moderation.UserFilter"](target_artist=artist)
+
+    expected = {
+        "uuid": str(content_filter.uuid),
+        "target": {"type": "artist", "id": artist.pk, "name": artist.name},
+        "creation_date": content_filter.creation_date.isoformat().replace(
+            "+00:00", "Z"
+        ),
+    }
+
+    serializer = serializers.UserFilterSerializer(content_filter)
+
+    assert serializer.data == expected
+
+
+def test_user_filter_serializer_save(factories):
+    artist = factories["music.Artist"]()
+    user = factories["users.User"]()
+    data = {"target": {"type": "artist", "id": artist.pk}}
+
+    serializer = serializers.UserFilterSerializer(data=data)
+    serializer.is_valid(raise_exception=True)
+    content_filter = serializer.save(user=user)
+
+    assert content_filter.target_artist == artist
diff --git a/api/tests/moderation/test_views.py b/api/tests/moderation/test_views.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d53f4565a315b84c40fccd7d8b6c226a6883a24
--- /dev/null
+++ b/api/tests/moderation/test_views.py
@@ -0,0 +1,24 @@
+from django.urls import reverse
+
+
+def test_restrict_to_own_filters(factories, logged_in_api_client):
+    cf = factories["moderation.UserFilter"](
+        for_artist=True, user=logged_in_api_client.user
+    )
+    factories["moderation.UserFilter"](for_artist=True)
+    url = reverse("api:v1:moderation:content-filters-list")
+    response = logged_in_api_client.get(url)
+    assert response.status_code == 200
+    assert response.data["count"] == 1
+    assert response.data["results"][0]["uuid"] == str(cf.uuid)
+
+
+def test_create_filter(factories, logged_in_api_client):
+    artist = factories["music.Artist"]()
+    url = reverse("api:v1:moderation:content-filters-list")
+    data = {"target": {"type": "artist", "id": artist.pk}}
+    response = logged_in_api_client.post(url, data, format="json")
+
+    cf = logged_in_api_client.user.content_filters.latest("id")
+    assert cf.target_artist == artist
+    assert response.status_code == 201
diff --git a/api/tests/music/test_commands.py b/api/tests/music/test_commands.py
index 38186dd7e92095715668f56ecf88bfc5c6659ad0..a08f1b10b8f9f90d0f3d8474ce7380bcf45594b7 100644
--- a/api/tests/music/test_commands.py
+++ b/api/tests/music/test_commands.py
@@ -1,6 +1,9 @@
 import os
+import pytest
 
+from funkwhale_api.music.management.commands import check_inplace_files
 from funkwhale_api.music.management.commands import fix_uploads
+from funkwhale_api.music.management.commands import prune_library
 
 DATA_DIR = os.path.dirname(os.path.abspath(__file__))
 
@@ -73,3 +76,110 @@ def test_fix_uploads_mimetype(factories, mocker):
 
     assert upload1.mimetype == "audio/mpeg"
     assert upload2.mimetype == "audio/something"
+
+
+def test_prune_library_dry_run(factories):
+    prunable = factories["music.Track"]()
+    not_prunable = factories["music.Track"]()
+    c = prune_library.Command()
+    options = {
+        "prune_artists": True,
+        "prune_albums": True,
+        "prune_tracks": True,
+        "exclude_favorites": False,
+        "exclude_listenings": False,
+        "exclude_playlists": False,
+        "dry_run": True,
+    }
+    c.handle(**options)
+
+    for t in [prunable, not_prunable]:
+        # nothing pruned, because dry run
+        t.refresh_from_db()
+
+
+def test_prune_library(factories, mocker):
+    prunable_track = factories["music.Track"]()
+    not_prunable_track = factories["music.Track"]()
+    prunable_tracks = prunable_track.__class__.objects.filter(pk=prunable_track.pk)
+    get_prunable_tracks = mocker.patch(
+        "funkwhale_api.music.tasks.get_prunable_tracks", return_value=prunable_tracks
+    )
+
+    prunable_album = factories["music.Album"]()
+    not_prunable_album = factories["music.Album"]()
+    prunable_albums = prunable_album.__class__.objects.filter(pk=prunable_album.pk)
+    get_prunable_albums = mocker.patch(
+        "funkwhale_api.music.tasks.get_prunable_albums", return_value=prunable_albums
+    )
+
+    prunable_artist = factories["music.Artist"]()
+    not_prunable_artist = factories["music.Artist"]()
+    prunable_artists = prunable_artist.__class__.objects.filter(pk=prunable_artist.pk)
+    get_prunable_artists = mocker.patch(
+        "funkwhale_api.music.tasks.get_prunable_artists", return_value=prunable_artists
+    )
+
+    c = prune_library.Command()
+    options = {
+        "exclude_favorites": mocker.Mock(),
+        "exclude_listenings": mocker.Mock(),
+        "exclude_playlists": mocker.Mock(),
+        "prune_artists": True,
+        "prune_albums": True,
+        "prune_tracks": True,
+        "dry_run": False,
+    }
+    c.handle(**options)
+
+    get_prunable_tracks.assert_called_once_with(
+        exclude_favorites=options["exclude_favorites"],
+        exclude_listenings=options["exclude_listenings"],
+        exclude_playlists=options["exclude_playlists"],
+    )
+    get_prunable_albums.assert_called_once()
+    get_prunable_artists.assert_called_once()
+
+    with pytest.raises(prunable_track.DoesNotExist):
+        prunable_track.refresh_from_db()
+
+    with pytest.raises(prunable_album.DoesNotExist):
+        prunable_album.refresh_from_db()
+
+    with pytest.raises(prunable_artist.DoesNotExist):
+        prunable_artist.refresh_from_db()
+
+    for o in [not_prunable_track, not_prunable_album, not_prunable_artist]:
+        o.refresh_from_db()
+
+
+def test_check_inplace_files_dry_run(factories, tmpfile):
+    prunable = factories["music.Upload"](source="file:///notfound", audio_file=None)
+    not_prunable = factories["music.Upload"](
+        source="file://{}".format(tmpfile.name), audio_file=None
+    )
+    c = check_inplace_files.Command()
+    c.handle(dry_run=True)
+
+    for u in [prunable, not_prunable]:
+        # nothing pruned, because dry run
+        u.refresh_from_db()
+
+
+def test_check_inplace_files_no_dry_run(factories, tmpfile):
+    prunable = factories["music.Upload"](source="file:///notfound", audio_file=None)
+    not_prunable = [
+        factories["music.Upload"](
+            source="file://{}".format(tmpfile.name), audio_file=None
+        ),
+        factories["music.Upload"](source="upload://"),
+        factories["music.Upload"](source="https://"),
+    ]
+    c = check_inplace_files.Command()
+    c.handle(dry_run=False)
+
+    with pytest.raises(prunable.DoesNotExist):
+        prunable.refresh_from_db()
+
+    for u in not_prunable:
+        u.refresh_from_db()
diff --git a/api/tests/music/test_filters.py b/api/tests/music/test_filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9abc4b2156b6a537471bb83ec583ecfb477faee
--- /dev/null
+++ b/api/tests/music/test_filters.py
@@ -0,0 +1,54 @@
+from funkwhale_api.music import filters
+from funkwhale_api.music import models
+
+
+def test_album_filter_hidden(factories, mocker, queryset_equal_list):
+    factories["music.Album"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_album = factories["music.Album"](artist=cf.target_artist)
+
+    qs = models.Album.objects.all()
+    filterset = filters.AlbumFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_album]
+
+
+def test_artist_filter_hidden(factories, mocker, queryset_equal_list):
+    factories["music.Artist"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_artist = cf.target_artist
+
+    qs = models.Artist.objects.all()
+    filterset = filters.ArtistFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_artist]
+
+
+def test_artist_filter_track_artist(factories, mocker, queryset_equal_list):
+    factories["music.Track"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_track = factories["music.Track"](artist=cf.target_artist)
+
+    qs = models.Track.objects.all()
+    filterset = filters.TrackFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_track]
+
+
+def test_artist_filter_track_album_artist(factories, mocker, queryset_equal_list):
+    factories["music.Track"]()
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    hidden_track = factories["music.Track"](album__artist=cf.target_artist)
+
+    qs = models.Track.objects.all()
+    filterset = filters.TrackFilter(
+        {"hidden": "true"}, request=mocker.Mock(user=cf.user), queryset=qs
+    )
+
+    assert filterset.qs == [hidden_track]
diff --git a/api/tests/music/test_lyrics.py b/api/tests/music/test_lyrics.py
deleted file mode 100644
index c8ce92b6a26418e9600e725b93bd1daa53ee72a4..0000000000000000000000000000000000000000
--- a/api/tests/music/test_lyrics.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from django.urls import reverse
-
-from funkwhale_api.music import lyrics as lyrics_utils
-from funkwhale_api.music import models, tasks
-
-
-def test_lyrics_tasks(lyricswiki_content, mocker, factories):
-    mocker.patch(
-        "funkwhale_api.music.lyrics._get_html", return_value=lyricswiki_content
-    )
-    lyrics = factories["music.Lyrics"](
-        url="http://lyrics.wikia.com/System_Of_A_Down:Chop_Suey!"
-    )
-
-    tasks.fetch_content(lyrics_id=lyrics.pk)
-    lyrics.refresh_from_db()
-    assert "Grab a brush and put on a little makeup" in lyrics.content
-
-
-def test_clean_content():
-    c = """<div class="lyricbox">Hello<br /><script>alert('hello');</script>Is it me you're looking for?<br /></div>"""
-    d = lyrics_utils.extract_content(c)
-    d = lyrics_utils.clean_content(d)
-
-    expected = """Hello
-Is it me you're looking for?
-"""
-    assert d == expected
-
-
-def test_markdown_rendering(factories):
-    content = """Hello
-Is it me you're looking for?"""
-
-    lyrics = factories["music.Lyrics"](content=content)
-
-    expected = "<p>Hello<br />\nIs it me you're looking for?</p>"
-    assert expected == lyrics.content_rendered
-
-
-def test_works_import_lyrics_if_any(
-    lyricswiki_content, works, tracks, mocker, factories, logged_in_client
-):
-    mocker.patch(
-        "funkwhale_api.musicbrainz.api.works.get",
-        return_value=works["get"]["chop_suey"],
-    )
-    mocker.patch(
-        "funkwhale_api.musicbrainz.api.recordings.get",
-        return_value=tracks["get"]["chop_suey"],
-    )
-    mocker.patch(
-        "funkwhale_api.music.lyrics._get_html", return_value=lyricswiki_content
-    )
-    track = factories["music.Track"](
-        work=None, mbid="07ca77cf-f513-4e9c-b190-d7e24bbad448"
-    )
-
-    url = reverse("api:v1:tracks-lyrics", kwargs={"pk": track.pk})
-    response = logged_in_client.get(url)
-
-    assert response.status_code == 200
-
-    track.refresh_from_db()
-    lyrics = models.Lyrics.objects.latest("id")
-    work = models.Work.objects.latest("id")
-
-    assert track.work == work
-    assert lyrics.work == work
diff --git a/api/tests/music/test_metadata.py b/api/tests/music/test_metadata.py
index f91f7545b89195a99b0072552cfa8ff164d6ca25..1656ece49701159c4215e82c95d384b052925d35 100644
--- a/api/tests/music/test_metadata.py
+++ b/api/tests/music/test_metadata.py
@@ -11,45 +11,22 @@ from funkwhale_api.music import metadata
 DATA_DIR = os.path.dirname(os.path.abspath(__file__))
 
 
-def test_get_all_metadata_at_once():
-    path = os.path.join(DATA_DIR, "test.ogg")
-    data = metadata.Metadata(path)
-
-    expected = {
-        "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
-        "artist": "Edvard Grieg",
-        "album_artist": "Edvard Grieg",
-        "album": "Peer Gynt Suite no. 1, op. 46",
-        "date": datetime.date(2012, 8, 15),
-        "track_number": 1,
-        "disc_number": 1,
-        "musicbrainz_albumid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
-        "musicbrainz_recordingid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
-        "musicbrainz_artistid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
-        "musicbrainz_albumartistid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
-        "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
-        "copyright": "Someone",
-    }
-
-    assert data.all() == expected
-
-
 @pytest.mark.parametrize(
     "field,value",
     [
         ("title", "Peer Gynt Suite no. 1, op. 46: I. Morning"),
         ("artist", "Edvard Grieg"),
-        ("album_artist", "Edvard Grieg"),
+        ("album_artist", "Edvard Grieg; Musopen Symphony Orchestra"),
         ("album", "Peer Gynt Suite no. 1, op. 46"),
-        ("date", datetime.date(2012, 8, 15)),
-        ("track_number", 1),
-        ("disc_number", 1),
-        ("musicbrainz_albumid", uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75")),
-        ("musicbrainz_recordingid", uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656")),
-        ("musicbrainz_artistid", uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823")),
+        ("date", "2012-08-15"),
+        ("position", "1"),
+        ("disc_number", "1"),
+        ("musicbrainz_albumid", "a766da8b-8336-47aa-a3ee-371cc41ccc75"),
+        ("mbid", "bd21ac48-46d8-4e78-925f-d9cc2a294656"),
+        ("musicbrainz_artistid", "013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
         (
             "musicbrainz_albumartistid",
-            uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+            "013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
         ),
         ("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
         ("copyright", "Someone"),
@@ -62,22 +39,44 @@ def test_can_get_metadata_from_ogg_file(field, value):
     assert data.get(field) == value
 
 
+def test_can_get_metadata_all():
+    path = os.path.join(DATA_DIR, "test.ogg")
+    data = metadata.Metadata(path)
+
+    expected = {
+        "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+        "artist": "Edvard Grieg",
+        "album_artist": "Edvard Grieg; Musopen Symphony Orchestra",
+        "album": "Peer Gynt Suite no. 1, op. 46",
+        "date": "2012-08-15",
+        "position": "1",
+        "disc_number": "1",
+        "musicbrainz_albumid": "a766da8b-8336-47aa-a3ee-371cc41ccc75",
+        "mbid": "bd21ac48-46d8-4e78-925f-d9cc2a294656",
+        "musicbrainz_artistid": "013c8e5b-d72a-4cd3-8dee-6c64d6125823",
+        "musicbrainz_albumartistid": "013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
+        "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
+        "copyright": "Someone",
+    }
+    assert data.all() == expected
+
+
 @pytest.mark.parametrize(
     "field,value",
     [
         ("title", "Peer Gynt Suite no. 1, op. 46: I. Morning"),
         ("artist", "Edvard Grieg"),
-        ("album_artist", "Edvard Grieg"),
+        ("album_artist", "Edvard Grieg; Musopen Symphony Orchestra"),
         ("album", "Peer Gynt Suite no. 1, op. 46"),
-        ("date", datetime.date(2012, 8, 15)),
-        ("track_number", 1),
-        ("disc_number", 1),
-        ("musicbrainz_albumid", uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75")),
-        ("musicbrainz_recordingid", uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656")),
-        ("musicbrainz_artistid", uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823")),
+        ("date", "2012-08-15"),
+        ("position", "1"),
+        ("disc_number", "1"),
+        ("musicbrainz_albumid", "a766da8b-8336-47aa-a3ee-371cc41ccc75"),
+        ("mbid", "bd21ac48-46d8-4e78-925f-d9cc2a294656"),
+        ("musicbrainz_artistid", "013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
         (
             "musicbrainz_albumartistid",
-            uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+            "013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
         ),
         ("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
         ("copyright", "Someone"),
@@ -97,16 +96,13 @@ def test_can_get_metadata_from_opus_file(field, value):
         ("artist", "Die Toten Hosen"),
         ("album_artist", "Die Toten Hosen"),
         ("album", "Ballast der Republik"),
-        ("date", datetime.date(2012, 5, 4)),
-        ("track_number", 1),
-        ("disc_number", 1),
-        ("musicbrainz_albumid", uuid.UUID("1f0441ad-e609-446d-b355-809c445773cf")),
-        ("musicbrainz_recordingid", uuid.UUID("124d0150-8627-46bc-bc14-789a3bc960c8")),
-        ("musicbrainz_artistid", uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1")),
-        (
-            "musicbrainz_albumartistid",
-            uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
-        ),
+        ("date", "2012-05-04"),
+        ("position", "1/16"),
+        ("disc_number", "1/2"),
+        ("musicbrainz_albumid", "1f0441ad-e609-446d-b355-809c445773cf"),
+        ("mbid", "124d0150-8627-46bc-bc14-789a3bc960c8"),
+        ("musicbrainz_artistid", "c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
+        ("musicbrainz_albumartistid", "c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
         # somehow, I cannot successfully create an ogg theora file
         # with the proper license field
         # ("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
@@ -126,16 +122,13 @@ def test_can_get_metadata_from_ogg_theora_file(field, value):
         ("artist", "Binärpilot"),
         ("album_artist", "Binärpilot"),
         ("album", "You Can't Stop Da Funk"),
-        ("date", datetime.date(2006, 2, 7)),
-        ("track_number", 2),
-        ("disc_number", 1),
-        ("musicbrainz_albumid", uuid.UUID("ce40cdb1-a562-4fd8-a269-9269f98d4124")),
-        ("musicbrainz_recordingid", uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb")),
-        ("musicbrainz_artistid", uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13")),
-        (
-            "musicbrainz_albumartistid",
-            uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
-        ),
+        ("date", "2006-02-07"),
+        ("position", "2/4"),
+        ("disc_number", "1/1"),
+        ("musicbrainz_albumid", "ce40cdb1-a562-4fd8-a269-9269f98d4124"),
+        ("mbid", "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
+        ("musicbrainz_artistid", "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
+        ("musicbrainz_albumartistid", "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
         ("license", "https://creativecommons.org/licenses/by-nc-nd/2.5/"),
         ("copyright", "Someone"),
     ],
@@ -144,7 +137,7 @@ def test_can_get_metadata_from_id3_mp3_file(field, value):
     path = os.path.join(DATA_DIR, "test.mp3")
     data = metadata.Metadata(path)
 
-    assert data.get(field) == value
+    assert str(data.get(field)) == value
 
 
 @pytest.mark.parametrize(
@@ -170,16 +163,13 @@ def test_can_get_pictures(name):
         ("artist", "Nine Inch Nails"),
         ("album_artist", "Nine Inch Nails"),
         ("album", "The Slip"),
-        ("date", datetime.date(2008, 5, 5)),
-        ("track_number", 1),
-        ("disc_number", 1),
-        ("musicbrainz_albumid", uuid.UUID("12b57d46-a192-499e-a91f-7da66790a1c1")),
-        ("musicbrainz_recordingid", uuid.UUID("30f3f33e-8d0c-4e69-8539-cbd701d18f28")),
-        ("musicbrainz_artistid", uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da")),
-        (
-            "musicbrainz_albumartistid",
-            uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
-        ),
+        ("date", "2008-05-05"),
+        ("position", "1"),
+        ("disc_number", "1"),
+        ("musicbrainz_albumid", "12b57d46-a192-499e-a91f-7da66790a1c1"),
+        ("mbid", "30f3f33e-8d0c-4e69-8539-cbd701d18f28"),
+        ("musicbrainz_artistid", "b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
+        ("musicbrainz_albumartistid", "b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
         ("license", "http://creativecommons.org/licenses/by-nc-sa/3.0/us/"),
         ("copyright", "2008 nin"),
     ],
@@ -199,54 +189,18 @@ def test_can_get_metadata_from_flac_file_not_crash_if_empty():
         data.get("test")
 
 
-@pytest.mark.parametrize(
-    "field_name",
-    [
-        "musicbrainz_artistid",
-        "musicbrainz_albumid",
-        "musicbrainz_recordingid",
-        "musicbrainz_albumartistid",
-    ],
-)
-def test_mbid_clean_keeps_only_first(field_name):
-    u1 = str(uuid.uuid4())
-    u2 = str(uuid.uuid4())
-    field = metadata.VALIDATION[field_name]
-    result = field.to_python("/".join([u1, u2]))
-
-    assert str(result) == u1
-
-
 @pytest.mark.parametrize(
     "raw,expected",
     [
         ("2017", datetime.date(2017, 1, 1)),
         ("2017-12-31", datetime.date(2017, 12, 31)),
         ("2017-14-01 01:32", datetime.date(2017, 1, 14)),  # deezer format
+        ("2017-02", datetime.date(2017, 1, 1)),  # weird format that exists
+        ("nonsense", None),
     ],
 )
 def test_date_parsing(raw, expected):
-    assert metadata.get_date(raw) == expected
-
-
-def test_date_parsing_failure():
-    with pytest.raises(metadata.ParseError):
-        metadata.get_date("noop")
-
-
-def test_metadata_all_ignore_parse_errors_true(mocker):
-    path = os.path.join(DATA_DIR, "sample.flac")
-    data = metadata.Metadata(path)
-    mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure"))
-    assert data.all()["date"] is None
-
-
-def test_metadata_all_ignore_parse_errors_false(mocker):
-    path = os.path.join(DATA_DIR, "sample.flac")
-    data = metadata.Metadata(path)
-    mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure"))
-    with pytest.raises(metadata.ParseError):
-        data.all(ignore_parse_errors=False)
+    assert metadata.PermissiveDateField().to_internal_value(raw) == expected
 
 
 def test_metadata_fallback_ogg_theora(mocker):
@@ -264,3 +218,337 @@ def test_metadata_fallback_ogg_theora(mocker):
     assert data.get("pictures", "default") == expected_result
 
     fallback_get.assert_called_once_with("pictures", "default")
+
+
+@pytest.mark.parametrize(
+    "path, expected",
+    [
+        (
+            "test.mp3",
+            {
+                "title": "Bend",
+                "artists": [
+                    {
+                        "name": "Binärpilot",
+                        "mbid": uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
+                    }
+                ],
+                "album": {
+                    "title": "You Can't Stop Da Funk",
+                    "mbid": uuid.UUID("ce40cdb1-a562-4fd8-a269-9269f98d4124"),
+                    "release_date": datetime.date(2006, 2, 7),
+                    "artists": [
+                        {
+                            "name": "Binärpilot",
+                            "mbid": uuid.UUID("9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"),
+                        }
+                    ],
+                },
+                "position": 2,
+                "disc_number": 1,
+                "mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
+                "license": "https://creativecommons.org/licenses/by-nc-nd/2.5/",
+                "copyright": "Someone",
+            },
+        ),
+        (
+            "test.ogg",
+            {
+                "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+                "artists": [
+                    {
+                        "name": "Edvard Grieg",
+                        "mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+                    }
+                ],
+                "album": {
+                    "title": "Peer Gynt Suite no. 1, op. 46",
+                    "mbid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
+                    "release_date": datetime.date(2012, 8, 15),
+                    "artists": [
+                        {
+                            "name": "Edvard Grieg",
+                            "mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+                        },
+                        {
+                            "name": "Musopen Symphony Orchestra",
+                            "mbid": uuid.UUID("5b4d7d2d-36df-4b38-95e3-a964234f520f"),
+                        },
+                    ],
+                },
+                "position": 1,
+                "disc_number": 1,
+                "mbid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
+                "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
+                "copyright": "Someone",
+            },
+        ),
+        (
+            "test.opus",
+            {
+                "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+                "artists": [
+                    {
+                        "name": "Edvard Grieg",
+                        "mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+                    }
+                ],
+                "album": {
+                    "title": "Peer Gynt Suite no. 1, op. 46",
+                    "mbid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
+                    "release_date": datetime.date(2012, 8, 15),
+                    "artists": [
+                        {
+                            "name": "Edvard Grieg",
+                            "mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+                        },
+                        {
+                            "name": "Musopen Symphony Orchestra",
+                            "mbid": uuid.UUID("5b4d7d2d-36df-4b38-95e3-a964234f520f"),
+                        },
+                    ],
+                },
+                "position": 1,
+                "disc_number": 1,
+                "mbid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
+                "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
+                "copyright": "Someone",
+            },
+        ),
+        (
+            "test_theora.ogg",
+            {
+                "title": "Drei Kreuze (dass wir hier sind)",
+                "artists": [
+                    {
+                        "name": "Die Toten Hosen",
+                        "mbid": uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
+                    }
+                ],
+                "album": {
+                    "title": "Ballast der Republik",
+                    "mbid": uuid.UUID("1f0441ad-e609-446d-b355-809c445773cf"),
+                    "release_date": datetime.date(2012, 5, 4),
+                    "artists": [
+                        {
+                            "name": "Die Toten Hosen",
+                            "mbid": uuid.UUID("c3bc80a6-1f4a-4e17-8cf0-6b1efe8302f1"),
+                        }
+                    ],
+                },
+                "position": 1,
+                "disc_number": 1,
+                "mbid": uuid.UUID("124d0150-8627-46bc-bc14-789a3bc960c8"),
+                # somehow, I cannot successfully create an ogg theora file
+                # with the proper license field
+                # ("license", "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/"),
+                "copyright": "â„— 2012 JKP GmbH & Co. KG",
+            },
+        ),
+        (
+            "sample.flac",
+            {
+                "title": "999,999",
+                "artists": [
+                    {
+                        "name": "Nine Inch Nails",
+                        "mbid": uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
+                    }
+                ],
+                "album": {
+                    "title": "The Slip",
+                    "mbid": uuid.UUID("12b57d46-a192-499e-a91f-7da66790a1c1"),
+                    "release_date": datetime.date(2008, 5, 5),
+                    "artists": [
+                        {
+                            "name": "Nine Inch Nails",
+                            "mbid": uuid.UUID("b7ffd2af-418f-4be2-bdd1-22f8b48613da"),
+                        }
+                    ],
+                },
+                "position": 1,
+                "disc_number": 1,
+                "mbid": uuid.UUID("30f3f33e-8d0c-4e69-8539-cbd701d18f28"),
+                "license": "http://creativecommons.org/licenses/by-nc-sa/3.0/us/",
+                "copyright": "2008 nin",
+            },
+        ),
+    ],
+)
+def test_track_metadata_serializer(path, expected, mocker):
+    path = os.path.join(DATA_DIR, path)
+    data = metadata.Metadata(path)
+    get_picture = mocker.patch.object(data, "get_picture")
+    expected["cover_data"] = get_picture.return_value
+
+    serializer = metadata.TrackMetadataSerializer(data=data)
+    assert serializer.is_valid(raise_exception=True) is True
+    assert serializer.validated_data == expected
+
+    get_picture.assert_called_once_with("cover_front", "other")
+
+
+@pytest.mark.parametrize(
+    "raw, expected",
+    [
+        (
+            {
+                "names": "Hello; World",
+                "mbids": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb; f269d497-1cc0-4ae4-a0c4-157ec7d73fcd ",
+            },
+            [
+                {
+                    "name": "Hello",
+                    "mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
+                },
+                {
+                    "name": "World",
+                    "mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"),
+                },
+            ],
+        ),
+        (
+            {
+                "names": "Hello; World; Foo",
+                "mbids": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb; f269d497-1cc0-4ae4-a0c4-157ec7d73fcd ",
+            },
+            [
+                {
+                    "name": "Hello",
+                    "mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcb"),
+                },
+                {
+                    "name": "World",
+                    "mbid": uuid.UUID("f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"),
+                },
+                {"name": "Foo", "mbid": None},
+            ],
+        ),
+    ],
+)
+def test_artists_cleaning(raw, expected):
+    field = metadata.ArtistField()
+    assert field.to_internal_value(raw) == expected
+
+
+@pytest.mark.parametrize(
+    "data, errored_field",
+    [
+        ({"name": "Hello", "mbid": "wrong-uuid"}, "mbid"),  # wrong uuid
+        ({"name": "", "mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"}, "name"),
+    ],
+)
+def test_artist_serializer_validation(data, errored_field):
+    serializer = metadata.ArtistSerializer(data=data)
+    assert serializer.is_valid() is False
+
+    assert len(serializer.errors) == 1
+    assert errored_field in serializer.errors
+
+
+@pytest.mark.parametrize(
+    "data, errored_field",
+    [
+        ({"title": "Hello", "mbid": "wrong"}, "mbid"),  # wrong uuid
+        (
+            {"title": "", "mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcd"},
+            "title",
+        ),  # empty title
+    ],
+)
+def test_album_serializer_validation(data, errored_field):
+    serializer = metadata.AlbumSerializer(data=data)
+    assert serializer.is_valid() is False
+
+    assert len(serializer.errors) == 1
+    assert errored_field in serializer.errors
+
+
+def test_fake_metadata_with_serializer():
+    data = {
+        "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+        "artist": "Edvard Grieg",
+        "album_artist": "Edvard Grieg; Musopen Symphony Orchestra",
+        "album": "Peer Gynt Suite no. 1, op. 46",
+        "date": "2012-08-15",
+        "position": "1",
+        "disc_number": "1",
+        "musicbrainz_albumid": "a766da8b-8336-47aa-a3ee-371cc41ccc75",
+        "mbid": "bd21ac48-46d8-4e78-925f-d9cc2a294656",
+        "musicbrainz_artistid": "013c8e5b-d72a-4cd3-8dee-6c64d6125823",
+        "musicbrainz_albumartistid": "013c8e5b-d72a-4cd3-8dee-6c64d6125823;5b4d7d2d-36df-4b38-95e3-a964234f520f",
+        "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
+        "copyright": "Someone",
+    }
+
+    expected = {
+        "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+        "artists": [
+            {
+                "name": "Edvard Grieg",
+                "mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+            }
+        ],
+        "album": {
+            "title": "Peer Gynt Suite no. 1, op. 46",
+            "mbid": uuid.UUID("a766da8b-8336-47aa-a3ee-371cc41ccc75"),
+            "release_date": datetime.date(2012, 8, 15),
+            "artists": [
+                {
+                    "name": "Edvard Grieg",
+                    "mbid": uuid.UUID("013c8e5b-d72a-4cd3-8dee-6c64d6125823"),
+                },
+                {
+                    "name": "Musopen Symphony Orchestra",
+                    "mbid": uuid.UUID("5b4d7d2d-36df-4b38-95e3-a964234f520f"),
+                },
+            ],
+        },
+        "position": 1,
+        "disc_number": 1,
+        "mbid": uuid.UUID("bd21ac48-46d8-4e78-925f-d9cc2a294656"),
+        "license": "Dummy license: http://creativecommons.org/licenses/by-sa/4.0/",
+        "copyright": "Someone",
+        "cover_data": None,
+    }
+    serializer = metadata.TrackMetadataSerializer(data=metadata.FakeMetadata(data))
+    assert serializer.is_valid(raise_exception=True) is True
+    assert serializer.validated_data == expected
+
+
+def test_serializer_album_artist_missing():
+    data = {
+        "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+        "artist": "Edvard Grieg",
+        "album": "Peer Gynt Suite no. 1, op. 46",
+    }
+
+    expected = {
+        "title": "Peer Gynt Suite no. 1, op. 46: I. Morning",
+        "artists": [{"name": "Edvard Grieg", "mbid": None}],
+        "album": {
+            "title": "Peer Gynt Suite no. 1, op. 46",
+            "mbid": None,
+            "release_date": None,
+            "artists": [],
+        },
+        "cover_data": None,
+    }
+    serializer = metadata.TrackMetadataSerializer(data=metadata.FakeMetadata(data))
+    assert serializer.is_valid(raise_exception=True) is True
+    assert serializer.validated_data == expected
+
+
+def test_artist_field_featuring():
+    data = {
+        "artist": "Santana feat. Chris Cornell",
+        # here is the tricky bit, note the slash
+        "musicbrainz_artistid": "9a3bf45c-347d-4630-894d-7cf3e8e0b632/cbf9738d-8f81-4a92-bc64-ede09341652d",
+    }
+
+    expected = [{"name": "Santana feat. Chris Cornell", "mbid": None}]
+
+    field = metadata.ArtistField()
+    value = field.get_value(data)
+
+    assert field.to_internal_value(value) == expected
diff --git a/api/tests/music/test_models.py b/api/tests/music/test_models.py
index ab32579b7e0db29c5a77843161715a919e9a45c3..5aa29b3cc4519d0c5158301d521a3550e2d56e62 100644
--- a/api/tests/music/test_models.py
+++ b/api/tests/music/test_models.py
@@ -522,3 +522,35 @@ def test_track_order_for_album(factories):
     t4 = factories["music.Track"](album=album, position=2, disc_number=2)
 
     assert list(models.Track.objects.order_for_album()) == [t1, t3, t2, t4]
+
+
+@pytest.mark.parametrize("factory", ["music.Artist", "music.Album", "music.Track"])
+def test_queryset_local_entities(factories, settings, factory):
+    settings.FEDERATION_HOSTNAME = "test.com"
+    obj1 = factories[factory](fid="http://test.com/1")
+    obj2 = factories[factory](fid="https://test.com/2")
+    factories[factory](fid="https://test.coma/3")
+    factories[factory](fid="https://noope/3")
+
+    assert list(obj1.__class__.objects.local().order_by("id")) == [obj1, obj2]
+
+
+@pytest.mark.parametrize(
+    "federation_hostname, fid, expected",
+    [
+        ("test.domain", "http://test.domain/", True),
+        ("test.domain", None, True),
+        ("test.domain", "https://test.domain/", True),
+        ("test.otherdomain", "http://test.domain/", False),
+    ],
+)
+def test_api_model_mixin_is_local(federation_hostname, fid, expected, settings):
+    settings.FEDERATION_HOSTNAME = federation_hostname
+    obj = models.Track(fid=fid)
+    assert obj.is_local is expected
+
+
+def test_api_model_mixin_domain_name():
+    obj = models.Track(fid="https://test.domain:543/something")
+
+    assert obj.domain_name == "test.domain"
diff --git a/api/tests/music/test_music.py b/api/tests/music/test_music.py
index ab5853f14d2262c97db146da29c5c0b8406f33a2..10d281071a8c885cb52031f68b96b6b6120ce5c4 100644
--- a/api/tests/music/test_music.py
+++ b/api/tests/music/test_music.py
@@ -1,7 +1,5 @@
 import datetime
 
-import pytest
-
 from funkwhale_api.federation import utils as federation_utils
 from funkwhale_api.music import models
 
@@ -40,8 +38,6 @@ def test_can_create_album_from_api(artists, albums, mocker, db):
 
     assert album.mbid, data["id"]
     assert album.title, "Hypnotize"
-    with pytest.raises(ValueError):
-        assert album.cover.path is not None
     assert album.release_date, datetime.date(2005, 1, 1)
     assert album.artist.name, "System of a Down"
     assert album.artist.mbid, data["artist-credit"][0]["artist"]["id"]
diff --git a/api/tests/music/test_mutations.py b/api/tests/music/test_mutations.py
new file mode 100644
index 0000000000000000000000000000000000000000..be3fb0d76cf831d026e414131b82258e9b1a11db
--- /dev/null
+++ b/api/tests/music/test_mutations.py
@@ -0,0 +1,119 @@
+import datetime
+import pytest
+
+from funkwhale_api.music import licenses
+
+
+@pytest.mark.parametrize(
+    "field, old_value, new_value, expected", [("name", "foo", "bar", "bar")]
+)
+def test_artist_mutation(field, old_value, new_value, expected, factories, now, mocker):
+    dispatch = mocker.patch("funkwhale_api.federation.routes.outbox.dispatch")
+    artist = factories["music.Artist"](**{field: old_value})
+    mutation = factories["common.Mutation"](
+        type="update", target=artist, payload={field: new_value}
+    )
+    mutation.apply()
+    artist.refresh_from_db()
+
+    assert getattr(artist, field) == expected
+    dispatch.assert_called_once_with(
+        {"type": "Update", "object": {"type": "Artist"}}, context={"artist": artist}
+    )
+
+
+@pytest.mark.parametrize(
+    "field, old_value, new_value, expected",
+    [
+        ("title", "foo", "bar", "bar"),
+        (
+            "release_date",
+            datetime.date(2016, 1, 1),
+            "2018-02-01",
+            datetime.date(2018, 2, 1),
+        ),
+    ],
+)
+def test_album_mutation(field, old_value, new_value, expected, factories, now, mocker):
+    dispatch = mocker.patch("funkwhale_api.federation.routes.outbox.dispatch")
+    album = factories["music.Album"](**{field: old_value})
+    mutation = factories["common.Mutation"](
+        type="update", target=album, payload={field: new_value}
+    )
+    mutation.apply()
+    album.refresh_from_db()
+
+    assert getattr(album, field) == expected
+    dispatch.assert_called_once_with(
+        {"type": "Update", "object": {"type": "Album"}}, context={"album": album}
+    )
+
+
+def test_track_license_mutation(factories, now):
+    track = factories["music.Track"](license=None)
+    mutation = factories["common.Mutation"](
+        type="update", target=track, payload={"license": "cc-by-sa-4.0"}
+    )
+    licenses.load(licenses.LICENSES)
+    mutation.apply()
+    track.refresh_from_db()
+
+    assert track.license.code == "cc-by-sa-4.0"
+
+
+def test_track_null_license_mutation(factories, now):
+    track = factories["music.Track"](license="cc-by-sa-4.0")
+    mutation = factories["common.Mutation"](
+        type="update", target=track, payload={"license": None}
+    )
+    licenses.load(licenses.LICENSES)
+    mutation.apply()
+    track.refresh_from_db()
+
+    assert track.license is None
+
+
+def test_track_title_mutation(factories, now):
+    track = factories["music.Track"](title="foo")
+    mutation = factories["common.Mutation"](
+        type="update", target=track, payload={"title": "bar"}
+    )
+    mutation.apply()
+    track.refresh_from_db()
+
+    assert track.title == "bar"
+
+
+def test_track_copyright_mutation(factories, now):
+    track = factories["music.Track"](copyright="foo")
+    mutation = factories["common.Mutation"](
+        type="update", target=track, payload={"copyright": "bar"}
+    )
+    mutation.apply()
+    track.refresh_from_db()
+
+    assert track.copyright == "bar"
+
+
+def test_track_position_mutation(factories):
+    track = factories["music.Track"](position=4)
+    mutation = factories["common.Mutation"](
+        type="update", target=track, payload={"position": 12}
+    )
+    mutation.apply()
+    track.refresh_from_db()
+
+    assert track.position == 12
+
+
+def test_track_mutation_apply_outbox(factories, mocker):
+    dispatch = mocker.patch("funkwhale_api.federation.routes.outbox.dispatch")
+    track = factories["music.Track"](position=4)
+    mutation = factories["common.Mutation"](
+        type="update", target=track, payload={"position": 12}
+    )
+    mutation.apply()
+
+    dispatch.assert_called_once_with(
+        {"type": "Update", "object": {"type": "Track"}}, context={"track": track}
+    )
diff --git a/api/tests/music/test_serializers.py b/api/tests/music/test_serializers.py
index 155f998904dccadcf2915ab3890767d34eb33be0..5f9b7d9d151035a78396ac3e4e3d91d30884c298 100644
--- a/api/tests/music/test_serializers.py
+++ b/api/tests/music/test_serializers.py
@@ -34,6 +34,7 @@ def test_artist_album_serializer(factories, to_api_date):
     album = album.__class__.objects.with_tracks_count().get(pk=album.pk)
     expected = {
         "id": album.id,
+        "fid": album.fid,
         "mbid": str(album.mbid),
         "title": album.title,
         "artist": album.artist.id,
@@ -47,6 +48,7 @@ def test_artist_album_serializer(factories, to_api_date):
             "small_square_crop": album.cover.crop["50x50"].url,
         },
         "release_date": to_api_date(album.release_date),
+        "is_local": album.is_local,
     }
     serializer = serializers.ArtistAlbumSerializer(album)
 
@@ -61,8 +63,10 @@ def test_artist_with_albums_serializer(factories, to_api_date):
 
     expected = {
         "id": artist.id,
+        "fid": artist.fid,
         "mbid": str(artist.mbid),
         "name": artist.name,
+        "is_local": artist.is_local,
         "creation_date": to_api_date(artist.creation_date),
         "albums": [serializers.ArtistAlbumSerializer(album).data],
     }
@@ -79,6 +83,7 @@ def test_album_track_serializer(factories, to_api_date):
 
     expected = {
         "id": track.id,
+        "fid": track.fid,
         "artist": serializers.ArtistSimpleSerializer(track.artist).data,
         "album": track.album.id,
         "mbid": str(track.mbid),
@@ -91,6 +96,7 @@ def test_album_track_serializer(factories, to_api_date):
         "duration": None,
         "license": track.license.code,
         "copyright": track.copyright,
+        "is_local": track.is_local,
     }
     serializer = serializers.AlbumTrackSerializer(track)
     assert serializer.data == expected
@@ -154,6 +160,7 @@ def test_album_serializer(factories, to_api_date):
     album = track1.album
     expected = {
         "id": album.id,
+        "fid": album.fid,
         "mbid": str(album.mbid),
         "title": album.title,
         "artist": serializers.ArtistSimpleSerializer(album.artist).data,
@@ -167,6 +174,7 @@ def test_album_serializer(factories, to_api_date):
         },
         "release_date": to_api_date(album.release_date),
         "tracks": serializers.AlbumTrackSerializer([track2, track1], many=True).data,
+        "is_local": album.is_local,
     }
     serializer = serializers.AlbumSerializer(album)
 
@@ -181,6 +189,7 @@ def test_track_serializer(factories, to_api_date):
     setattr(track, "playable_uploads", [upload])
     expected = {
         "id": track.id,
+        "fid": track.fid,
         "artist": serializers.ArtistSimpleSerializer(track.artist).data,
         "album": serializers.TrackAlbumSerializer(track.album).data,
         "mbid": str(track.mbid),
@@ -189,10 +198,10 @@ def test_track_serializer(factories, to_api_date):
         "disc_number": track.disc_number,
         "uploads": [serializers.TrackUploadSerializer(upload).data],
         "creation_date": to_api_date(track.creation_date),
-        "lyrics": track.get_lyrics_url(),
         "listen_url": track.listen_url,
         "license": upload.track.license.code,
         "copyright": upload.track.copyright,
+        "is_local": upload.track.is_local,
     }
     serializer = serializers.TrackSerializer(track)
     assert serializer.data == expected
diff --git a/api/tests/music/test_spa_views.py b/api/tests/music/test_spa_views.py
index 7761e313f33747c0c30f5ad62ed1992b2d376566..b9397009c669575c749f2605f3f3096ee0342ee8 100644
--- a/api/tests/music/test_spa_views.py
+++ b/api/tests/music/test_spa_views.py
@@ -3,6 +3,7 @@ import urllib.parse
 from django.urls import reverse
 
 from funkwhale_api.common import utils
+from funkwhale_api.music import serializers
 
 
 def test_library_track(spa_html, no_api_auth, client, factories, settings):
@@ -68,6 +69,14 @@ def test_library_track(spa_html, no_api_auth, client, factories, settings):
                 )
             ),
         },
+        {"tag": "meta", "property": "twitter:card", "content": "player"},
+        {
+            "tag": "meta",
+            "property": "twitter:player",
+            "content": serializers.get_embed_url("track", id=track.id),
+        },
+        {"tag": "meta", "property": "twitter:player:width", "content": "600"},
+        {"tag": "meta", "property": "twitter:player:height", "content": "400"},
     ]
 
     metas = utils.parse_meta(response.content.decode())
@@ -122,6 +131,14 @@ def test_library_album(spa_html, no_api_auth, client, factories, settings):
                 )
             ),
         },
+        {"tag": "meta", "property": "twitter:card", "content": "player"},
+        {
+            "tag": "meta",
+            "property": "twitter:player",
+            "content": serializers.get_embed_url("album", id=album.id),
+        },
+        {"tag": "meta", "property": "twitter:player:width", "content": "600"},
+        {"tag": "meta", "property": "twitter:player:height", "content": "400"},
     ]
 
     metas = utils.parse_meta(response.content.decode())
@@ -132,6 +149,7 @@ def test_library_album(spa_html, no_api_auth, client, factories, settings):
 
 def test_library_artist(spa_html, no_api_auth, client, factories, settings):
     album = factories["music.Album"]()
+    factories["music.Upload"](playable=True, track__album=album)
     artist = album.artist
     url = "/library/artists/{}".format(artist.pk)
 
@@ -152,6 +170,25 @@ def test_library_artist(spa_html, no_api_auth, client, factories, settings):
                 settings.FUNKWHALE_URL, album.cover.crop["400x400"].url
             ),
         },
+        {
+            "tag": "link",
+            "rel": "alternate",
+            "type": "application/json+oembed",
+            "href": (
+                utils.join_url(settings.FUNKWHALE_URL, reverse("api:v1:oembed"))
+                + "?format=json&url={}".format(
+                    urllib.parse.quote_plus(utils.join_url(settings.FUNKWHALE_URL, url))
+                )
+            ),
+        },
+        {"tag": "meta", "property": "twitter:card", "content": "player"},
+        {
+            "tag": "meta",
+            "property": "twitter:player",
+            "content": serializers.get_embed_url("artist", id=artist.id),
+        },
+        {"tag": "meta", "property": "twitter:player:width", "content": "600"},
+        {"tag": "meta", "property": "twitter:player:height", "content": "400"},
     ]
 
     metas = utils.parse_meta(response.content.decode())
diff --git a/api/tests/music/test_tasks.py b/api/tests/music/test_tasks.py
index fcb464f3686e44b05f3733830441e5d073a85a51..78f4622babb9b31cfde6f02f04b67eb2c90319ee 100644
--- a/api/tests/music/test_tasks.py
+++ b/api/tests/music/test_tasks.py
@@ -8,6 +8,7 @@ from django.core.paginator import Paginator
 from django.utils import timezone
 
 from funkwhale_api.federation import serializers as federation_serializers
+from funkwhale_api.federation import jsonld
 from funkwhale_api.music import licenses, metadata, signals, tasks
 
 DATA_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -19,15 +20,13 @@ DATA_DIR = os.path.dirname(os.path.abspath(__file__))
 def test_can_create_track_from_file_metadata_no_mbid(db, mocker):
     metadata = {
         "title": "Test track",
-        "artist": "Test artist",
-        "album": "Test album",
-        "date": datetime.date(2012, 8, 15),
-        "track_number": 4,
+        "artists": [{"name": "Test artist"}],
+        "album": {"title": "Test album", "release_date": datetime.date(2012, 8, 15)},
+        "position": 4,
         "disc_number": 2,
         "license": "Hello world: http://creativecommons.org/licenses/by-sa/4.0/",
         "copyright": "2018 Someone",
     }
-    mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
     match_license = mocker.spy(licenses, "match")
 
     track = tasks.get_track_from_import_metadata(metadata)
@@ -38,44 +37,100 @@ def test_can_create_track_from_file_metadata_no_mbid(db, mocker):
     assert track.disc_number == 2
     assert track.license.code == "cc-by-sa-4.0"
     assert track.copyright == metadata["copyright"]
-    assert track.album.title == metadata["album"]
+    assert track.album.title == metadata["album"]["title"]
     assert track.album.mbid is None
     assert track.album.release_date == datetime.date(2012, 8, 15)
-    assert track.artist.name == metadata["artist"]
+    assert track.artist.name == metadata["artists"][0]["name"]
     assert track.artist.mbid is None
+    assert track.artist.attributed_to is None
     match_license.assert_called_once_with(metadata["license"], metadata["copyright"])
 
 
+def test_can_create_track_from_file_metadata_attributed_to(factories, mocker):
+    actor = factories["federation.Actor"]()
+    metadata = {
+        "title": "Test track",
+        "artists": [{"name": "Test artist"}],
+        "album": {"title": "Test album", "release_date": datetime.date(2012, 8, 15)},
+        "position": 4,
+        "disc_number": 2,
+        "copyright": "2018 Someone",
+    }
+
+    track = tasks.get_track_from_import_metadata(metadata, attributed_to=actor)
+
+    assert track.title == metadata["title"]
+    assert track.mbid is None
+    assert track.position == 4
+    assert track.disc_number == 2
+    assert track.copyright == metadata["copyright"]
+    assert track.attributed_to == actor
+    assert track.album.title == metadata["album"]["title"]
+    assert track.album.mbid is None
+    assert track.album.release_date == datetime.date(2012, 8, 15)
+    assert track.album.attributed_to == actor
+    assert track.artist.name == metadata["artists"][0]["name"]
+    assert track.artist.mbid is None
+    assert track.artist.attributed_to == actor
+
+
+def test_can_create_track_from_file_metadata_featuring(factories):
+    metadata = {
+        "title": "Whole Lotta Love",
+        "position": 1,
+        "disc_number": 1,
+        "mbid": "508704c0-81d4-4c94-ba58-3fc0b7da23eb",
+        "album": {
+            "title": "Guitar Heaven: The Greatest Guitar Classics of All Time",
+            "mbid": "d06f2072-4148-488d-af6f-69ab6539ddb8",
+            "release_date": datetime.date(2010, 9, 17),
+            "artists": [
+                {"name": "Santana", "mbid": "9a3bf45c-347d-4630-894d-7cf3e8e0b632"}
+            ],
+        },
+        "artists": [{"name": "Santana feat. Chris Cornell", "mbid": None}],
+    }
+    track = tasks.get_track_from_import_metadata(metadata)
+
+    assert track.album.artist.name == "Santana"
+    assert track.artist.name == "Santana feat. Chris Cornell"
+
+
 def test_can_create_track_from_file_metadata_mbid(factories, mocker):
     metadata = {
         "title": "Test track",
-        "artist": "Test artist",
-        "album_artist": "Test album artist",
-        "album": "Test album",
-        "date": datetime.date(2012, 8, 15),
-        "track_number": 4,
-        "musicbrainz_albumid": "ce40cdb1-a562-4fd8-a269-9269f98d4124",
-        "musicbrainz_recordingid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
-        "musicbrainz_artistid": "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13",
-        "musicbrainz_albumartistid": "9c6bddde-6478-4d9f-ad0d-03f6fcb19e13",
+        "artists": [
+            {"name": "Test artist", "mbid": "9c6bddde-6228-4d9f-ad0d-03f6fcb19e13"}
+        ],
+        "album": {
+            "title": "Test album",
+            "release_date": datetime.date(2012, 8, 15),
+            "mbid": "9c6bddde-6478-4d9f-ad0d-03f6fcb19e15",
+            "artists": [
+                {
+                    "name": "Test album artist",
+                    "mbid": "9c6bddde-6478-4d9f-ad0d-03f6fcb19e13",
+                }
+            ],
+        },
+        "position": 4,
+        "mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
         "cover_data": {"content": b"image_content", "mimetype": "image/png"},
     }
 
-    mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
-
     track = tasks.get_track_from_import_metadata(metadata)
 
     assert track.title == metadata["title"]
-    assert track.mbid == metadata["musicbrainz_recordingid"]
+    assert track.mbid == metadata["mbid"]
     assert track.position == 4
     assert track.disc_number is None
-    assert track.album.title == metadata["album"]
-    assert track.album.mbid == metadata["musicbrainz_albumid"]
-    assert track.album.artist.mbid == metadata["musicbrainz_albumartistid"]
-    assert track.album.artist.name == metadata["album_artist"]
+    assert track.album.title == metadata["album"]["title"]
+    assert track.album.mbid == metadata["album"]["mbid"]
+    assert track.album.artist.mbid == metadata["album"]["artists"][0]["mbid"]
+    assert track.album.artist.name == metadata["album"]["artists"][0]["name"]
     assert track.album.release_date == datetime.date(2012, 8, 15)
-    assert track.artist.name == metadata["artist"]
-    assert track.artist.mbid == metadata["musicbrainz_artistid"]
+    assert track.artist.name == metadata["artists"][0]["name"]
+    assert track.artist.mbid == metadata["artists"][0]["mbid"]
 
 
 def test_can_create_track_from_file_metadata_mbid_existing_album_artist(
@@ -84,22 +139,21 @@ def test_can_create_track_from_file_metadata_mbid_existing_album_artist(
     artist = factories["music.Artist"]()
     album = factories["music.Album"]()
     metadata = {
-        "artist": "",
-        "album": "",
+        "album": {
+            "mbid": album.mbid,
+            "title": "",
+            "artists": [{"name": "", "mbid": album.artist.mbid}],
+        },
         "title": "Hello",
-        "track_number": 4,
-        "musicbrainz_albumid": album.mbid,
-        "musicbrainz_recordingid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
-        "musicbrainz_artistid": artist.mbid,
-        "musicbrainz_albumartistid": album.artist.mbid,
+        "position": 4,
+        "artists": [{"mbid": artist.mbid, "name": ""}],
+        "mbid": "f269d497-1cc0-4ae4-a0c4-157ec7d73fcb",
     }
 
-    mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
-
     track = tasks.get_track_from_import_metadata(metadata)
 
     assert track.title == metadata["title"]
-    assert track.mbid == metadata["musicbrainz_recordingid"]
+    assert track.mbid == metadata["mbid"]
     assert track.position == 4
     assert track.album == album
     assert track.artist == artist
@@ -111,18 +165,17 @@ def test_can_create_track_from_file_metadata_fid_existing_album_artist(
     artist = factories["music.Artist"]()
     album = factories["music.Album"]()
     metadata = {
-        "artist": "",
-        "album": "",
+        "artists": [{"name": "", "fid": artist.fid}],
+        "album": {
+            "title": "",
+            "fid": album.fid,
+            "artists": [{"name": "", "fid": album.artist.fid}],
+        },
         "title": "Hello",
-        "track_number": 4,
+        "position": 4,
         "fid": "https://hello",
-        "album_fid": album.fid,
-        "artist_fid": artist.fid,
-        "album_artist_fid": album.artist.fid,
     }
 
-    mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
-
     track = tasks.get_track_from_import_metadata(metadata)
 
     assert track.title == metadata["title"]
@@ -132,25 +185,68 @@ def test_can_create_track_from_file_metadata_fid_existing_album_artist(
     assert track.artist == artist
 
 
+def test_can_create_track_from_file_metadata_distinct_release_mbid(factories):
+    """Cf https://dev.funkwhale.audio/funkwhale/funkwhale/issues/772"""
+    artist = factories["music.Artist"]()
+    album = factories["music.Album"](artist=artist)
+    track = factories["music.Track"](album=album, artist=artist)
+    metadata = {
+        "artists": [{"name": artist.name, "mbid": artist.mbid}],
+        "album": {"title": album.title, "mbid": str(uuid.uuid4())},
+        "title": track.title,
+        "position": 4,
+        "fid": "https://hello",
+    }
+
+    new_track = tasks.get_track_from_import_metadata(metadata)
+
+    # the returned track should be different from the existing one, and mapped
+    # to a new album, because the albumid is different
+    assert new_track.album != album
+    assert new_track != track
+
+
+def test_can_create_track_from_file_metadata_distinct_position(factories):
+    """Cf https://dev.funkwhale.audio/funkwhale/funkwhale/issues/740"""
+    artist = factories["music.Artist"]()
+    album = factories["music.Album"](artist=artist)
+    track = factories["music.Track"](album=album, artist=artist)
+    metadata = {
+        "artists": [{"name": artist.name, "mbid": artist.mbid}],
+        "album": {"title": album.title, "mbid": album.mbid},
+        "title": track.title,
+        "position": track.position + 1,
+    }
+
+    new_track = tasks.get_track_from_import_metadata(metadata)
+
+    assert new_track != track
+
+
 def test_can_create_track_from_file_metadata_federation(factories, mocker, r_mock):
     metadata = {
-        "artist": "Artist",
-        "album": "Album",
-        "album_artist": "Album artist",
+        "artists": [
+            {"name": "Artist", "fid": "https://artist.fid", "fdate": timezone.now()}
+        ],
+        "album": {
+            "title": "Album",
+            "fid": "https://album.fid",
+            "fdate": timezone.now(),
+            "artists": [
+                {
+                    "name": "Album artist",
+                    "fid": "https://album.artist.fid",
+                    "fdate": timezone.now(),
+                }
+            ],
+        },
         "title": "Hello",
-        "track_number": 4,
+        "position": 4,
         "fid": "https://hello",
-        "album_fid": "https://album.fid",
-        "artist_fid": "https://artist.fid",
-        "album_artist_fid": "https://album.artist.fid",
         "fdate": timezone.now(),
-        "album_fdate": timezone.now(),
-        "album_artist_fdate": timezone.now(),
-        "artist_fdate": timezone.now(),
         "cover_data": {"url": "https://cover/hello.png", "mimetype": "image/png"},
     }
     r_mock.get(metadata["cover_data"]["url"], body=io.BytesIO(b"coucou"))
-    mocker.patch("funkwhale_api.music.metadata.Metadata.all", return_value=metadata)
 
     track = tasks.get_track_from_import_metadata(metadata, update_cover=True)
 
@@ -159,16 +255,16 @@ def test_can_create_track_from_file_metadata_federation(factories, mocker, r_moc
     assert track.creation_date == metadata["fdate"]
     assert track.position == 4
     assert track.album.cover.read() == b"coucou"
-    assert track.album.cover.path.endswith(".png")
-    assert track.album.fid == metadata["album_fid"]
-    assert track.album.title == metadata["album"]
-    assert track.album.creation_date == metadata["album_fdate"]
-    assert track.album.artist.fid == metadata["album_artist_fid"]
-    assert track.album.artist.name == metadata["album_artist"]
-    assert track.album.artist.creation_date == metadata["album_artist_fdate"]
-    assert track.artist.fid == metadata["artist_fid"]
-    assert track.artist.name == metadata["artist"]
-    assert track.artist.creation_date == metadata["artist_fdate"]
+    assert track.album.cover_path.endswith(".png")
+    assert track.album.fid == metadata["album"]["fid"]
+    assert track.album.title == metadata["album"]["title"]
+    assert track.album.creation_date == metadata["album"]["fdate"]
+    assert track.album.artist.fid == metadata["album"]["artists"][0]["fid"]
+    assert track.album.artist.name == metadata["album"]["artists"][0]["name"]
+    assert track.album.artist.creation_date == metadata["album"]["artists"][0]["fdate"]
+    assert track.artist.fid == metadata["artists"][0]["fid"]
+    assert track.artist.name == metadata["artists"][0]["name"]
+    assert track.artist.creation_date == metadata["artists"][0]["fdate"]
 
 
 def test_sort_candidates(factories):
@@ -184,6 +280,7 @@ def test_upload_import(now, factories, temp_signal, mocker):
     outbox = mocker.patch("funkwhale_api.federation.routes.outbox.dispatch")
     update_album_cover = mocker.patch("funkwhale_api.music.tasks.update_album_cover")
     get_picture = mocker.patch("funkwhale_api.music.metadata.Metadata.get_picture")
+    get_track_from_import_metadata = mocker.spy(tasks, "get_track_from_import_metadata")
     track = factories["music.Track"](album__cover="")
     upload = factories["music.Upload"](
         track=None, import_metadata={"funkwhale": {"track": {"uuid": str(track.uuid)}}}
@@ -201,6 +298,10 @@ def test_upload_import(now, factories, temp_signal, mocker):
     update_album_cover.assert_called_once_with(
         upload.track.album, cover_data=get_picture.return_value, source=upload.source
     )
+    assert (
+        get_track_from_import_metadata.call_args[-1]["attributed_to"]
+        == upload.library.actor
+    )
     handler.assert_called_once_with(
         upload=upload,
         old_status="pending",
@@ -348,7 +449,38 @@ def test_upload_import_error(factories, now, temp_signal):
 
     assert upload.import_status == "errored"
     assert upload.import_date == now
-    assert upload.import_details == {"error_code": "track_uuid_not_found"}
+    assert upload.import_details == {
+        "error_code": "track_uuid_not_found",
+        "detail": None,
+    }
+    handler.assert_called_once_with(
+        upload=upload,
+        old_status="pending",
+        new_status="errored",
+        sender=None,
+        signal=signals.upload_import_status_updated,
+    )
+
+
+def test_upload_import_error_metadata(factories, now, temp_signal, mocker):
+    path = os.path.join(DATA_DIR, "test.ogg")
+    upload = factories["music.Upload"](audio_file__frompath=path)
+    mocker.patch.object(
+        metadata.AlbumField,
+        "to_internal_value",
+        side_effect=metadata.serializers.ValidationError("Hello"),
+    )
+    with temp_signal(signals.upload_import_status_updated) as handler:
+        tasks.process_upload(upload_id=upload.pk)
+    upload.refresh_from_db()
+
+    assert upload.import_status == "errored"
+    assert upload.import_date == now
+    assert upload.import_details == {
+        "error_code": "invalid_metadata",
+        "detail": {"album": ["Hello"]},
+        "file_metadata": metadata.Metadata(path).all(),
+    }
     handler.assert_called_once_with(
         upload=upload,
         old_status="pending",
@@ -402,10 +534,17 @@ def test_update_album_cover_file_cover_separate_file(ext, mimetype, factories, m
     )
 
 
-def test_federation_audio_track_to_metadata(now):
+def test_federation_audio_track_to_metadata(now, mocker):
     published = now
     released = now.date()
+    references = {
+        "http://track.attributed": mocker.Mock(),
+        "http://album.attributed": mocker.Mock(),
+        "http://album-artist.attributed": mocker.Mock(),
+        "http://artist.attributed": mocker.Mock(),
+    }
     payload = {
+        "@context": jsonld.get_default_context(),
         "type": "Track",
         "id": "http://hello.track",
         "musicbrainzId": str(uuid.uuid4()),
@@ -415,6 +554,7 @@ def test_federation_audio_track_to_metadata(now):
         "published": published.isoformat(),
         "license": "http://creativecommons.org/licenses/by-sa/4.0/",
         "copyright": "2018 Someone",
+        "attributedTo": "http://track.attributed",
         "album": {
             "published": published.isoformat(),
             "type": "Album",
@@ -422,6 +562,7 @@ def test_federation_audio_track_to_metadata(now):
             "name": "Purple album",
             "musicbrainzId": str(uuid.uuid4()),
             "released": released.isoformat(),
+            "attributedTo": "http://album.attributed",
             "artists": [
                 {
                     "type": "Artist",
@@ -429,8 +570,14 @@ def test_federation_audio_track_to_metadata(now):
                     "id": "http://hello.artist",
                     "name": "John Smith",
                     "musicbrainzId": str(uuid.uuid4()),
+                    "attributedTo": "http://album-artist.attributed",
                 }
             ],
+            "cover": {
+                "type": "Link",
+                "href": "http://cover.test",
+                "mediaType": "image/png",
+            },
         },
         "artists": [
             {
@@ -439,46 +586,65 @@ def test_federation_audio_track_to_metadata(now):
                 "id": "http://hello.trackartist",
                 "name": "Bob Smith",
                 "musicbrainzId": str(uuid.uuid4()),
+                "attributedTo": "http://artist.attributed",
             }
         ],
     }
     serializer = federation_serializers.TrackSerializer(data=payload)
     serializer.is_valid(raise_exception=True)
     expected = {
-        "artist": payload["artists"][0]["name"],
-        "album": payload["album"]["name"],
-        "album_artist": payload["album"]["artists"][0]["name"],
         "title": payload["name"],
-        "date": released,
-        "track_number": payload["position"],
+        "position": payload["position"],
         "disc_number": payload["disc"],
         "license": "http://creativecommons.org/licenses/by-sa/4.0/",
         "copyright": "2018 Someone",
+        "mbid": payload["musicbrainzId"],
+        "fdate": serializer.validated_data["published"],
+        "fid": payload["id"],
+        "attributed_to": references["http://track.attributed"],
+        "album": {
+            "title": payload["album"]["name"],
+            "attributed_to": references["http://album.attributed"],
+            "release_date": released,
+            "mbid": payload["album"]["musicbrainzId"],
+            "fid": payload["album"]["id"],
+            "fdate": serializer.validated_data["album"]["published"],
+            "artists": [
+                {
+                    "name": a["name"],
+                    "mbid": a["musicbrainzId"],
+                    "fid": a["id"],
+                    "attributed_to": references["http://album-artist.attributed"],
+                    "fdate": serializer.validated_data["album"]["artists"][i][
+                        "published"
+                    ],
+                }
+                for i, a in enumerate(payload["album"]["artists"])
+            ],
+        },
         # musicbrainz
-        "musicbrainz_albumid": payload["album"]["musicbrainzId"],
-        "musicbrainz_recordingid": payload["musicbrainzId"],
-        "musicbrainz_artistid": payload["artists"][0]["musicbrainzId"],
-        "musicbrainz_albumartistid": payload["album"]["artists"][0]["musicbrainzId"],
         # federation
-        "fid": payload["id"],
-        "album_fid": payload["album"]["id"],
-        "artist_fid": payload["artists"][0]["id"],
-        "album_artist_fid": payload["album"]["artists"][0]["id"],
-        "fdate": serializer.validated_data["published"],
-        "artist_fdate": serializer.validated_data["artists"][0]["published"],
-        "album_artist_fdate": serializer.validated_data["album"]["artists"][0][
-            "published"
+        "artists": [
+            {
+                "name": a["name"],
+                "mbid": a["musicbrainzId"],
+                "fid": a["id"],
+                "fdate": serializer.validated_data["artists"][i]["published"],
+                "attributed_to": references["http://artist.attributed"],
+            }
+            for i, a in enumerate(payload["artists"])
         ],
-        "album_fdate": serializer.validated_data["album"]["published"],
+        "cover_data": {
+            "mimetype": serializer.validated_data["album"]["cover"]["mediaType"],
+            "url": serializer.validated_data["album"]["cover"]["href"],
+        },
     }
 
-    result = tasks.federation_audio_track_to_metadata(serializer.validated_data)
+    result = tasks.federation_audio_track_to_metadata(
+        serializer.validated_data, references
+    )
     assert result == expected
 
-    # ensure we never forget to test a mandatory field
-    for k in metadata.ALL_FIELDS:
-        assert k in result
-
 
 def test_scan_library_fetches_page_and_calls_scan_page(now, mocker, factories, r_mock):
     scan = factories["music.LibraryScan"]()
@@ -584,3 +750,83 @@ def test_clean_transcoding_cache(preferences, now, factories):
 
     with pytest.raises(u1.__class__.DoesNotExist):
         u1.refresh_from_db()
+
+
+def test_get_prunable_tracks(factories):
+    prunable_track = factories["music.Track"]()
+    # non prunable tracks
+    factories["music.Upload"]()
+    factories["favorites.TrackFavorite"]()
+    factories["history.Listening"]()
+    factories["playlists.PlaylistTrack"]()
+
+    assert list(tasks.get_prunable_tracks()) == [prunable_track]
+
+
+def test_get_prunable_tracks_include_favorites(factories):
+    prunable_track = factories["music.Track"]()
+    favorited = factories["favorites.TrackFavorite"]().track
+    # non prunable tracks
+    factories["favorites.TrackFavorite"](track__playable=True)
+    factories["music.Upload"]()
+    factories["history.Listening"]()
+    factories["playlists.PlaylistTrack"]()
+
+    qs = tasks.get_prunable_tracks(exclude_favorites=False).order_by("id")
+    assert list(qs) == [prunable_track, favorited]
+
+
+def test_get_prunable_tracks_include_playlists(factories):
+    prunable_track = factories["music.Track"]()
+    in_playlist = factories["playlists.PlaylistTrack"]().track
+    # non prunable tracks
+    factories["favorites.TrackFavorite"]()
+    factories["music.Upload"]()
+    factories["history.Listening"]()
+    factories["playlists.PlaylistTrack"](track__playable=True)
+
+    qs = tasks.get_prunable_tracks(exclude_playlists=False).order_by("id")
+    assert list(qs) == [prunable_track, in_playlist]
+
+
+def test_get_prunable_tracks_include_listenings(factories):
+    prunable_track = factories["music.Track"]()
+    listened = factories["history.Listening"]().track
+    # non prunable tracks
+    factories["favorites.TrackFavorite"]()
+    factories["music.Upload"]()
+    factories["history.Listening"](track__playable=True)
+    factories["playlists.PlaylistTrack"]()
+
+    qs = tasks.get_prunable_tracks(exclude_listenings=False).order_by("id")
+    assert list(qs) == [prunable_track, listened]
+
+
+def test_get_prunable_albums(factories):
+    prunable_album = factories["music.Album"]()
+    # non prunable album
+    factories["music.Track"]().album
+
+    assert list(tasks.get_prunable_albums()) == [prunable_album]
+
+
+def test_get_prunable_artists(factories):
+    prunable_artist = factories["music.Artist"]()
+    # non prunable artist
+    non_prunable_artist = factories["music.Artist"]()
+    non_prunable_album_artist = factories["music.Artist"]()
+    factories["music.Track"](artist=non_prunable_artist)
+    factories["music.Track"](album__artist=non_prunable_album_artist)
+
+    assert list(tasks.get_prunable_artists()) == [prunable_artist]
+
+
+def test_update_library_entity(factories, mocker):
+    artist = factories["music.Artist"]()
+    save = mocker.spy(artist, "save")
+
+    tasks.update_library_entity(artist, {"name": "Hello"})
+    save.assert_called_once_with(update_fields=["name"])
+
+    artist.refresh_from_db()
+    assert artist.name == "Hello"
diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py
index 85ba2955a141f200fb1f0e81143d82cee2c78dcb..102b5a790a82d8d6fc174df72b414d0bf64033bf 100644
--- a/api/tests/music/test_views.py
+++ b/api/tests/music/test_views.py
@@ -70,6 +70,19 @@ def test_track_list_serializer(api_request, factories, logged_in_api_client):
     assert response.data == expected
 
 
+def test_track_list_filter_id(api_request, factories, logged_in_api_client):
+    track1 = factories["music.Track"]()
+    track2 = factories["music.Track"]()
+    factories["music.Track"]()
+    url = reverse("api:v1:tracks-list")
+    response = logged_in_api_client.get(url, {"id[]": [track1.id, track2.id]})
+
+    assert response.status_code == 200
+    assert response.data["count"] == 2
+    assert response.data["results"][0]["id"] == track2.id
+    assert response.data["results"][1]["id"] == track1.id
+
+
 @pytest.mark.parametrize("param,expected", [("true", "full"), ("false", "empty")])
 def test_artist_view_filter_playable(param, expected, factories, api_request):
     artists = {
@@ -108,6 +121,27 @@ def test_album_view_filter_playable(param, expected, factories, api_request):
     assert list(queryset) == expected
 
 
+@pytest.mark.parametrize(
+    "param", [("I've Got"), ("Français"), ("I've Got Everything : Spoken Word Poetry")]
+)
+def test_album_view_filter_query(param, factories, api_request):
+    # Test both partial and full search.
+    factories["music.Album"](title="I've Got Nothing : Original Soundtrack")
+    factories["music.Album"](title="I've Got Cake : Remix")
+    factories["music.Album"](title="Français Et Tu")
+    factories["music.Album"](title="I've Got Everything : Spoken Word Poetry")
+
+    request = api_request.get("/", {"q": param})
+    view = views.AlbumViewSet()
+    view.action_map = {"get": "list"}
+    view.request = view.initialize_request(request)
+    queryset = view.filter_queryset(view.get_queryset())
+
+    # Loop through our "expected list", and assert some string finds against our param.
+    for val in list(queryset):
+        assert val.title.find(param) != -1
+
+
 def test_can_serve_upload_as_remote_library(
     factories, authenticated_actor, logged_in_api_client, settings, preferences
 ):
@@ -297,7 +331,7 @@ def test_listen_correct_access(factories, logged_in_api_client):
     assert response.status_code == 200
 
 
-def test_listen_explicit_file(factories, logged_in_api_client, mocker):
+def test_listen_explicit_file(factories, logged_in_api_client, mocker, settings):
     mocked_serve = mocker.spy(views, "handle_serve")
     upload1 = factories["music.Upload"](
         library__privacy_level="everyone", import_status="finished"
@@ -310,8 +344,24 @@ def test_listen_explicit_file(factories, logged_in_api_client, mocker):
 
     assert response.status_code == 200
     mocked_serve.assert_called_once_with(
-        upload2, user=logged_in_api_client.user, format=None
+        upload2,
+        user=logged_in_api_client.user,
+        format=None,
+        max_bitrate=None,
+        proxy_media=settings.PROXY_MEDIA,
+    )
+
+
+def test_listen_no_proxy(factories, logged_in_api_client, settings):
+    settings.PROXY_MEDIA = False
+    upload = factories["music.Upload"](
+        library__privacy_level="everyone", import_status="finished"
     )
+    url = reverse("api:v1:listen-detail", kwargs={"uuid": upload.track.uuid})
+    response = logged_in_api_client.get(url, {"upload": upload.uuid})
+
+    assert response.status_code == 302
+    assert response["Location"] == upload.audio_file.url
 
 
 @pytest.mark.parametrize(
@@ -333,6 +383,22 @@ def test_should_transcode(mimetype, format, expected, factories):
     assert views.should_transcode(upload, format) is expected
 
 
+@pytest.mark.parametrize(
+    "bitrate,max_bitrate,expected",
+    [
+        # already in acceptable bitrate
+        (192000, 320000, False),
+        # No max bitrate specified
+        (192000, None, False),
+        # requested max below available
+        (192000, 128000, True),
+    ],
+)
+def test_should_transcode_bitrate(bitrate, max_bitrate, expected, factories):
+    upload = models.Upload(mimetype="audio/mpeg", bitrate=bitrate)
+    assert views.should_transcode(upload, "mp3", max_bitrate=max_bitrate) is expected
+
+
 @pytest.mark.parametrize("value", [True, False])
 def test_should_transcode_according_to_preference(value, preferences, factories):
     upload = models.Upload(mimetype="audio/ogg")
@@ -352,14 +418,14 @@ def test_handle_serve_create_mp3_version(factories, now):
     assert version.mimetype == "audio/mpeg"
     assert version.accessed_date == now
     assert version.bitrate == upload.bitrate
-    assert version.audio_file.path.endswith(".mp3")
+    assert version.audio_file_path.endswith(".mp3")
     assert version.size == version.audio_file.size
     assert magic.from_buffer(version.audio_file.read(), mime=True) == "audio/mpeg"
 
     assert response.status_code == 200
 
 
-def test_listen_transcode(factories, now, logged_in_api_client, mocker):
+def test_listen_transcode(factories, now, logged_in_api_client, mocker, settings):
     upload = factories["music.Upload"](
         import_status="finished", library__actor__user=logged_in_api_client.user
     )
@@ -370,7 +436,43 @@ def test_listen_transcode(factories, now, logged_in_api_client, mocker):
     assert response.status_code == 200
 
     handle_serve.assert_called_once_with(
-        upload, user=logged_in_api_client.user, format="mp3"
+        upload,
+        user=logged_in_api_client.user,
+        format="mp3",
+        max_bitrate=None,
+        proxy_media=settings.PROXY_MEDIA,
+    )
+
+
+@pytest.mark.parametrize(
+    "max_bitrate, expected",
+    [
+        ("", None),
+        ("", None),
+        ("-1", None),
+        ("128", 128000),
+        ("320", 320000),
+        ("460", 320000),
+    ],
+)
+def test_listen_transcode_bitrate(
+    max_bitrate, expected, factories, now, logged_in_api_client, mocker, settings
+):
+    upload = factories["music.Upload"](
+        import_status="finished", library__actor__user=logged_in_api_client.user
+    )
+    url = reverse("api:v1:listen-detail", kwargs={"uuid": upload.track.uuid})
+    handle_serve = mocker.spy(views, "handle_serve")
+    response = logged_in_api_client.get(url, {"max_bitrate": max_bitrate})
+
+    assert response.status_code == 200
+
+    handle_serve.assert_called_once_with(
+        upload,
+        user=logged_in_api_client.user,
+        format=None,
+        max_bitrate=expected,
+        proxy_media=settings.PROXY_MEDIA,
     )
 
 
@@ -396,7 +498,11 @@ def test_listen_transcode_in_place(
     assert response.status_code == 200
 
     handle_serve.assert_called_once_with(
-        upload, user=logged_in_api_client.user, format="mp3"
+        upload,
+        user=logged_in_api_client.user,
+        format="mp3",
+        max_bitrate=None,
+        proxy_media=settings.PROXY_MEDIA,
     )
 
 
@@ -578,7 +684,7 @@ def test_list_licenses(api_client, preferences, mocker):
 
     expected = [
         serializers.LicenseSerializer(l.conf).data
-        for l in models.License.objects.order_by("code")[:25]
+        for l in models.License.objects.order_by("code")
     ]
     url = reverse("api:v1:licenses-list")
 
@@ -667,3 +773,38 @@ def test_oembed_album(factories, no_api_auth, api_client, settings):
     response = api_client.get(url, {"url": album_url, "format": "json"})
 
     assert response.data == expected
+
+
+def test_oembed_artist(factories, no_api_auth, api_client, settings):
+    settings.FUNKWHALE_URL = "http://test"
+    settings.FUNKWHALE_EMBED_URL = "http://embed"
+    track = factories["music.Track"]()
+    album = track.album
+    artist = track.artist
+    url = reverse("api:v1:oembed")
+    artist_url = "https://test.com/library/artists/{}".format(artist.pk)
+    iframe_src = "http://embed?type=artist&id={}".format(artist.pk)
+    expected = {
+        "version": "1.0",
+        "type": "rich",
+        "provider_name": settings.APP_NAME,
+        "provider_url": settings.FUNKWHALE_URL,
+        "height": 400,
+        "width": 600,
+        "title": artist.name,
+        "description": artist.name,
+        "thumbnail_url": federation_utils.full_url(album.cover.crop["400x400"].url),
+        "thumbnail_height": 400,
+        "thumbnail_width": 400,
+        "html": '<iframe width="600" height="400" scrolling="no" frameborder="no" src="{}"></iframe>'.format(
+            iframe_src
+        ),
+        "author_name": artist.name,
+        "author_url": federation_utils.full_url(
+            utils.spa_reverse("library_artist", kwargs={"pk": artist.pk})
+        ),
+    }
+
+    response = api_client.get(url, {"url": artist_url, "format": "json"})
+
+    assert response.data == expected
diff --git a/api/tests/music/test_works.py b/api/tests/music/test_works.py
deleted file mode 100644
index 96b537ca297a5b9e8c81528349b42d5404fbe9f6..0000000000000000000000000000000000000000
--- a/api/tests/music/test_works.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from funkwhale_api.music import models
-
-
-def test_can_import_work(factories, mocker, works):
-    mocker.patch(
-        "funkwhale_api.musicbrainz.api.works.get",
-        return_value=works["get"]["chop_suey"],
-    )
-    recording = factories["music.Track"](mbid="07ca77cf-f513-4e9c-b190-d7e24bbad448")
-    mbid = "e2ecabc4-1b9d-30b2-8f30-3596ec423dc5"
-    work = models.Work.create_from_api(id=mbid)
-
-    assert work.title == "Chop Suey!"
-    assert work.nature == "song"
-    assert work.language == "eng"
-    assert work.mbid == mbid
-
-    # a imported work should also be linked to corresponding recordings
-
-    recording.refresh_from_db()
-    assert recording.work == work
-
-
-def test_can_get_work_from_recording(factories, mocker, works, tracks):
-    mocker.patch(
-        "funkwhale_api.musicbrainz.api.works.get",
-        return_value=works["get"]["chop_suey"],
-    )
-    mocker.patch(
-        "funkwhale_api.musicbrainz.api.recordings.get",
-        return_value=tracks["get"]["chop_suey"],
-    )
-    recording = factories["music.Track"](
-        work=None, mbid="07ca77cf-f513-4e9c-b190-d7e24bbad448"
-    )
-    mbid = "e2ecabc4-1b9d-30b2-8f30-3596ec423dc5"
-
-    assert recording.work is None
-
-    work = recording.get_work()
-
-    assert work.title == "Chop Suey!"
-    assert work.nature == "song"
-    assert work.language == "eng"
-    assert work.mbid == mbid
-
-    recording.refresh_from_db()
-    assert recording.work == work
-
-
-def test_works_import_lyrics_if_any(db, mocker, works):
-    mocker.patch(
-        "funkwhale_api.musicbrainz.api.works.get",
-        return_value=works["get"]["chop_suey"],
-    )
-    mbid = "e2ecabc4-1b9d-30b2-8f30-3596ec423dc5"
-    work = models.Work.create_from_api(id=mbid)
-
-    lyrics = models.Lyrics.objects.latest("id")
-    assert lyrics.work == work
-    assert lyrics.url == "http://lyrics.wikia.com/System_Of_A_Down:Chop_Suey!"
diff --git a/api/tests/playlists/test_models.py b/api/tests/playlists/test_models.py
index b90f525184b2f4863d8d9f7ab07314ac1e1a1712..92ffbf4edf8a25731b0473458e45f4022282946a 100644
--- a/api/tests/playlists/test_models.py
+++ b/api/tests/playlists/test_models.py
@@ -124,6 +124,139 @@ def test_insert_many_honor_max_tracks(preferences, factories):
         playlist.insert_many([track, track, track])
 
 
+def test_can_insert_duplicate_by_default(factories):
+    playlist = factories["playlists.Playlist"]()
+    track = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=0, track=track)
+
+    new = factories["playlists.PlaylistTrack"](playlist=playlist, index=1, track=track)
+    playlist.insert(new)
+
+    new.refresh_from_db()
+    assert new.index == 1
+
+
+def test_cannot_insert_duplicate(factories):
+    playlist = factories["playlists.Playlist"](name="playlist")
+    track = factories["music.Track"]()
+
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=0, track=track)
+
+    with pytest.raises(exceptions.ValidationError) as e:
+        new = factories["playlists.PlaylistTrack"](
+            playlist=playlist, index=1, track=track
+        )
+        playlist.insert(new, allow_duplicates=False)
+
+    errors = e.value.detail["non_field_errors"]
+    assert len(errors) == 1
+
+    err = errors[0]
+    assert err["code"] == "tracks_already_exist_in_playlist"
+    assert err["playlist_name"] == "playlist"
+    assert err["tracks"] == [track.title]
+
+
+def test_can_insert_track_to_playlist_with_existing_duplicates(factories):
+    playlist = factories["playlists.Playlist"]()
+    existing_duplicate = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](
+        playlist=playlist, index=0, track=existing_duplicate
+    )
+    factories["playlists.PlaylistTrack"](
+        playlist=playlist, index=1, track=existing_duplicate
+    )
+    factories["playlists.PlaylistTrack"](
+        playlist=playlist, index=2, track=existing_duplicate
+    )
+
+    new_track = factories["music.Track"]()
+    new_plt = factories["playlists.PlaylistTrack"](
+        playlist=playlist, index=3, track=new_track
+    )
+
+    # no error
+    playlist.insert(new_plt, allow_duplicates=False)
+
+
+def test_can_insert_duplicate_with_override(factories):
+    playlist = factories["playlists.Playlist"]()
+    track = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=0, track=track)
+
+    new = factories["playlists.PlaylistTrack"](playlist=playlist, index=1, track=track)
+    playlist.insert(new, allow_duplicates=True)
+
+    new.refresh_from_db()
+    assert new.index == 1
+
+
+def test_can_insert_many_duplicates_by_default(factories):
+    playlist = factories["playlists.Playlist"]()
+
+    t1 = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=0, track=t1)
+
+    t2 = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=1, track=t2)
+
+    t4 = factories["music.Track"]()
+
+    tracks = [t1, t4, t2]
+
+    plts = playlist.insert_many(tracks)
+
+    assert len(plts) == 3
+    assert plts[0].track == t1
+    assert plts[1].track == t4
+    assert plts[2].track == t2
+
+
+def test_cannot_insert_many_duplicates(factories):
+    playlist = factories["playlists.Playlist"](name="playlist")
+
+    t1 = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=0, track=t1)
+
+    t2 = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=1, track=t2)
+
+    t4 = factories["music.Track"]()
+
+    with pytest.raises(exceptions.ValidationError) as e:
+        tracks = [t1, t4, t2]
+        playlist.insert_many(tracks, allow_duplicates=False)
+
+    errors = e.value.detail["non_field_errors"]
+    assert len(errors) == 1
+
+    err = errors[0]
+    assert err["code"] == "tracks_already_exist_in_playlist"
+    assert err["playlist_name"] == "playlist"
+    assert err["tracks"] == [t1.title, t2.title]
+
+
+def test_can_insert_many_duplicates_with_override(factories):
+    playlist = factories["playlists.Playlist"]()
+
+    t1 = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=0, track=t1)
+
+    t2 = factories["music.Track"]()
+    factories["playlists.PlaylistTrack"](playlist=playlist, index=1, track=t2)
+
+    t4 = factories["music.Track"]()
+
+    tracks = [t1, t4, t2]
+
+    plts = playlist.insert_many(tracks, allow_duplicates=True)
+
+    assert len(plts) == 3
+    assert plts[0].track == t1
+    assert plts[1].track == t4
+    assert plts[2].track == t2
+
+
 @pytest.mark.parametrize(
     "privacy_level,expected", [("me", False), ("instance", False), ("everyone", True)]
 )
diff --git a/api/tests/playlists/test_serializers.py b/api/tests/playlists/test_serializers.py
index 0afc927ade0fcb58c25578064dcdc9d4c7c5f88a..2500947292142b653e99886144c8020788ad5762 100644
--- a/api/tests/playlists/test_serializers.py
+++ b/api/tests/playlists/test_serializers.py
@@ -24,7 +24,7 @@ def test_create_insert_is_called_when_index_is_None(factories, mocker):
     assert serializer.is_valid() is True
 
     plt = serializer.save()
-    insert.assert_called_once_with(playlist, plt, None)
+    insert.assert_called_once_with(playlist, plt, None, True)
     assert plt.index == 0
 
 
@@ -41,7 +41,7 @@ def test_create_insert_is_called_when_index_is_provided(factories, mocker):
 
     plt = serializer.save()
     first.refresh_from_db()
-    insert.assert_called_once_with(playlist, plt, 0)
+    insert.assert_called_once_with(playlist, plt, 0, True)
     assert plt.index == 0
     assert first.index == 1
 
@@ -60,11 +60,35 @@ def test_update_insert_is_called_when_index_is_provided(factories, mocker):
 
     plt = serializer.save()
     first.refresh_from_db()
-    insert.assert_called_once_with(playlist, plt, 0)
+    insert.assert_called_once_with(playlist, plt, 0, True)
     assert plt.index == 0
     assert first.index == 1
 
 
+def test_update_insert_is_called_with_duplicate_override_when_duplicates_allowed(
+    factories, mocker
+):
+    playlist = factories["playlists.Playlist"]()
+    plt = factories["playlists.PlaylistTrack"](playlist=playlist, index=0)
+    insert = mocker.spy(models.Playlist, "insert")
+    factories["playlists.Playlist"]()
+    factories["music.Track"]()
+
+    serializer = serializers.PlaylistTrackWriteSerializer(
+        plt,
+        data={
+            "playlist": playlist.pk,
+            "track": plt.track.pk,
+            "index": 0,
+            "allow_duplicates": True,
+        },
+    )
+    assert serializer.is_valid() is True
+    plt = serializer.save()
+
+    insert.assert_called_once_with(playlist, plt, 0, True)
+
+
 def test_playlist_serializer_include_covers(factories, api_request):
     playlist = factories["playlists.Playlist"]()
     t1 = factories["music.Track"]()
diff --git a/api/tests/radios/test_radios.py b/api/tests/radios/test_radios.py
index 7e8f260d0338d2ef71b3b51fb11c5acde917789a..640e712117bfb2ffc641af43daaa0eb5268ad0fd 100644
--- a/api/tests/radios/test_radios.py
+++ b/api/tests/radios/test_radios.py
@@ -237,3 +237,44 @@ def test_can_start_less_listened_radio(factories):
 
     for i in range(5):
         assert radio.pick(filter_playable=False) in good_tracks
+
+
+def test_similar_radio_track(factories):
+    user = factories["users.User"]()
+    seed = factories["music.Track"]()
+    radio = radios.SimilarRadio()
+    radio.start_session(user, related_object=seed)
+
+    factories["music.Track"].create_batch(5)
+
+    # one user listened to this track
+    l1 = factories["history.Listening"](track=seed)
+
+    expected_next = factories["music.Track"]()
+    factories["history.Listening"](track=expected_next, user=l1.user)
+
+    assert radio.pick(filter_playable=False) == expected_next
+
+
+def test_session_radio_get_queryset_ignore_filtered_track_artist(
+    factories, queryset_equal_list
+):
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    factories["music.Track"](artist=cf.target_artist)
+    valid_track = factories["music.Track"]()
+    radio = radios.RandomRadio()
+    radio.start_session(user=cf.user)
+
+    assert radio.get_queryset() == [valid_track]
+
+
+def test_session_radio_get_queryset_ignore_filtered_track_album_artist(
+    factories, queryset_equal_list
+):
+    cf = factories["moderation.UserFilter"](for_artist=True)
+    factories["music.Track"](album__artist=cf.target_artist)
+    valid_track = factories["music.Track"]()
+    radio = radios.RandomRadio()
+    radio.start_session(user=cf.user)
+
+    assert radio.get_queryset() == [valid_track]
diff --git a/api/tests/subsonic/test_views.py b/api/tests/subsonic/test_views.py
index 0dbbaf39a2b6018017351dbf51400b3b62ad5d35..73f968ff47130daefa5312d1aa61e10a9a15ddde 100644
--- a/api/tests/subsonic/test_views.py
+++ b/api/tests/subsonic/test_views.py
@@ -7,6 +7,7 @@ from django.utils import timezone
 from rest_framework.response import Response
 
 import funkwhale_api
+from funkwhale_api.moderation import filters as moderation_filters
 from funkwhale_api.music import models as music_models
 from funkwhale_api.music import views as music_views
 from funkwhale_api.subsonic import renderers, serializers
@@ -100,20 +101,31 @@ def test_ping(f, db, api_client):
 def test_get_artists(
     f, db, logged_in_api_client, factories, mocker, queryset_equal_queries
 ):
+    factories["moderation.UserFilter"](
+        user=logged_in_api_client.user,
+        target_artist=factories["music.Artist"](playable=True),
+    )
     url = reverse("api:subsonic-get_artists")
     assert url.endswith("getArtists") is True
     factories["music.Artist"].create_batch(size=3, playable=True)
     playable_by = mocker.spy(music_models.ArtistQuerySet, "playable_by")
+    exclude_query = moderation_filters.get_filtered_content_query(
+        moderation_filters.USER_FILTER_CONFIG["ARTIST"], logged_in_api_client.user
+    )
+    assert exclude_query is not None
     expected = {
         "artists": serializers.GetArtistsSerializer(
-            music_models.Artist.objects.all()
+            music_models.Artist.objects.all().exclude(exclude_query)
         ).data
     }
     response = logged_in_api_client.get(url, {"f": f})
 
     assert response.status_code == 200
     assert response.data == expected
-    playable_by.assert_called_once_with(music_models.Artist.objects.all(), None)
+    playable_by.assert_called_once_with(
+        music_models.Artist.objects.all().exclude(exclude_query),
+        logged_in_api_client.user.actor,
+    )
 
 
 @pytest.mark.parametrize("f", ["json"])
@@ -205,7 +217,12 @@ def test_get_song(
 
 
 @pytest.mark.parametrize("f", ["json"])
-def test_stream(f, db, logged_in_api_client, factories, mocker, queryset_equal_queries):
+def test_stream(
+    f, db, logged_in_api_client, factories, mocker, queryset_equal_queries, settings
+):
+    # Even with this settings set to false, we proxy media in the subsonic API
+    # Because clients don't expect a 302 redirect
+    settings.PROXY_MEDIA = False
     url = reverse("api:subsonic-stream")
     mocked_serve = mocker.spy(music_views, "handle_serve")
     assert url.endswith("stream") is True
@@ -214,7 +231,11 @@ def test_stream(f, db, logged_in_api_client, factories, mocker, queryset_equal_q
     response = logged_in_api_client.get(url, {"f": f, "id": upload.track.pk})
 
     mocked_serve.assert_called_once_with(
-        upload=upload, user=logged_in_api_client.user, format=None
+        upload=upload,
+        user=logged_in_api_client.user,
+        format=None,
+        max_bitrate=None,
+        proxy_media=True,
     )
     assert response.status_code == 200
     playable_by.assert_called_once_with(music_models.Track.objects.all(), None)
@@ -230,7 +251,34 @@ def test_stream_format(format, expected, logged_in_api_client, factories, mocker
     response = logged_in_api_client.get(url, {"id": upload.track.pk, "format": format})
 
     mocked_serve.assert_called_once_with(
-        upload=upload, user=logged_in_api_client.user, format=expected
+        upload=upload,
+        user=logged_in_api_client.user,
+        format=expected,
+        max_bitrate=None,
+        proxy_media=True,
+    )
+    assert response.status_code == 200
+
+
+@pytest.mark.parametrize(
+    "max_bitrate,expected", [(0, None), (192, 192000), (2000, 320000)]
+)
+def test_stream_bitrate(max_bitrate, expected, logged_in_api_client, factories, mocker):
+    url = reverse("api:subsonic-stream")
+    mocked_serve = mocker.patch.object(
+        music_views, "handle_serve", return_value=Response()
+    )
+    upload = factories["music.Upload"](playable=True)
+    response = logged_in_api_client.get(
+        url, {"id": upload.track.pk, "maxBitRate": max_bitrate}
+    )
+
+    mocked_serve.assert_called_once_with(
+        upload=upload,
+        user=logged_in_api_client.user,
+        format=None,
+        max_bitrate=expected,
+        proxy_media=True,
     )
     assert response.status_code == 200
 
@@ -502,12 +550,20 @@ def test_get_music_folders(f, db, logged_in_api_client, factories):
 def test_get_indexes(
     f, db, logged_in_api_client, factories, mocker, queryset_equal_queries
 ):
+    factories["moderation.UserFilter"](
+        user=logged_in_api_client.user,
+        target_artist=factories["music.Artist"](playable=True),
+    )
+    exclude_query = moderation_filters.get_filtered_content_query(
+        moderation_filters.USER_FILTER_CONFIG["ARTIST"], logged_in_api_client.user
+    )
+
     url = reverse("api:subsonic-get_indexes")
     assert url.endswith("getIndexes") is True
     factories["music.Artist"].create_batch(size=3, playable=True)
     expected = {
         "indexes": serializers.GetArtistsSerializer(
-            music_models.Artist.objects.all()
+            music_models.Artist.objects.all().exclude(exclude_query)
         ).data
     }
     playable_by = mocker.spy(music_models.ArtistQuerySet, "playable_by")
@@ -516,7 +572,10 @@ def test_get_indexes(
     assert response.status_code == 200
     assert response.data == expected
 
-    playable_by.assert_called_once_with(music_models.Artist.objects.all(), None)
+    playable_by.assert_called_once_with(
+        music_models.Artist.objects.all().exclude(exclude_query),
+        logged_in_api_client.user.actor,
+    )
 
 
 def test_get_cover_art_album(factories, logged_in_api_client):
diff --git a/api/tests/test_auth.py b/api/tests/test_auth.py
new file mode 100644
index 0000000000000000000000000000000000000000..653110f0944e0b08e13bf40f97460de4d47a83da
--- /dev/null
+++ b/api/tests/test_auth.py
@@ -0,0 +1,36 @@
+from django.urls import reverse
+from rest_framework_jwt.settings import api_settings
+
+jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
+jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
+
+
+def test_can_authenticate_using_jwt_token_param_in_url(factories, preferences, client):
+    user = factories["users.User"]()
+    preferences["common__api_authentication_required"] = True
+    url = reverse("api:v1:tracks-list")
+    response = client.get(url)
+
+    assert response.status_code == 401
+
+    payload = jwt_payload_handler(user)
+    token = jwt_encode_handler(payload)
+    response = client.get(url, data={"jwt": token})
+    assert response.status_code == 200
+
+
+def test_can_authenticate_using_oauth_token_param_in_url(
+    factories, preferences, client, mocker
+):
+    mocker.patch(
+        "funkwhale_api.users.oauth.permissions.should_allow", return_value=True
+    )
+    token = factories["users.AccessToken"]()
+    preferences["common__api_authentication_required"] = True
+    url = reverse("api:v1:tracks-list")
+    response = client.get(url)
+
+    assert response.status_code == 401
+
+    response = client.get(url, data={"token": token.token})
+    assert response.status_code == 200
diff --git a/api/tests/test_jwt_querystring.py b/api/tests/test_jwt_querystring.py
deleted file mode 100644
index 18a673fb480d71fdea41dc60557dfd56b6c34aaa..0000000000000000000000000000000000000000
--- a/api/tests/test_jwt_querystring.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from django.urls import reverse
-from rest_framework_jwt.settings import api_settings
-
-jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
-jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
-
-
-def test_can_authenticate_using_token_param_in_url(factories, preferences, client):
-    user = factories["users.User"]()
-    preferences["common__api_authentication_required"] = True
-    url = reverse("api:v1:tracks-list")
-    response = client.get(url)
-
-    assert response.status_code == 401
-
-    payload = jwt_payload_handler(user)
-    token = jwt_encode_handler(payload)
-    response = client.get(url, data={"jwt": token})
-    assert response.status_code == 200
diff --git a/api/tests/users/oauth/__init__.py b/api/tests/users/oauth/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/api/tests/users/oauth/test_api_permissions.py b/api/tests/users/oauth/test_api_permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..e73d3a3f91c71b30c2444719ed035f5049d3d4a2
--- /dev/null
+++ b/api/tests/users/oauth/test_api_permissions.py
@@ -0,0 +1,80 @@
+import pytest
+import uuid
+
+from django.urls import reverse
+
+from funkwhale_api.users.oauth import scopes
+
+# mutations
+
+
+@pytest.mark.parametrize(
+    "name, url_kwargs, scope, method",
+    [
+        ("api:v1:search", {}, "read:libraries", "get"),
+        ("api:v1:artists-list", {}, "read:libraries", "get"),
+        ("api:v1:albums-list", {}, "read:libraries", "get"),
+        ("api:v1:tracks-list", {}, "read:libraries", "get"),
+        ("api:v1:tracks-mutations", {"pk": 42}, "read:edits", "get"),
+        ("api:v1:tags-list", {}, "read:libraries", "get"),
+        ("api:v1:licenses-list", {}, "read:libraries", "get"),
+        ("api:v1:moderation:content-filters-list", {}, "read:filters", "get"),
+        ("api:v1:listen-detail", {"uuid": uuid.uuid4()}, "read:libraries", "get"),
+        ("api:v1:uploads-list", {}, "read:libraries", "get"),
+        ("api:v1:playlists-list", {}, "read:playlists", "get"),
+        ("api:v1:playlist-tracks-list", {}, "read:playlists", "get"),
+        ("api:v1:favorites:tracks-list", {}, "read:favorites", "get"),
+        ("api:v1:history:listenings-list", {}, "read:listenings", "get"),
+        ("api:v1:radios:radios-list", {}, "read:radios", "get"),
+        ("api:v1:oauth:grants-list", {}, "read:security", "get"),
+        ("api:v1:federation:inbox-list", {}, "read:notifications", "get"),
+        (
+            "api:v1:federation:libraries-detail",
+            {"uuid": uuid.uuid4()},
+            "read:libraries",
+            "get",
+        ),
+        ("api:v1:federation:library-follows-list", {}, "read:follows", "get"),
+        # admin / privileged stuff
+        ("api:v1:instance:admin-settings-list", {}, "read:instance:settings", "get"),
+        (
+            "api:v1:manage:users:invitations-list",
+            {},
+            "read:instance:invitations",
+            "get",
+        ),
+        ("api:v1:manage:users:users-list", {}, "read:instance:users", "get"),
+        ("api:v1:manage:library:uploads-list", {}, "read:instance:libraries", "get"),
+        ("api:v1:manage:accounts-list", {}, "read:instance:accounts", "get"),
+        ("api:v1:manage:federation:domains-list", {}, "read:instance:domains", "get"),
+        (
+            "api:v1:manage:moderation:instance-policies-list",
+            {},
+            "read:instance:policies",
+            "get",
+        ),
+        ("api:v1:manage:library:artists-list", {}, "read:instance:libraries", "get"),
+    ],
+)
+def test_views_permissions(
+    name, url_kwargs, scope, method, mocker, logged_in_api_client
+):
+    """
+    Smoke tests to ensure viewsets are correctly protected
+    """
+    url = reverse(name, kwargs=url_kwargs)
+    user_scopes = scopes.get_from_permissions(
+        **logged_in_api_client.user.get_permissions()
+    )
+
+    should_allow = mocker.patch(
+        "funkwhale_api.users.oauth.permissions.should_allow", return_value=False
+    )
+    handler = getattr(logged_in_api_client, method)
+    response = handler(url)
+    should_allow.assert_called_once_with(
+        required_scope=scope, request_scopes=user_scopes
+    )
+    assert response.status_code == 403, "{} on {} is not protected correctly!".format(
+        method, url
+    )
diff --git a/api/tests/users/oauth/test_models.py b/api/tests/users/oauth/test_models.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b27900ee825568961f4d139128a09ce14d558a2
--- /dev/null
+++ b/api/tests/users/oauth/test_models.py
@@ -0,0 +1,21 @@
+import pytest
+
+from django import forms
+
+from funkwhale_api.users import models
+
+
+@pytest.mark.parametrize(
+    "uri",
+    ["urn:ietf:wg:oauth:2.0:oob", "urn:ietf:wg:oauth:2.0:oob:auto", "http://test.com"],
+)
+def test_redirect_uris_oob(uri, db):
+    app = models.Application(redirect_uris=uri)
+    assert app.clean() is None
+
+
+@pytest.mark.parametrize("uri", ["urn:ietf:wg:oauth:2.0:invalid", "noop"])
+def test_redirect_uris_invalid(uri, db):
+    app = models.Application(redirect_uris=uri)
+    with pytest.raises(forms.ValidationError):
+        app.clean()
diff --git a/api/tests/users/oauth/test_permissions.py b/api/tests/users/oauth/test_permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..65974fbf645f92af478457fadd7138f7067a3a01
--- /dev/null
+++ b/api/tests/users/oauth/test_permissions.py
@@ -0,0 +1,241 @@
+import pytest
+
+from funkwhale_api.users.oauth import scopes
+from funkwhale_api.users.oauth import permissions
+
+
+@pytest.mark.parametrize(
+    "required_scope, request_scopes, expected",
+    [
+        (None, {}, True),
+        ("write:profile", {"write"}, True),
+        ("write:profile", {"read"}, False),
+        ("write:profile", {"read:profile"}, False),
+        ("write:profile", {"write:profile"}, True),
+        ("read:profile", {"read"}, True),
+        ("read:profile", {"write"}, False),
+        ("read:profile", {"read:profile"}, True),
+        ("read:profile", {"write:profile"}, False),
+        ("write:profile", {"write"}, True),
+        ("write:profile", {"read:profile"}, False),
+        ("write:profile", {"write:profile"}, True),
+        ("write:profile", {"write"}, True),
+        ("write:profile", {"read:profile"}, False),
+        ("write:profile", {"write:profile"}, True),
+        ("write:profile", {"write"}, True),
+        ("write:profile", {"read:profile"}, False),
+        ("write:profile", {"write:profile"}, True),
+    ],
+)
+def test_should_allow(required_scope, request_scopes, expected):
+    assert (
+        permissions.should_allow(
+            required_scope=required_scope, request_scopes=request_scopes
+        )
+        is expected
+    )
+
+
+@pytest.mark.parametrize("method", ["OPTIONS", "HEAD"])
+def test_scope_permission_safe_methods(method, mocker, factories):
+    view = mocker.Mock(required_scope="write:profile", anonymous_policy=False)
+    request = mocker.Mock(method=method)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) is True
+
+
+@pytest.mark.parametrize(
+    "policy, preference, expected",
+    [
+        (True, False, True),
+        (False, False, False),
+        ("setting", True, False),
+        ("setting", False, True),
+    ],
+)
+def test_scope_permission_anonymous_policy(
+    policy, preference, expected, preferences, mocker, anonymous_user
+):
+    preferences["common__api_authentication_required"] = preference
+    view = mocker.Mock(required_scope="libraries", anonymous_policy=policy)
+    request = mocker.Mock(method="GET", user=anonymous_user, actor=None)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) is expected
+
+
+def test_scope_permission_dict_no_required(mocker, anonymous_user):
+    view = mocker.Mock(
+        required_scope={"read": None, "write": "write:profile"},
+        anonymous_policy=True,
+        action="read",
+    )
+    request = mocker.Mock(method="GET", user=anonymous_user, actor=None)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) is True
+
+
+@pytest.mark.parametrize(
+    "required_scope, method, action, expected_scope",
+    [
+        ("profile", "GET", "read", "read:profile"),
+        ("profile", "POST", "write", "write:profile"),
+        ({"read": "read:profile"}, "GET", "read", "read:profile"),
+        ({"write": "write:profile"}, "POST", "write", "write:profile"),
+    ],
+)
+def test_scope_permission_user(
+    required_scope, method, action, expected_scope, mocker, factories
+):
+    user = factories["users.User"]()
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method=method, user=user, actor=None)
+    view = mocker.Mock(
+        required_scope=required_scope, anonymous_policy=False, action=action
+    )
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) == should_allow.return_value
+
+    should_allow.assert_called_once_with(
+        required_scope=expected_scope,
+        request_scopes=scopes.get_from_permissions(**user.get_permissions()),
+    )
+
+
+def test_scope_permission_token(mocker, factories):
+    token = factories["users.AccessToken"](
+        scope="write:profile read:playlists",
+        application__scope="write:profile read:playlists",
+    )
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", auth=token)
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) == should_allow.return_value
+
+    should_allow.assert_called_once_with(
+        required_scope="write:profile",
+        request_scopes={"write:profile", "read:playlists"},
+    )
+
+
+def test_scope_permission_actor(mocker, factories, anonymous_user):
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(
+        method="POST", actor=factories["federation.Actor"](), user=anonymous_user
+    )
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) == should_allow.return_value
+
+    should_allow.assert_called_once_with(
+        required_scope="write:profile", request_scopes=scopes.FEDERATION_REQUEST_SCOPES
+    )
+
+
+def test_scope_permission_token_anonymous_user_auth_required(
+    mocker, factories, anonymous_user, preferences
+):
+    preferences["common__api_authentication_required"] = True
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", user=anonymous_user, actor=None)
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) is False
+
+    should_allow.assert_not_called()
+
+
+def test_scope_permission_token_anonymous_user_auth_not_required(
+    mocker, factories, anonymous_user, preferences
+):
+    preferences["common__api_authentication_required"] = False
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", user=anonymous_user, actor=None)
+    view = mocker.Mock(required_scope="profile", anonymous_policy="setting")
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) == should_allow.return_value
+
+    should_allow.assert_called_once_with(
+        required_scope="write:profile", request_scopes=scopes.ANONYMOUS_SCOPES
+    )
+
+
+def test_scope_permission_token_expired(mocker, factories, now):
+    token = factories["users.AccessToken"](
+        scope="profile:write playlists:read", expires=now
+    )
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", auth=token)
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) is False
+
+    should_allow.assert_not_called()
+
+
+def test_scope_permission_token_no_user(mocker, factories, now):
+    token = factories["users.AccessToken"](
+        scope="profile:write playlists:read", user=None
+    )
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", auth=token)
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) is False
+
+    should_allow.assert_not_called()
+
+
+def test_scope_permission_token_honor_app_scopes(mocker, factories, now):
+    # token contains read access, but app scope only allows profile:write
+    token = factories["users.AccessToken"](
+        scope="write:profile read", application__scope="write:profile"
+    )
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", auth=token)
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) == should_allow.return_value
+
+    should_allow.assert_called_once_with(
+        required_scope="write:profile", request_scopes={"write:profile"}
+    )
+
+
+def test_scope_permission_token_honor_allowed_app_scopes(mocker, factories, now):
+    mocker.patch.object(scopes, "OAUTH_APP_SCOPES", {"read:profile"})
+    token = factories["users.AccessToken"](
+        scope="write:profile read:profile read",
+        application__scope="write:profile read:profile read",
+    )
+    should_allow = mocker.patch.object(permissions, "should_allow")
+    request = mocker.Mock(method="POST", auth=token)
+    view = mocker.Mock(required_scope="profile", anonymous_policy=False)
+    p = permissions.ScopePermission()
+
+    assert p.has_permission(request, view) == should_allow.return_value
+
+    should_allow.assert_called_once_with(
+        required_scope="write:profile", request_scopes={"read:profile"}
+    )
diff --git a/api/tests/users/oauth/test_scopes.py b/api/tests/users/oauth/test_scopes.py
new file mode 100644
index 0000000000000000000000000000000000000000..3d12cb664e7dadcdc078706b0e79fae1764fe221
--- /dev/null
+++ b/api/tests/users/oauth/test_scopes.py
@@ -0,0 +1,156 @@
+import pytest
+
+from funkwhale_api.users.oauth import scopes
+
+
+@pytest.mark.parametrize(
+    "user_perms, expected",
+    [
+        (
+            # All permissions, so all scopes
+            {"moderation": True, "library": True, "settings": True},
+            {
+                "read:profile",
+                "write:profile",
+                "read:libraries",
+                "write:libraries",
+                "read:playlists",
+                "write:playlists",
+                "read:favorites",
+                "write:favorites",
+                "read:notifications",
+                "write:notifications",
+                "read:radios",
+                "write:radios",
+                "read:follows",
+                "write:follows",
+                "read:edits",
+                "write:edits",
+                "read:filters",
+                "write:filters",
+                "read:listenings",
+                "write:listenings",
+                "read:security",
+                "write:security",
+                "read:instance:policies",
+                "write:instance:policies",
+                "read:instance:accounts",
+                "write:instance:accounts",
+                "read:instance:domains",
+                "write:instance:domains",
+                "read:instance:settings",
+                "write:instance:settings",
+                "read:instance:users",
+                "write:instance:users",
+                "read:instance:invitations",
+                "write:instance:invitations",
+                "read:instance:edits",
+                "write:instance:edits",
+                "read:instance:libraries",
+                "write:instance:libraries",
+            },
+        ),
+        (
+            {"moderation": True, "library": False, "settings": True},
+            {
+                "read:profile",
+                "write:profile",
+                "read:libraries",
+                "write:libraries",
+                "read:playlists",
+                "write:playlists",
+                "read:favorites",
+                "write:favorites",
+                "read:notifications",
+                "write:notifications",
+                "read:radios",
+                "write:radios",
+                "read:follows",
+                "write:follows",
+                "read:edits",
+                "write:edits",
+                "read:filters",
+                "write:filters",
+                "read:listenings",
+                "write:listenings",
+                "read:security",
+                "write:security",
+                "read:instance:policies",
+                "write:instance:policies",
+                "read:instance:accounts",
+                "write:instance:accounts",
+                "read:instance:domains",
+                "write:instance:domains",
+                "read:instance:settings",
+                "write:instance:settings",
+                "read:instance:users",
+                "write:instance:users",
+                "read:instance:invitations",
+                "write:instance:invitations",
+            },
+        ),
+        (
+            {"moderation": True, "library": False, "settings": False},
+            {
+                "read:profile",
+                "write:profile",
+                "read:libraries",
+                "write:libraries",
+                "read:playlists",
+                "write:playlists",
+                "read:favorites",
+                "write:favorites",
+                "read:notifications",
+                "write:notifications",
+                "read:radios",
+                "write:radios",
+                "read:follows",
+                "write:follows",
+                "read:edits",
+                "write:edits",
+                "read:filters",
+                "write:filters",
+                "read:listenings",
+                "write:listenings",
+                "read:security",
+                "write:security",
+                "read:instance:policies",
+                "write:instance:policies",
+                "read:instance:accounts",
+                "write:instance:accounts",
+                "read:instance:domains",
+                "write:instance:domains",
+            },
+        ),
+        (
+            {"moderation": False, "library": False, "settings": False},
+            {
+                "read:profile",
+                "write:profile",
+                "read:libraries",
+                "write:libraries",
+                "read:playlists",
+                "write:playlists",
+                "read:favorites",
+                "write:favorites",
+                "read:notifications",
+                "write:notifications",
+                "read:radios",
+                "write:radios",
+                "read:follows",
+                "write:follows",
+                "read:edits",
+                "write:edits",
+                "read:filters",
+                "write:filters",
+                "read:listenings",
+                "write:listenings",
+                "read:security",
+                "write:security",
+            },
+        ),
+    ],
+)
+def test_get_scopes_from_user_permissions(user_perms, expected):
+
+    assert scopes.get_from_permissions(**user_perms) == expected
diff --git a/api/tests/users/oauth/test_tasks.py b/api/tests/users/oauth/test_tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..c30f2488371f1c38d8525ddee47b8c4dc417185a
--- /dev/null
+++ b/api/tests/users/oauth/test_tasks.py
@@ -0,0 +1,10 @@
+from oauth2_provider import models
+from funkwhale_api.users.oauth import tasks
+
+
+def test_clear_expired_tokens(mocker, db):
+    clear_expired = mocker.spy(models, "clear_expired")
+
+    tasks.clear_expired_tokens()
+
+    clear_expired.assert_called_once()
diff --git a/api/tests/users/oauth/test_views.py b/api/tests/users/oauth/test_views.py
new file mode 100644
index 0000000000000000000000000000000000000000..19d25870974fd0ee756fab765a20db06fd459186
--- /dev/null
+++ b/api/tests/users/oauth/test_views.py
@@ -0,0 +1,363 @@
+import json
+import pytest
+
+from django.urls import reverse
+
+from funkwhale_api.users import models
+from funkwhale_api.users.oauth import serializers
+
+
+def test_apps_post(api_client, db):
+    url = reverse("api:v1:oauth:apps-list")
+    data = {
+        "name": "Test app",
+        "redirect_uris": "http://test.app",
+        "scopes": "read write:profile",
+    }
+    response = api_client.post(url, data)
+
+    assert response.status_code == 201
+
+    app = models.Application.objects.get(name=data["name"])
+
+    assert app.client_type == models.Application.CLIENT_CONFIDENTIAL
+    assert app.authorization_grant_type == models.Application.GRANT_AUTHORIZATION_CODE
+    assert app.redirect_uris == data["redirect_uris"]
+    assert response.data == serializers.CreateApplicationSerializer(app).data
+    assert app.scope == "read write:profile"
+    assert app.user is None
+
+
+def test_apps_post_logged_in_user(logged_in_api_client, db):
+    url = reverse("api:v1:oauth:apps-list")
+    data = {
+        "name": "Test app",
+        "redirect_uris": "http://test.app",
+        "scopes": "read write:profile",
+    }
+    response = logged_in_api_client.post(url, data)
+
+    assert response.status_code == 201
+
+    app = models.Application.objects.get(name=data["name"])
+
+    assert app.client_type == models.Application.CLIENT_CONFIDENTIAL
+    assert app.authorization_grant_type == models.Application.GRANT_AUTHORIZATION_CODE
+    assert app.redirect_uris == data["redirect_uris"]
+    assert response.data == serializers.CreateApplicationSerializer(app).data
+    assert app.scope == "read write:profile"
+    assert app.user == logged_in_api_client.user
+
+
+def test_apps_list_anonymous(api_client, db):
+    url = reverse("api:v1:oauth:apps-list")
+    response = api_client.get(url)
+
+    assert response.status_code == 401
+
+
+def test_apps_list_logged_in(factories, logged_in_api_client, db):
+    app = factories["users.Application"](user=logged_in_api_client.user)
+    factories["users.Application"]()
+    url = reverse("api:v1:oauth:apps-list")
+    response = logged_in_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data["results"] == [serializers.ApplicationSerializer(app).data]
+
+
+def test_apps_delete_not_owner(factories, logged_in_api_client, db):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:apps-detail", kwargs={"client_id": app.client_id})
+    response = logged_in_api_client.delete(url)
+
+    assert response.status_code == 404
+
+
+def test_apps_delete_owner(factories, logged_in_api_client, db):
+    app = factories["users.Application"](user=logged_in_api_client.user)
+    url = reverse("api:v1:oauth:apps-detail", kwargs={"client_id": app.client_id})
+    response = logged_in_api_client.delete(url)
+
+    assert response.status_code == 204
+
+    with pytest.raises(app.DoesNotExist):
+        app.refresh_from_db()
+
+
+def test_apps_update_not_owner(factories, logged_in_api_client, db):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:apps-detail", kwargs={"client_id": app.client_id})
+    response = logged_in_api_client.patch(url, {"name": "Hello"})
+
+    assert response.status_code == 404
+
+
+def test_apps_update_owner(factories, logged_in_api_client, db):
+    app = factories["users.Application"](user=logged_in_api_client.user)
+    url = reverse("api:v1:oauth:apps-detail", kwargs={"client_id": app.client_id})
+    response = logged_in_api_client.patch(url, {"name": "Hello"})
+
+    assert response.status_code == 200
+    app.refresh_from_db()
+
+    assert app.name == "Hello"
+
+
+def test_apps_get(preferences, logged_in_api_client, factories):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:apps-detail", kwargs={"client_id": app.client_id})
+    response = logged_in_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data == serializers.ApplicationSerializer(app).data
+
+
+def test_apps_get_owner(preferences, logged_in_api_client, factories):
+    app = factories["users.Application"](user=logged_in_api_client.user)
+    url = reverse("api:v1:oauth:apps-detail", kwargs={"client_id": app.client_id})
+    response = logged_in_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data == serializers.CreateApplicationSerializer(app).data
+
+
+def test_authorize_view_post(logged_in_client, factories):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:authorize")
+    response = logged_in_client.post(
+        url,
+        {
+            "allow": True,
+            "redirect_uri": app.redirect_uris,
+            "client_id": app.client_id,
+            "state": "hello",
+            "response_type": "code",
+            "scope": "read",
+        },
+    )
+    grant = models.Grant.objects.get(application=app)
+    assert response.status_code == 302
+    assert response["Location"] == "{}?code={}&state={}".format(
+        app.redirect_uris, grant.code, "hello"
+    )
+
+
+def test_authorize_view_post_ajax_no_redirect(logged_in_client, factories):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:authorize")
+    response = logged_in_client.post(
+        url,
+        {
+            "allow": True,
+            "redirect_uri": app.redirect_uris,
+            "client_id": app.client_id,
+            "state": "hello",
+            "response_type": "code",
+            "scope": "read",
+        },
+        HTTP_X_REQUESTED_WITH="XMLHttpRequest",
+    )
+    assert response.status_code == 200
+    grant = models.Grant.objects.get(application=app)
+    assert json.loads(response.content.decode()) == {
+        "redirect_uri": "{}?code={}&state={}".format(
+            app.redirect_uris, grant.code, "hello"
+        ),
+        "code": grant.code,
+    }
+
+
+def test_authorize_view_post_ajax_oob(logged_in_client, factories):
+    app = factories["users.Application"](redirect_uris="urn:ietf:wg:oauth:2.0:oob")
+    url = reverse("api:v1:oauth:authorize")
+    response = logged_in_client.post(
+        url,
+        {
+            "allow": True,
+            "redirect_uri": app.redirect_uris,
+            "client_id": app.client_id,
+            "state": "hello",
+            "response_type": "code",
+            "scope": "read",
+        },
+        HTTP_X_REQUESTED_WITH="XMLHttpRequest",
+    )
+    assert response.status_code == 200
+    grant = models.Grant.objects.get(application=app)
+    assert json.loads(response.content.decode()) == {
+        "redirect_uri": "{}?code={}&state={}".format(
+            app.redirect_uris, grant.code, "hello"
+        ),
+        "code": grant.code,
+    }
+
+
+def test_authorize_view_invalid_form(logged_in_client, factories):
+    url = reverse("api:v1:oauth:authorize")
+    response = logged_in_client.post(
+        url,
+        {
+            "allow": True,
+            "redirect_uri": "",
+            "client_id": "Noop",
+            "state": "hello",
+            "response_type": "code",
+            "scope": "read",
+        },
+    )
+
+    assert response.status_code == 400
+    assert json.loads(response.content.decode()) == {
+        "redirect_uri": ["This field is required."]
+    }
+
+
+def test_authorize_view_invalid_redirect_url(logged_in_client, factories):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:authorize")
+    response = logged_in_client.post(
+        url,
+        {
+            "allow": True,
+            "redirect_uri": "http://wrong.url",
+            "client_id": app.client_id,
+            "state": "hello",
+            "response_type": "code",
+            "scope": "read",
+        },
+    )
+
+    assert response.status_code == 400
+    assert json.loads(response.content.decode()) == {
+        "detail": "Mismatching redirect URI."
+    }
+
+
+def test_authorize_view_invalid_oauth(logged_in_client, factories):
+    app = factories["users.Application"]()
+    url = reverse("api:v1:oauth:authorize")
+    response = logged_in_client.post(
+        url,
+        {
+            "allow": True,
+            "redirect_uri": app.redirect_uris,
+            "client_id": "wrong_id",
+            "state": "hello",
+            "response_type": "code",
+            "scope": "read",
+        },
+    )
+
+    assert response.status_code == 400
+    assert json.loads(response.content.decode()) == {
+        "non_field_errors": ["Invalid application"]
+    }
+
+
+def test_authorize_view_anonymous(client, factories):
+    url = reverse("api:v1:oauth:authorize")
+    response = client.post(url, {})
+
+    assert response.status_code == 401
+
+
+def test_token_view_post(api_client, factories):
+    grant = factories["users.Grant"]()
+    app = grant.application
+    url = reverse("api:v1:oauth:token")
+
+    response = api_client.post(
+        url,
+        {
+            "redirect_uri": app.redirect_uris,
+            "client_id": app.client_id,
+            "client_secret": app.client_secret,
+            "grant_type": "authorization_code",
+            "code": grant.code,
+        },
+    )
+    payload = json.loads(response.content.decode())
+
+    assert "access_token" in payload
+    assert "refresh_token" in payload
+    assert payload["expires_in"] == 36000
+    assert payload["scope"] == grant.scope
+    assert payload["token_type"] == "Bearer"
+    assert response.status_code == 200
+
+    with pytest.raises(grant.DoesNotExist):
+        grant.refresh_from_db()
+
+
+def test_revoke_view_post(logged_in_client, factories):
+    token = factories["users.AccessToken"]()
+    url = reverse("api:v1:oauth:revoke")
+
+    response = logged_in_client.post(
+        url,
+        {
+            "token": token.token,
+            "client_id": token.application.client_id,
+            "client_secret": token.application.client_secret,
+        },
+    )
+    assert response.status_code == 200
+
+    with pytest.raises(token.DoesNotExist):
+        token.refresh_from_db()
+
+
+def test_grants_list(factories, logged_in_api_client):
+    token = factories["users.AccessToken"](user=logged_in_api_client.user)
+    refresh_token = factories["users.RefreshToken"](user=logged_in_api_client.user)
+    factories["users.AccessToken"]()
+    url = reverse("api:v1:oauth:grants-list")
+    expected = [
+        serializers.ApplicationSerializer(refresh_token.application).data,
+        serializers.ApplicationSerializer(token.application).data,
+    ]
+
+    response = logged_in_api_client.get(url)
+
+    assert response.status_code == 200
+    assert response.data == expected
+
+
+def test_grant_delete(factories, logged_in_api_client, mocker, now):
+    token = factories["users.AccessToken"](user=logged_in_api_client.user)
+    refresh_token = factories["users.RefreshToken"](
+        user=logged_in_api_client.user, application=token.application
+    )
+    grant = factories["users.Grant"](
+        user=logged_in_api_client.user, application=token.application
+    )
+    revoke_token = mocker.spy(token.__class__, "revoke")
+    revoke_refresh = mocker.spy(refresh_token.__class__, "revoke")
+    to_keep = [
+        factories["users.AccessToken"](application=token.application),
+        factories["users.RefreshToken"](application=token.application),
+        factories["users.Grant"](application=token.application),
+    ]
+    url = reverse(
+        "api:v1:oauth:grants-detail", kwargs={"client_id": token.application.client_id}
+    )
+
+    response = logged_in_api_client.delete(url)
+
+    assert response.status_code == 204
+
+    revoke_token.assert_called_once()
+    revoke_refresh.assert_called_once()
+
+    with pytest.raises(token.DoesNotExist):
+        token.refresh_from_db()
+
+    with pytest.raises(grant.DoesNotExist):
+        grant.refresh_from_db()
+
+    refresh_token.refresh_from_db()
+    assert refresh_token.revoked == now
+
+    for t in to_keep:
+        t.refresh_from_db()
diff --git a/api/tests/users/test_models.py b/api/tests/users/test_models.py
index 4b2f71bca02fa754bdb60615fd08d3e496d58013..1b185e55f88844baa9400a82c49dff3d706a24f7 100644
--- a/api/tests/users/test_models.py
+++ b/api/tests/users/test_models.py
@@ -219,3 +219,13 @@ def test_user_get_quota_status(factories, preferences, mocker):
         "errored": 3,
         "finished": 4,
     }
+
+
+def test_deleting_users_deletes_associated_actor(factories):
+    actor = factories["federation.Actor"]()
+    user = factories["users.User"](actor=actor)
+
+    user.delete()
+
+    with pytest.raises(actor.DoesNotExist):
+        actor.refresh_from_db()
diff --git a/api/tests/users/test_permissions.py b/api/tests/users/test_permissions.py
deleted file mode 100644
index 0b92f74a58ab7d914a0b15ceeb48b17e5abf95ae..0000000000000000000000000000000000000000
--- a/api/tests/users/test_permissions.py
+++ /dev/null
@@ -1,92 +0,0 @@
-import pytest
-from rest_framework.views import APIView
-
-from funkwhale_api.users import permissions
-
-
-def test_has_user_permission_no_user(api_request):
-    view = APIView.as_view()
-    permission = permissions.HasUserPermission()
-    request = api_request.get("/")
-    assert permission.has_permission(request, view) is False
-
-
-def test_has_user_permission_anonymous(anonymous_user, api_request):
-    view = APIView.as_view()
-    permission = permissions.HasUserPermission()
-    request = api_request.get("/")
-    setattr(request, "user", anonymous_user)
-    assert permission.has_permission(request, view) is False
-
-
-@pytest.mark.parametrize("value", [True, False])
-def test_has_user_permission_logged_in_single(value, factories, api_request):
-    user = factories["users.User"](permission_moderation=value)
-
-    class View(APIView):
-        required_permissions = ["moderation"]
-
-    view = View()
-    permission = permissions.HasUserPermission()
-    request = api_request.get("/")
-    setattr(request, "user", user)
-    result = permission.has_permission(request, view)
-    assert result == user.has_permissions("moderation") == value
-
-
-@pytest.mark.parametrize(
-    "moderation,library,expected",
-    [
-        (True, False, False),
-        (False, True, False),
-        (False, False, False),
-        (True, True, True),
-    ],
-)
-def test_has_user_permission_logged_in_multiple_and(
-    moderation, library, expected, factories, api_request
-):
-    user = factories["users.User"](
-        permission_moderation=moderation, permission_library=library
-    )
-
-    class View(APIView):
-        required_permissions = ["moderation", "library"]
-        permission_operator = "and"
-
-    view = View()
-    permission = permissions.HasUserPermission()
-    request = api_request.get("/")
-    setattr(request, "user", user)
-    result = permission.has_permission(request, view)
-    assert result == user.has_permissions("moderation", "library") == expected
-
-
-@pytest.mark.parametrize(
-    "moderation,library,expected",
-    [
-        (True, False, True),
-        (False, True, True),
-        (False, False, False),
-        (True, True, True),
-    ],
-)
-def test_has_user_permission_logged_in_multiple_or(
-    moderation, library, expected, factories, api_request
-):
-    user = factories["users.User"](
-        permission_moderation=moderation, permission_library=library
-    )
-
-    class View(APIView):
-        required_permissions = ["moderation", "library"]
-        permission_operator = "or"
-
-    view = View()
-    permission = permissions.HasUserPermission()
-    request = api_request.get("/")
-    setattr(request, "user", user)
-    result = permission.has_permission(request, view)
-    has_permission_result = user.has_permissions("moderation", "library", operator="or")
-
-    assert result == has_permission_result == expected
diff --git a/api/tests/users/test_views.py b/api/tests/users/test_views.py
index 92e9922bf0a6679641e10835a1b22c6eb2160ddb..956a7178cf98641e295cc6369d198cf954fd47e6 100644
--- a/api/tests/users/test_views.py
+++ b/api/tests/users/test_views.py
@@ -168,15 +168,20 @@ def test_changing_password_updates_secret_key(logged_in_api_client):
     assert user.password != password
 
 
-def test_can_request_password_reset(factories, api_client, mailoutbox):
+def test_can_request_password_reset(
+    factories, preferences, settings, api_client, mailoutbox
+):
     user = factories["users.User"]()
     payload = {"email": user.email}
-    emails = len(mailoutbox)
     url = reverse("rest_password_reset")
+    preferences["instance__name"] = "Hello world"
 
     response = api_client.post(url, payload)
     assert response.status_code == 200
-    assert len(mailoutbox) > emails
+
+    confirmation_message = mailoutbox[-1]
+    assert "Hello world" in confirmation_message.body
+    assert settings.FUNKWHALE_HOSTNAME in confirmation_message.body
 
 
 def test_user_can_patch_his_own_settings(logged_in_api_client):
@@ -225,6 +230,21 @@ def test_user_can_get_subsonic_token(logged_in_api_client):
     assert response.data == {"subsonic_api_token": "test"}
 
 
+def test_user_can_request_new_subsonic_token_uncommon_username(logged_in_api_client):
+    user = logged_in_api_client.user
+    user.username = "firstname.lastname"
+    user.subsonic_api_token = "test"
+    user.save()
+
+    url = reverse(
+        "api:v1:users:users-subsonic-token", kwargs={"username": user.username}
+    )
+
+    response = logged_in_api_client.post(url)
+
+    assert response.status_code == 200
+
+
 def test_user_can_delete_subsonic_token(logged_in_api_client):
     user = logged_in_api_client.user
     user.subsonic_api_token = "test"
@@ -287,3 +307,24 @@ def test_creating_user_creates_actor_as_well(
     user = User.objects.get(username="test1")
 
     assert user.actor == actor
+
+
+def test_creating_user_sends_confirmation_email(
+    api_client, db, settings, preferences, mailoutbox
+):
+    url = reverse("rest_register")
+    data = {
+        "username": "test1",
+        "email": "test1@test.com",
+        "password1": "testtest",
+        "password2": "testtest",
+    }
+    preferences["users__registration_enabled"] = True
+    preferences["instance__name"] = "Hello world"
+    response = api_client.post(url, data)
+
+    assert response.status_code == 201
+
+    confirmation_message = mailoutbox[-1]
+    assert "Hello world" in confirmation_message.body
+    assert settings.FUNKWHALE_HOSTNAME in confirmation_message.body
diff --git a/changes/changelog.d/252.feature b/changes/changelog.d/252.feature
new file mode 100644
index 0000000000000000000000000000000000000000..4bbb2da1e527d95e0546366c92bea1d819337d29
--- /dev/null
+++ b/changes/changelog.d/252.feature
@@ -0,0 +1 @@
+Improved error handling and display during import (#252, #718, #583, #501, #544)
diff --git a/changes/changelog.d/356.bugfix b/changes/changelog.d/356.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..c99d3687076fedd9d25ca8d452756644e638bd18
--- /dev/null
+++ b/changes/changelog.d/356.bugfix
@@ -0,0 +1 @@
+Fixed issue with querying the albums api endpoint (#356)
\ No newline at end of file
diff --git a/changes/changelog.d/356.feature b/changes/changelog.d/356.feature
new file mode 100644
index 0000000000000000000000000000000000000000..cf0744c18cd5d875d055a6ef9ade8fcf683cb3a4
--- /dev/null
+++ b/changes/changelog.d/356.feature
@@ -0,0 +1 @@
+Added albums view. Similar to artists view, it's viewable by clicking on the "Albums" link on the top bar. (#356)
\ No newline at end of file
diff --git a/changes/changelog.d/359.feature b/changes/changelog.d/359.feature
new file mode 100644
index 0000000000000000000000000000000000000000..657788c917af76f5698d12dd639f997f33286a46
--- /dev/null
+++ b/changes/changelog.d/359.feature
@@ -0,0 +1 @@
+Change the document title to display current track information. (#359)
diff --git a/changes/changelog.d/385.enhancement b/changes/changelog.d/385.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..aa6e0a676cd62d81f6e7fd589fc745a3350a1189
--- /dev/null
+++ b/changes/changelog.d/385.enhancement
@@ -0,0 +1 @@
+Improved readability of logo (#385)
diff --git a/changes/changelog.d/550.enhancement b/changes/changelog.d/550.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..1ec0243dee3ac42fb3108290d455579ca65357d3
--- /dev/null
+++ b/changes/changelog.d/550.enhancement
@@ -0,0 +1 @@
+Show remaining storage space during import and prevent file upload if not enough space is remaining (#550)
diff --git a/changes/changelog.d/563.bugfix b/changes/changelog.d/563.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..14f49b75e7a714b70554ba7a16b1e570b78fc9cc
--- /dev/null
+++ b/changes/changelog.d/563.bugfix
@@ -0,0 +1 @@
+Fixed unplayable radios for anonymous users (#563)
diff --git a/changes/changelog.d/565.feature b/changes/changelog.d/565.feature
new file mode 100644
index 0000000000000000000000000000000000000000..9f2a92a719bdd62b24b7f1292a7638bbc2947ac8
--- /dev/null
+++ b/changes/changelog.d/565.feature
@@ -0,0 +1 @@
+Support S3-compatible storages for media files (#565)
diff --git a/changes/changelog.d/572.enhancement b/changes/changelog.d/572.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..cb75911db6bbe484c220c45548dfe73ab8f97231
--- /dev/null
+++ b/changes/changelog.d/572.enhancement
@@ -0,0 +1 @@
+Preload next track in queue (#572)
diff --git a/changes/changelog.d/578.enhancement b/changes/changelog.d/578.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..073de471fd355f06832888baa9a5955d3d813808
--- /dev/null
+++ b/changes/changelog.d/578.enhancement
@@ -0,0 +1,2 @@
+Added twitter:* meta tags to detect tracks and albums players automatically on more sites (#578)
+Improved responsiveness of embedded player
\ No newline at end of file
diff --git a/changes/changelog.d/619.enhancement b/changes/changelog.d/619.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..16a95a641955503ad7c8325c5a526a3e5f70738c
--- /dev/null
+++ b/changes/changelog.d/619.enhancement
@@ -0,0 +1 @@
+Use attributedTo instead of actor in library ActivityPub payload (#619)
diff --git a/changes/changelog.d/662.enhancement b/changes/changelog.d/662.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..cda19e4ed3449e1e8a547e7d17b861d7e8fc6ea4
--- /dev/null
+++ b/changes/changelog.d/662.enhancement
@@ -0,0 +1 @@
+Added standardized translation context for all strings in the frontend to give accurate hints to translators.
diff --git a/changes/changelog.d/689.feature b/changes/changelog.d/689.feature
new file mode 100644
index 0000000000000000000000000000000000000000..0b53c4a09032aebdaeab41020807097c4fa472a3
--- /dev/null
+++ b/changes/changelog.d/689.feature
@@ -0,0 +1 @@
+Support metadata update on tracks, albums and artists and broadcast those on the federation (#689)
diff --git a/changes/changelog.d/701.feature b/changes/changelog.d/701.feature
new file mode 100644
index 0000000000000000000000000000000000000000..d2a9500d6b1fd40f6d4ec33dd9f034bc307cf37c
--- /dev/null
+++ b/changes/changelog.d/701.feature
@@ -0,0 +1 @@
+Allow artists hiding (#701)
diff --git a/changes/changelog.d/702.bugfix b/changes/changelog.d/702.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..3c8090fc43a93ce3c7e7f0000a6c3f12de0e6385
--- /dev/null
+++ b/changes/changelog.d/702.bugfix
@@ -0,0 +1 @@
+Fixed alignement/size issue with some buttons (#702)
\ No newline at end of file
diff --git a/changes/changelog.d/715.enhancement b/changes/changelog.d/715.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..faba8a62c1fdcc4aa4b79fe078233a49c24a429e
--- /dev/null
+++ b/changes/changelog.d/715.enhancement
@@ -0,0 +1,3 @@
+Better workflow for connecting to another instance (#715)
+
+Changing the instance used is now better integrated in the App, and it is checked that the chosen instance and the suggested instances are valid and running Funkwhale servers.
diff --git a/changes/changelog.d/718.bugfix b/changes/changelog.d/718.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..4dd1e13fef40808c95d8aeda080ef0e6e6a22cfb
--- /dev/null
+++ b/changes/changelog.d/718.bugfix
@@ -0,0 +1 @@
+Fixed crashing upload processing on invalid date format (#718)
diff --git a/changes/changelog.d/719.enhancement b/changes/changelog.d/719.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..e4c5b35bebdbe2d0d98793649ed71639a7ddd071
--- /dev/null
+++ b/changes/changelog.d/719.enhancement
@@ -0,0 +1 @@
+Added a "load more" button on artist pages to load more tracks/albums (#719)
diff --git a/changes/changelog.d/722.bugfix b/changes/changelog.d/722.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..9f230ae615e445ce1f38bc532745b69b1962e4d4
--- /dev/null
+++ b/changes/changelog.d/722.bugfix
@@ -0,0 +1 @@
+Fixed non-transparent background for volume range on Firefox (#722)
\ No newline at end of file
diff --git a/changes/changelog.d/725.enhancement b/changes/changelog.d/725.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..4c30ba4274f8212be0954614d7de5021cbee43e6
--- /dev/null
+++ b/changes/changelog.d/725.enhancement
@@ -0,0 +1 @@
+Merged artist/album buttons with title text on artist and album pages (#725)
diff --git a/changes/changelog.d/740.bugfix b/changes/changelog.d/740.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..5cf04c826906b92af522b2ca8850d7747e7f5da8
--- /dev/null
+++ b/changes/changelog.d/740.bugfix
@@ -0,0 +1 @@
+Do not consider tracks as duplicates during import if they have different positions (#740)
diff --git a/changes/changelog.d/747.feature b/changes/changelog.d/747.feature
new file mode 100644
index 0000000000000000000000000000000000000000..a278f0a1094c4675453af32fd329d37ad4f583dc
--- /dev/null
+++ b/changes/changelog.d/747.feature
@@ -0,0 +1 @@
+Support embedding full artist discographies (#747)
diff --git a/changes/changelog.d/748.enhancement b/changes/changelog.d/748.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..1515b08a27e9d8bb126f24000fd06599cefe92de
--- /dev/null
+++ b/changes/changelog.d/748.enhancement
@@ -0,0 +1 @@
+Labels for privacy levels are now consistently grabbed from a common source instead of being hardcoded everytime they are needed.
diff --git a/changes/changelog.d/752.feature b/changes/changelog.d/752.feature
new file mode 100644
index 0000000000000000000000000000000000000000..6d33f6faa629eacdf695111e2fa26c5a4929596f
--- /dev/null
+++ b/changes/changelog.d/752.feature
@@ -0,0 +1 @@
+Support OAuth2 authorization for better integration with third-party apps (#752)
diff --git a/changes/changelog.d/754.bugfix b/changes/changelog.d/754.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..dd7bc48c6dcc42cee6b59e8f079ae301fe424936
--- /dev/null
+++ b/changes/changelog.d/754.bugfix
@@ -0,0 +1 @@
+Add missing command from contributing file (#754)
diff --git a/changes/changelog.d/758.bugfix b/changes/changelog.d/758.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..3275ddbe1a32255b69fa4bc3ba2c6c7a44559d01
--- /dev/null
+++ b/changes/changelog.d/758.bugfix
@@ -0,0 +1 @@
+Ensure all our ActivityPub fetches are authenticated (#758)
diff --git a/changes/changelog.d/768.enhancement b/changes/changelog.d/768.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..4d0ab83e51af129f139b13e25d0594ce29fa6b84
--- /dev/null
+++ b/changes/changelog.d/768.enhancement
@@ -0,0 +1 @@
+Descriptions will now be shown underneath user libraries (#768)
\ No newline at end of file
diff --git a/changes/changelog.d/770.doc b/changes/changelog.d/770.doc
new file mode 100644
index 0000000000000000000000000000000000000000..4f419f20906586ac00af7da0916647e7c8854c0e
--- /dev/null
+++ b/changes/changelog.d/770.doc
@@ -0,0 +1 @@
+Document how to use Redis over unix sockets (#770)
diff --git a/changes/changelog.d/772.bugfix b/changes/changelog.d/772.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..5c0ddbeae0326003b432ac2fed62fc15c9994a47
--- /dev/null
+++ b/changes/changelog.d/772.bugfix
@@ -0,0 +1 @@
+Prevent skipping on file import if album_mbid is different (#772)
diff --git a/changes/changelog.d/776.enhancement b/changes/changelog.d/776.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..4cdf48815ade07870fb1e29ca05c5df836078d07
--- /dev/null
+++ b/changes/changelog.d/776.enhancement
@@ -0,0 +1 @@
+Don't store unhandled ActivityPub messages in database (#776)
diff --git a/changes/changelog.d/777.enhancement b/changes/changelog.d/777.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..96a46409e89e1fa0ff76ab68ac327ac5afac8cb1
--- /dev/null
+++ b/changes/changelog.d/777.enhancement
@@ -0,0 +1 @@
+Added a prune_library management command to remove obsolete metadata from the database (#777)
diff --git a/changes/changelog.d/781.enhancement b/changes/changelog.d/781.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..e3dd2597acfe16eda30c2b643d7f36267c55c0ec
--- /dev/null
+++ b/changes/changelog.d/781.enhancement
@@ -0,0 +1 @@
+Added a `check_inplace_files` management command to remove purge the database from references to in-place imported files that don't exist on disk anymore (#781)
diff --git a/changes/changelog.d/782.bugfix b/changes/changelog.d/782.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..16b0ccdd40e6d062b886dd187d4de54ddcb0763f
--- /dev/null
+++ b/changes/changelog.d/782.bugfix
@@ -0,0 +1 @@
+Better handling of featuring/multi-artist tracks tagged with MusicBrainz (#782)
diff --git a/changes/changelog.d/784.feature b/changes/changelog.d/784.feature
new file mode 100644
index 0000000000000000000000000000000000000000..8e61fb6e35068e8539958c70854b3a032c394957
--- /dev/null
+++ b/changes/changelog.d/784.feature
@@ -0,0 +1 @@
+Display a confirmation dialog when adding duplicate songs to a playlist (#784)
diff --git a/changes/changelog.d/791.bugfix b/changes/changelog.d/791.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..ef5c5c6966ebb9d8f8affb07693fc148f20580a4
--- /dev/null
+++ b/changes/changelog.d/791.bugfix
@@ -0,0 +1 @@
+Fixed overflowing input on account detail page (#791)
diff --git a/changes/changelog.d/795.bugfix b/changes/changelog.d/795.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..13191c0f12eba16f62c3512a06f233b3cf5a1f8e
--- /dev/null
+++ b/changes/changelog.d/795.bugfix
@@ -0,0 +1 @@
+Fixed cover not showing in queue/player when playing tracks from "albums" tab (#795)
diff --git a/changes/changelog.d/798.bugfix b/changes/changelog.d/798.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..d1cd2eb6c34d224e507b3028b47c8019dfc4d279
--- /dev/null
+++ b/changes/changelog.d/798.bugfix
@@ -0,0 +1 @@
+Allow users with dots in their usernames to request a subsonic password (#798)
diff --git a/changes/changelog.d/799.enhancement b/changes/changelog.d/799.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..5b24ee44ce116defe104e4854b168058481fa1c7
--- /dev/null
+++ b/changes/changelog.d/799.enhancement
@@ -0,0 +1 @@
+Removed broken/instable lyrics feature (#799)
diff --git a/changes/changelog.d/802.enhancement b/changes/changelog.d/802.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..25d4f3e5daf3bd3e0e63963ad110bcfe4df0c739
--- /dev/null
+++ b/changes/changelog.d/802.enhancement
@@ -0,0 +1 @@
+Now honor maxBitrate parameter in Subsonic API (#802)
diff --git a/changes/changelog.d/805.enhancement b/changes/changelog.d/805.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..e11e2493bd95909ee6f92e8bcba65efee893a07a
--- /dev/null
+++ b/changes/changelog.d/805.enhancement
@@ -0,0 +1 @@
+Reduced app size for regular users by moving admin-related code in a dedicated chunk (#805)
diff --git a/changes/changelog.d/806.bugfix b/changes/changelog.d/806.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..7a2f0b518632387969f79afdcda97f9696172cd9
--- /dev/null
+++ b/changes/changelog.d/806.bugfix
@@ -0,0 +1 @@
+Use proper site name/domain in emails (#806)
diff --git a/changes/changelog.d/808.enhancement b/changes/changelog.d/808.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..8a114ee6d38fa5d4852a8e0a2d6d4f849b26512b
--- /dev/null
+++ b/changes/changelog.d/808.enhancement
@@ -0,0 +1 @@
+Advertise the list of supported upload extensions in the Nodeinfo endpoint (#808)
diff --git a/changes/changelog.d/809.enhancement b/changes/changelog.d/809.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..92a4e57bc7793bc64ed1ee8aed7c73eee4ebc39f
--- /dev/null
+++ b/changes/changelog.d/809.enhancement
@@ -0,0 +1 @@
+Added admin options to disable login for users, ensure related content is deleted when deleting a user account (#809)
diff --git a/changes/changelog.d/812.bugfix b/changes/changelog.d/812.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..ec604dcec4ceae9f3960618493435abfef594d7d
--- /dev/null
+++ b/changes/changelog.d/812.bugfix
@@ -0,0 +1 @@
+Ensure correct track duration and playable status when browsing radios (#812)
diff --git a/changes/changelog.d/815.enhancement b/changes/changelog.d/815.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..5635fb00a2b48d178d8c51f9d35f734465adda73
--- /dev/null
+++ b/changes/changelog.d/815.enhancement
@@ -0,0 +1 @@
+Bumped dependencies to latest versions (#815)
diff --git a/changes/changelog.d/819.bugfix b/changes/changelog.d/819.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..a1977568c3b00c959bbdfb1595baea49f71aeebc
--- /dev/null
+++ b/changes/changelog.d/819.bugfix
@@ -0,0 +1 @@
+Fixed invalid required fields in Upload django's admin (#819)
diff --git a/changes/changelog.d/822.bugfix b/changes/changelog.d/822.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..547a6acd2e5de098279db33085e7021c1a7ba3d6
--- /dev/null
+++ b/changes/changelog.d/822.bugfix
@@ -0,0 +1 @@
+Width of filter menus for radios has been set to stop text from overlapping the borders
\ No newline at end of file
diff --git a/changes/changelog.d/824.bugfix b/changes/changelog.d/824.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..fa681a4e0e62fd4d00f7ac61227a1967532fe6d9
--- /dev/null
+++ b/changes/changelog.d/824.bugfix
@@ -0,0 +1 @@
+Fixed invalid OEmbed URL when using a local FUNKWHALE_SPA_HTML_ROOT (#824)
diff --git a/changes/changelog.d/826.bugfix b/changes/changelog.d/826.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..6cf7c25cb9dbb7536fc783283de5ff6eeb27bec7
--- /dev/null
+++ b/changes/changelog.d/826.bugfix
@@ -0,0 +1 @@
+Added env variable to set AWS region and signature version to serve media without proxy (#826)
diff --git a/changes/changelog.d/828.bugfix b/changes/changelog.d/828.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..768ebcbd1e32252c4ff5bcf4fc6d9c6ee2374f13
--- /dev/null
+++ b/changes/changelog.d/828.bugfix
@@ -0,0 +1 @@
+Fixed an encoding issue with instance name on about page (#828)
diff --git a/changes/changelog.d/830.enhancement b/changes/changelog.d/830.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..190c1127d79231191c313410f28e95a2eac34bc5
--- /dev/null
+++ b/changes/changelog.d/830.enhancement
@@ -0,0 +1 @@
+Better handling of follow/accept messages to avoid and recover from desync between instances (#830)
diff --git a/changes/changelog.d/buttons.enhancement b/changes/changelog.d/buttons.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..a7a079d249f6e5e862e50c68d4d90f8136decf74
--- /dev/null
+++ b/changes/changelog.d/buttons.enhancement
@@ -0,0 +1 @@
+The buttons displaying an icon now always show a little divider between the icon and the text. (!620)
diff --git a/changes/changelog.d/compose.enhancement b/changes/changelog.d/compose.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..bab1ca5e97a0cd0d3151683d6f61165d69c976a7
--- /dev/null
+++ b/changes/changelog.d/compose.enhancement
@@ -0,0 +1 @@
+Use network/depends_on instead of links in docker-compose.yml (!716)
\ No newline at end of file
diff --git a/changes/changelog.d/db.enhancement b/changes/changelog.d/db.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..396d9daa71fc2654462e96f5867475ea32ea2041
--- /dev/null
+++ b/changes/changelog.d/db.enhancement
@@ -0,0 +1 @@
+Keep persistent connections to the database instead of recreating a new one for each request
diff --git a/changes/changelog.d/embed-wizard.enhancement b/changes/changelog.d/embed-wizard.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..7c34913229866a89f5e3219345cfdd378769de27
--- /dev/null
+++ b/changes/changelog.d/embed-wizard.enhancement
@@ -0,0 +1 @@
+Enhanced the design of the embed wizard. (!619)
diff --git a/changes/changelog.d/envvar-spa-root.bugfix b/changes/changelog.d/envvar-spa-root.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..42b66e817c436134cf5a69bc333a7f10e85d904c
--- /dev/null
+++ b/changes/changelog.d/envvar-spa-root.bugfix
@@ -0,0 +1 @@
+Add required envvar for dev environment (!668)
diff --git a/changes/changelog.d/factories.bugfix b/changes/changelog.d/factories.bugfix
new file mode 100644
index 0000000000000000000000000000000000000000..58fa58074c6a99455734a2b6d59312ed4a99c5a3
--- /dev/null
+++ b/changes/changelog.d/factories.bugfix
@@ -0,0 +1 @@
+Fixed dev command for fake data creation (!664)
diff --git a/changes/changelog.d/footer.enhancement b/changes/changelog.d/footer.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..e2c117ead13d49e985c78812406f4ef7d54f15eb
--- /dev/null
+++ b/changes/changelog.d/footer.enhancement
@@ -0,0 +1 @@
+Ensure the footer always stays at the bottom of the page
diff --git a/changes/changelog.d/similar-radio.enhancement b/changes/changelog.d/similar-radio.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..d4c0a58de6adcb2fb789953dc8da9b59d60841a8
--- /dev/null
+++ b/changes/changelog.d/similar-radio.enhancement
@@ -0,0 +1 @@
+[Experimental] Added a new "Similar" radio based on users history (suggested by @gordon)
diff --git a/changes/changelog.d/system-actor.enhancement b/changes/changelog.d/system-actor.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..25c5534a862c73b3f121f5bf08cdc90b69dbe3ef
--- /dev/null
+++ b/changes/changelog.d/system-actor.enhancement
@@ -0,0 +1 @@
+Expose an instance-level actor (service@domain) in nodeinfo endpoint (#689)
diff --git a/changes/notes.rst b/changes/notes.rst
index 96ac3d7651f92166072a2fb200c0dd57606851e3..40f7e3c59dad0be11ab443d4b7b05349f83df0ea 100644
--- a/changes/notes.rst
+++ b/changes/notes.rst
@@ -5,3 +5,107 @@ Next release notes
 
     Those release notes refer to the current development branch and are reset
     after each release.
+
+Edits on tracks, albums and artists
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Funkwhale was a bit annoying when it camed to metadata. Tracks, albums and artists profiles
+were created from audio file tags, but basically immutable after that (unless you had
+admin access to Django's UI, which wasn't ideal to do this kind of changes).
+
+With this release, everyone can suggest changes on track, album and artist pages. Users
+with the "library" permission can review suggested edits in a dedicated interface
+and apply/reject them.
+
+Approved edits are broadcasted via federation, to ensure other instances get the information
+too.
+
+Not all fields are currently modifiable using this feature. Especially, it's not possible
+to suggest a new album cover, or reassign a track to a different album or artist. Those will
+be implemented in a future release.
+
+Admin UI for tracks, albums, artists, libraries and uploads
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As part of our ongoing effort to make Funkwhale easier to manage for instance owners,
+this release includes a brand new administration interface to deal with:
+
+- tracks
+- albums
+- artists
+- libraries
+- uploads
+
+You can use this UI to quickly search for any object, delete objects in batch, understand
+where they are coming from etc. This new UI should remove the need to go through Django's
+admin in the vast majority of cases (but also includes a link to Django's admin when needed).
+
+
+Artist hiding in the interface
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It's now possible for users to hide artists they don't want to see.
+
+Content linked to hidden artists will not show up in the interface anymore. Especially:
+
+- Hidden artists tracks are removed from the current queue
+- Starting a playlist will skip tracks from hidden artists
+- Recently favorited, recently listened and recently added widgets on the homepage won't include content from hidden artists
+- Radio suggestions will exclude tracks from hidden artists
+- Hidden artists won't appear in Subsonic apps
+
+Results linked to hidden artists will continue to show up in search results and their profile page remains accessible.
+
+OAuth2 authorization for better integration with third-party apps
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Funkwhale now support the OAuth2 authorization and authentication protocol which will allow
+third-party apps to interact with Funkwhale on behalf of users.
+
+This feature makes it possible to build third-party apps that have the same capabilities
+as Funkwhale's Web UI. The only exception at the moment is for actions that requires
+special permissions, such as modifying instance settings or moderation (but this will be
+enabled in a future release).
+
+If you want to start building an app on top of Funkwhale's API, please check-out
+`https://docs.funkwhale.audio/api.html`_ and `https://docs.funkwhale.audio/developers/authentication.html`_.
+
+Better error handling and display during import
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Funkwhale should now be more resilient to missing tags in imported files, and give
+you more insights when something goes wrong, including the specific tags that were missing
+or invalid, and additional debug information to share in your support requests.
+
+This information is available in all pages that list uploads, when clicking on the button next to the upload status.
+
+Support for S3-compatible storages to store media files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Storing all media files on the Funkwhale server itself may not be possible or desirable
+in all scenarios. You can now configure Funkwhale to store those files in a S3
+bucket instead.
+
+Check-out `https://docs.funkwhale.audio/admin/external-storages.html`_ if you want to use
+this feature.
+
+Prune library command
+^^^^^^^^^^^^^^^^^^^^^
+
+Users are often surprised by Funkwhale's tendency to keep track, album and artist
+metadata even if no associated files exist.
+
+To help with that, we now offer a ``prune_library`` management command you can run
+to purge your database from obsolete entries. `Please refer to our documentation
+for usage instructions <https://docs.funkwhale.audio/admin/commands.html#pruning-library>`_.
+
+Check in-place files command
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using in-place import with a living audio library, you'll quite often rename or
+remove files from the file system. Unfortunately, Funkwhale keeps a reference to those
+files in the database, which results in unplayable tracks.
+
+To help with that, we now offer a ``check_inplace_files`` management command you can run
+to purge your database from obsolete files. `Please refer to our documentation
+for usage instructions <https://docs.funkwhale.audio/admin/commands.html#remove-obsolete-files-from-database>`_.
diff --git a/deploy/Gentoo/.gitkeep b/deploy/Gentoo/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/deploy/Gentoo/README.md b/deploy/Gentoo/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b4f90b6609d33cc9317c320a9270c7f796291b2b
--- /dev/null
+++ b/deploy/Gentoo/README.md
@@ -0,0 +1,19 @@
+### Gentoo init scripts 
+
+Copy the files to  `/etc/init.d/`
+
+```
+# cp /path/to/scripts/funkwhale_* /etc/init.d/
+```
+
+Make the files executable:
+
+```
+# chmod +x /etc/init.d/funkwhale_*
+```
+
+Starting funkwhale_server will automatically start the other two, as well as nginx and redis.
+
+```
+# rc-service funkwhale_server start
+```
\ No newline at end of file
diff --git a/deploy/Gentoo/funkwhale_beat b/deploy/Gentoo/funkwhale_beat
new file mode 100644
index 0000000000000000000000000000000000000000..49d427437a26c9f0bfe9a74777da48537960ff56
--- /dev/null
+++ b/deploy/Gentoo/funkwhale_beat
@@ -0,0 +1,27 @@
+#!/sbin/openrc-run
+NAME=funkwhalebeat
+PIDFILE=/var/run/$NAME.pid
+USER=funkwhale
+WORKDIR=/srv/funkwhale/api 
+Celery=/srv/funkwhale/virtualenv/bin/celery 
+BEAT_ARGS="-A funkwhale_api.taskapp beat -l INFO"
+depend() {
+        need net 
+}
+
+start() {
+	ebegin "Starting Funkwhale Beat"
+        cd /srv/funkwhale/api
+	set -a && source /srv/funkwhale/config/.env && set +a
+	echo ' start beat' 
+	start-stop-daemon --start --user $USER --make-pidfile --pidfile $PIDFILE  -d $WORKDIR  --exec $Celery -- $BEAT_ARGS >> /var/log/funk/worker.log 2>&1&
+        echo 'Started Beat'
+	echo
+	eend $?
+}
+
+stop() {
+	ebegin "Stopping Funkwhale Beat"
+	start-stop-daemon --stop --pidfile $PIDFILE
+	eend $?
+}
diff --git a/deploy/Gentoo/funkwhale_server b/deploy/Gentoo/funkwhale_server
new file mode 100644
index 0000000000000000000000000000000000000000..926bd01d16610d984c6132ea04c72adf1dbc6131
--- /dev/null
+++ b/deploy/Gentoo/funkwhale_server
@@ -0,0 +1,29 @@
+#!/sbin/openrc-run
+
+NAME=funkwhaleserver
+PIDFILE=/var/run/$NAME.pid
+USER=funkwhale
+DAEMON_ARGS="-b 127.0.0.1 -p 5000 config.asgi:application --proxy-headers "
+Daphne=/srv/funkwhale/virtualenv/bin/daphne
+WORKDIR=/srv/funkwhale/api 
+
+depend() {
+        need net redis postgresql nginx funkwhale_beat funkwhale_worker
+}
+
+start() {
+	ebegin "Starting Funkwhale Server"
+        cd /srv/funkwhale/api
+	set -a && source /srv/funkwhale/config/.env && set +a
+        echo 'Starting Funkwhale Server'
+	start-stop-daemon --start --user $USER --make-pidfile --pidfile $PIDFILE  -d $WORKDIR  --exec $Daphne -- $DAEMON_ARGS >> /var/log/funk/daphne.log 2>&1&
+	echo 'Funkwhale Server started'
+	echo
+	eend $?
+}
+
+stop() {
+	ebegin "Stopping Funkwhale"
+	start-stop-daemon --stop --pidfile $PIDFILE
+	eend $?
+}
diff --git a/deploy/Gentoo/funkwhale_worker b/deploy/Gentoo/funkwhale_worker
new file mode 100644
index 0000000000000000000000000000000000000000..faa54f292925ac63ec59a7b2d476bec4bc4670e3
--- /dev/null
+++ b/deploy/Gentoo/funkwhale_worker
@@ -0,0 +1,28 @@
+#!/sbin/openrc-run
+NAME=funkwhaleworker
+PIDFILE=/var/run/$NAME.pid
+USER=funkwhale
+WORKDIR=/srv/funkwhale/api 
+Celery=/srv/funkwhale/virtualenv/bin/celery 
+WORKER_ARGS=" -A funkwhale_api.taskapp worker -l INFO"
+
+depend() {
+        need net 
+}
+
+start() {
+	ebegin "Starting Funkwhale Worker"
+        cd /srv/funkwhale/api
+	set -a && source /srv/funkwhale/config/.env && set +a
+	echo ' start beat' 
+	start-stop-daemon --start --user $USER --make-pidfile --pidfile $PIDFILE  -d $WORKDIR  --exec $Celery -- $WORKER_ARGS >> /var/log/funk/worker.log 2>&1&
+        echo 'Started Worker'
+	echo
+	eend $?
+}
+
+stop() {
+	ebegin "Stopping Funkwhale Worker"
+	start-stop-daemon --stop --pidfile $PIDFILE
+	eend $?
+}
diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml
index 89ab61c99721bcf1c2002514e610a1c2173ffe53..bcf24422f9591414c18e5e51f833ed4d1e9bfb73 100644
--- a/deploy/docker-compose.yml
+++ b/deploy/docker-compose.yml
@@ -3,6 +3,8 @@ version: "3"
 services:
   postgres:
     restart: unless-stopped
+    networks:
+      - default
     env_file: .env
     image: postgres:11
     volumes:
@@ -10,6 +12,8 @@ services:
 
   redis:
     restart: unless-stopped
+    networks:
+      - default
     env_file: .env
     image: redis:3
     volumes:
@@ -18,6 +22,11 @@ services:
   celeryworker:
     restart: unless-stopped
     image: funkwhale/funkwhale:${FUNKWHALE_VERSION:-latest}
+    networks:
+      - default
+    depends_on:
+      - postgres
+      - redis
     env_file: .env
     # Celery workers handle background tasks (such file imports or federation
     # messaging). The more processes a worker gets, the more tasks
@@ -28,9 +37,6 @@ services:
     # flag:
     #   celery -A funkwhale_api.taskapp worker -l INFO --concurrency=4
     command: celery -A funkwhale_api.taskapp worker -l INFO
-    links:
-      - postgres
-      - redis
     environment:
       - C_FORCE_ROOT=true
     volumes:
@@ -40,15 +46,22 @@ services:
   celerybeat:
     restart: unless-stopped
     image: funkwhale/funkwhale:${FUNKWHALE_VERSION:-latest}
-    env_file: .env
-    command: celery -A funkwhale_api.taskapp beat -l INFO
-    links:
+    networks:
+      - default
+    depends_on:
       - postgres
       - redis
+    env_file: .env
+    command: celery -A funkwhale_api.taskapp beat -l INFO
 
   api:
     restart: unless-stopped
     image: funkwhale/funkwhale:${FUNKWHALE_VERSION:-latest}
+    networks:
+      - default
+    depends_on:
+      - postgres
+      - redis
     env_file: .env
     volumes:
       - "${MUSIC_DIRECTORY_SERVE_PATH-/srv/funkwhale/data/music}:${MUSIC_DIRECTORY_PATH-/music}:ro"
@@ -57,13 +70,14 @@ services:
       - "${FUNKWHALE_FRONTEND_PATH}:/frontend"
     ports:
       - "5000"
-    links:
-      - postgres
-      - redis
 
   nginx:
     restart: unless-stopped
     image: nginx
+    networks:
+      - default
+    depends_on:
+      - api
     env_file:
       - .env
     environment:
@@ -85,5 +99,6 @@ services:
         > /etc/nginx/conf.d/default.conf
         && cat /etc/nginx/conf.d/default.conf
         && nginx -g 'daemon off;'"
-    links:
-      - api
+
+networks:
+  default:
diff --git a/deploy/docker.nginx.template b/deploy/docker.nginx.template
index fd99c07050f9b42ed5c8999be2bbdf8118121645..431975629741f4546e18f061987d6fc7ec31b699 100644
--- a/deploy/docker.nginx.template
+++ b/deploy/docker.nginx.template
@@ -57,13 +57,20 @@ server {
         alias ${MEDIA_ROOT}/;
     }
 
+    # this is an internal location that is used to serve
+    # audio files once correct permission / authentication
+    # has been checked on API side
     location /_protected/media {
-        # this is an internal location that is used to serve
-        # audio files once correct permission / authentication
-        # has been checked on API side
         internal;
         alias   ${MEDIA_ROOT};
+
     }
+    # Comment the previous location and uncomment this one if you're storing
+    # media files in a S3 bucket
+    # location ~ /_protected/media/(.+) {
+    #     internal;
+    #     proxy_pass $1;
+    # }
 
     location /_protected/music {
         # this is an internal location that is used to serve
diff --git a/deploy/env.prod.sample b/deploy/env.prod.sample
index a71af5310b0c8768720355e44c898ebf950d8aad..b7b0301dadff33f34d288ac78a9684be73663998 100644
--- a/deploy/env.prod.sample
+++ b/deploy/env.prod.sample
@@ -75,7 +75,15 @@ REVERSE_PROXY_TYPE=nginx
 #  CACHE_URL=redis://:password@localhost:6379/0
 #  (the extra semicolon is important)
 # Use the next one if you followed Debian installation guide
+#
 # CACHE_URL=redis://127.0.0.1:6379/0
+#
+# If you want to use Redis over unix sockets, you'll actually need two variables:
+# For the cache part:
+#  CACHE_URL=redis:///run/redis/redis.sock?db=0
+# For the Celery/asynchronous tasks part:
+#  CELERY_BROKER_URL=redis+socket:///run/redis/redis.sock?virtual_host=0
+
 
 # Where media files (such as album covers or audio tracks) should be stored
 # on your system?
@@ -136,3 +144,28 @@ FUNKWHALE_FRONTEND_PATH=/srv/funkwhale/front/dist
 
 # Nginx related configuration
 NGINX_MAX_BODY_SIZE=100M
+
+## External storages configuration
+# Funkwhale can store uploaded files on Amazon S3 and S3-compatible storages (such as Minio)
+# Uncomment and fill the variables below
+
+AWS_ACCESS_KEY_ID=
+AWS_SECRET_ACCESS_KEY=
+AWS_STORAGE_BUCKET_NAME=
+# An optional bucket subdirectory were you want to store the files. This is especially useful
+# if you plan to use share the bucket with other services
+# AWS_LOCATION=
+
+# If you use a S3-compatible storage such as minio, set the following variable
+# the full URL to the storage server. Example:
+#   AWS_S3_ENDPOINT_URL=https://minio.mydomain.com
+# AWS_S3_ENDPOINT_URL=
+
+# If you want to serve media directly from your S3 bucket rather than through a proxy,
+# set this to true
+# PROXY_MEDIA=false
+
+# If you are using Amazon S3 to serve media directly, you will need to specify your region
+# name in order to access files. Example:
+#   AWS_S3_REGION_NAME=eu-west-2
+# AWS_S3_REGION_NAME= 
diff --git a/deploy/nginx.template b/deploy/nginx.template
index 7cdee70f48c320bc6e7ef1796c6a13b0d82b53f7..78b8ff3d6cf99e1b732e726ef448de9b65f9d517 100644
--- a/deploy/nginx.template
+++ b/deploy/nginx.template
@@ -111,6 +111,13 @@ server {
         internal;
         alias   ${MEDIA_ROOT};
     }
+    
+    # Comment the previous location and uncomment this one if you're storing
+    # media files in a S3 bucket
+    # location ~ /_protected/media/(.+) {
+    #     internal;
+    #     proxy_pass $1;
+    # }
 
     location /_protected/music {
         # this is an internal location that is used to serve
diff --git a/dev.yml b/dev.yml
index 51aad05898f4f04be13c594cc86bc04d7128f4f6..7c58b910590fc52a79c57402d814c3cd04db2cde 100644
--- a/dev.yml
+++ b/dev.yml
@@ -60,8 +60,10 @@ services:
       - "FUNKWHALE_PROTOCOL=${FUNKWHALE_PROTOCOL-http}"
       - "DATABASE_URL=postgresql://postgres@postgres/postgres"
       - "CACHE_URL=redis://redis:6379/0"
-    links:
+
+    depends_on:
       - postgres
+      # - minio
       - redis
     networks:
       - internal
@@ -73,8 +75,9 @@ services:
       - .env.dev
       - .env
     build: *backend
-    links:
+    depends_on:
       - postgres
+      # - minio
       - redis
     command: celery -A funkwhale_api.taskapp worker -l debug -B
     environment:
@@ -95,6 +98,8 @@ services:
       - .env.dev
       - .env
     image: nginx
+    ports:
+      - "${NGINX_PORTS_MAPPING-8000:80}"
     environment:
       - "NGINX_MAX_BODY_SIZE=${NGINX_MAX_BODY_SIZE-100M}"
       - "FUNKWHALE_API_IP=${FUNKHALE_API_IP-api}"
@@ -135,7 +140,7 @@ services:
       - "8001:8001"
 
   api-docs:
-    image: swaggerapi/swagger-ui
+    image: swaggerapi/swagger-ui:v3.21.0
     environment:
       - "API_URL=/swagger.yml"
     ports:
@@ -143,6 +148,23 @@ services:
     volumes:
       - "./docs/swagger.yml:/usr/share/nginx/html/swagger.yml"
 
+  # minio:
+  #   image: minio/minio
+  #   command: server /data
+  #   volumes:
+  #     - "./data/${COMPOSE_PROJECT_NAME-node1}/minio:/data"
+  #   environment:
+  #     - "MINIO_ACCESS_KEY=${AWS_ACCESS_KEY_ID-access_key}"
+  #     - "MINIO_SECRET_KEY=${AWS_SECRET_ACCESS_KEY-secret_key}"
+  #     - "MINIO_HTTP_TRACE: /dev/stdout"
+  #   ports:
+  #     - "9000:9000"
+  #   networks:
+  #     - federation
+  #     - internal
+
+
+
 networks:
   ? internal
   federation:
diff --git a/docker/nginx/conf.dev b/docker/nginx/conf.dev
index 50c3cbc2ef47f19b96f0c1716f933c61398e59c3..419bb0dd8975b09df4545d9ec6be4d69c24a2c32 100644
--- a/docker/nginx/conf.dev
+++ b/docker/nginx/conf.dev
@@ -93,13 +93,22 @@ http {
             alias /protected/media/;
         }
 
+        # this is an internal location that is used to serve
+        # audio files once correct permission / authentication
+        # has been checked on API side
         location /_protected/media {
-            # this is an internal location that is used to serve
-            # audio files once correct permission / authentication
-            # has been checked on API side
             internal;
             alias   /protected/media;
+
         }
+        # Comment the previous location and uncomment this one if you're storing
+        # media files in a S3 bucket
+        # location ~ /_protected/media/(.+) {
+        #     internal;
+        #     resolver 127.0.0.11;
+        #     proxy_pass $1;
+        #     add_header X-Remote-URL "$1";
+        # }
 
         location /_protected/music {
             # this is an internal location that is used to serve
diff --git a/docs/admin/backup.rst b/docs/admin/backup.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d474678ae3ba48a5c0a51b9114200673148c894e
--- /dev/null
+++ b/docs/admin/backup.rst
@@ -0,0 +1,79 @@
+Backup your Funkwhale instance
+==============================
+
+.. note::
+
+    Before upgrading your instance, we strongly advise you to make at least a database backup. Ideally, you should make a full backup, including the database and the media files.
+
+
+Docker setup
+------------
+
+If you've followed the setup instructions in :doc:`../installation/docker`, here is the backup path:
+
+Multi-container installation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Backup the db
+^^^^^^^^^^^^^
+
+On docker setups, you have to ``pg_dumpall`` in container ``funkwhale_postgres_1``:
+
+.. code-block:: shell
+
+   docker exec -t funkwhale_postgres_1 pg_dumpall -c -U postgres > dump_`date +%d-%m-%Y"_"%H_%M_%S`.sql
+
+Backup the media files
+^^^^^^^^^^^^^^^^^^^^^^
+
+To backup docker data volumes, as the volumes are bound mounted to the host, the ``rsync`` way would go like this:
+
+.. code-block:: shell
+
+    rsync -avzhP /srv/funkwhale/data/media /path/to/your/backup/media
+    rsync -avzhP /srv/funkwhale/data/music /path/to/your/backup/music
+
+
+Backup the configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On docker setups, the configuration file is located at the root level:
+
+.. code-block:: shell
+
+    rsync -avzhP /srv/funkwhale/.env /path/to/your/backup/.env
+
+
+Non-docker setup
+----------------
+
+Backup the db
+^^^^^^^^^^^^^
+
+On non-docker setups, you have to ``pg_dump`` as user ``postgres``:
+
+.. code-block:: shell
+
+   sudo -u postgres -H pg_dump funkwhale > /path/to/your/backup/dump_`date +%d-%m-%Y"_"%H_%M_%S`.sql
+
+Backup the media files
+^^^^^^^^^^^^^^^^^^^^^^
+
+A simple way to backup your media files is to use ``rsync``:
+
+.. code-block:: shell
+
+    rsync -avzhP /srv/funkwhale/data/media /path/to/your/backup/media
+    rsync -avzhP /srv/funkwhale/data/music /path/to/your/backup/music
+
+Backup the configuration files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: shell
+
+    rsync -avzhP /srv/funkwhale/config/.env /path/to/your/backup/.env
+
+.. note::
+   You may also want to backup your proxy configuration file.
+
+   For frequent backups, you may want to use deduplication and compression to keep the backup size low. In this case, a tool like ``borg`` will be more appropriate.
diff --git a/docs/admin/commands.rst b/docs/admin/commands.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c30a67a99913baa39457a56f88d3377d3293f3a7
--- /dev/null
+++ b/docs/admin/commands.rst
@@ -0,0 +1,82 @@
+Management commands
+===================
+
+Pruning library
+---------------
+
+Because Funkwhale is a multi-user and federated audio server, we don't delete any artist, album
+and track objects in the database when you delete the corresponding files.
+
+This is on purpose, because those objects may be referenced in user playlists, favorites,
+listening history or on other instances, or other users could have upload files matching
+linked to those entities in their own private libraries.
+
+Therefore, Funkwhale has a really conservative approach and doesn't delete metadata when
+audio files are deleted.
+
+This behaviour can be problematic in some situations though, e.g. if you imported
+a lot of wrongly tagged files, then deleted the files to reimport them later.
+
+To help with that, we provide a management you can run on the server and that will effectively
+prune you library from track, album and artist metadata that is not tied to any file:
+
+.. code-block:: sh
+
+    # print help
+    python manage.py prune_library --help
+
+    # prune tracks with no uploads
+    python manage.py prune_library --tracks
+
+    # prune albums with no tracks
+    python manage.py prune_library --albums
+
+    # prune artists with no tracks/albums
+    python manage.py prune_library --artists
+
+    # prune everything (tracks, albums and artists)
+    python manage.py prune_library --tracks --albums --artists
+
+The ``prune_library`` command will not delete anything by default, and only gives
+you an estimate of how many database objects would be affected by the pruning.
+
+Once you have reviewed the output and are comfortable with the changes, you should rerun
+the command with the ``--no-dry-run`` flag to disable dry run mode and actually apply
+the changes on the database.
+
+.. warning::
+
+    Running this command with ``--no-dry-run`` is irreversible. Unless you have a backup,
+    there will be no way to retrieve the deleted data.
+
+.. note::
+
+    The command will exclude tracks that are favorited, included in playlists or listening
+    history by default. If you want to include those in the pruning process as well,
+    add the corresponding ``--ignore-favorites``, ``--ignore-playlists`` and ``--ignore-listenings``
+    flags.
+
+Remove obsolete files from database
+-----------------------------------
+
+When importing using the :ref:`in-place method <in-place-import>`, if you move or remove
+in-place imported files on disk, Funkwhale will still have a reference to those files and won't
+be able to serve them properly.
+
+To help with that, whenever you remove or move files that were previously imported
+with the ``--in-place`` flag, you can run the following command::
+
+    python manage.py check_inplace_files
+
+This command will loop through all the database objects that reference
+an in-place imported file, check that the file is accessible on disk,
+or delete the database object if it's not.
+
+Once you have reviewed the output and are comfortable with the changes, you should rerun
+the command with the ``--no-dry-run`` flag to disable dry run mode and actually delete the
+database objects.
+
+.. warning::
+
+    Running this command with ``--no-dry-run`` is irreversible. Unless you have a backup,
+    there will be no way to retrieve the deleted data.
diff --git a/docs/admin/external-storages.rst b/docs/admin/external-storages.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c8dbbe9635f30846ebf97090cda35fa763356c9d
--- /dev/null
+++ b/docs/admin/external-storages.rst
@@ -0,0 +1,117 @@
+Using external storages to store Funkwhale content
+==================================================
+
+By default, Funkwhale will store user-uploaded and related media such as audio files,
+transcoded files, avatars and album covers on a server directory.
+
+However, for bigger instances or more complex deployment scenarios, you may want
+to use distributed or external storages.
+
+S3 and S3-compatible servers
+----------------------------
+
+.. note::
+
+    This feature was released in Funkwhale 0.19 and is still considered experimental.
+    Please let us know if you see anything unusual while using it.
+
+Funkwhale supports storing media files Amazon S3 and compatible implementations such as Minio or Wasabi.
+
+In this scenario, the content itself is stored in the S3 bucket. Non-sensitive media such as
+album covers or user avatars are served directly from the bucket. However, audio files
+are still served by the reverse proxy, to enforce proper authentication.
+
+To enable S3 on Funkwhale, add the following environment variables::
+
+    AWS_ACCESS_KEY_ID=
+    AWS_SECRET_ACCESS_KEY=
+    AWS_STORAGE_BUCKET_NAME=
+    # An optional bucket subdirectory were you want to store the files. This is especially useful
+    # if you plan to use share the bucket with other services
+    # AWS_LOCATION=
+
+    # If you use a S3-compatible storage such as minio, set the following variable
+    # the full URL to the storage server. Example:
+    #   AWS_S3_ENDPOINT_URL=https://minio.mydomain.com
+    # AWS_S3_ENDPOINT_URL=
+
+Then, edit your nginx configuration. On docker setups, the file is located at ``/srv/funkwhale/nginx/funkwhale.template``,
+and at ``/etc/nginx/sites-available/funkwhale.template`` on non-docker setups.
+
+Replace the ``location /_protected/media`` block with the following::
+
+    location ~ /_protected/media/(.+) {
+        internal;
+        proxy_pass $1;
+    }
+
+Then restart Funkwhale and nginx.
+
+From now on, media files will be stored on the S3 bucket you configured. If you already
+had media files before configuring the S3 bucket, you also have to move those on the bucket
+by hand (which is outside the scope of this guide).
+
+.. note::
+
+    At the moment, we do not support S3 when using Apache as a reverse proxy.
+
+Serving audio files directly from the bucket
+********************************************
+
+Depending on your setup, you may want to serve audio fils directly from the S3 bucket
+instead of proxying them through Funkwhale, e.g to reduce the bandwidth consumption on your server,
+or get better performance.
+
+You can achieve that by adding ``PROXY_MEDIA=false`` to your ``.env`` file.
+
+When receiving a request on the stream endpoint, Funkwhale will check for authentication and permissions,
+then issue a 302 redirect to the file URL in the bucket.
+
+This URL is actually be visible by the client, but contains a signature valid only for one hour, to ensure
+no one can reuse this URL or share it publicly to distribute unauthorized content.
+
+.. note::
+   
+   If you are using Amazon S3, you will need to set your ``AWS_S3_REGION_NAME`` in the ``.env`` file to
+   use this feature. 
+
+.. note::
+
+    Since some Subsonic clients don't support 302 redirections, Funkwhale will ignore
+    the ``PROXY_MEDIA`` setting and always proxy file when accessed through the Subsonic API.
+
+
+Securing your S3 bucket
+***********************
+
+It's important to ensure your the root of your bucket doesn't list its content,
+which is the default on many S3 servers. Otherwise, anyone could find out the true
+URLs of your audio files and bypass authentication.
+
+To avoid that, you can set the following policy on your bucket::
+
+    {
+        "Version": "2012-10-17",
+        "Statement": [
+            {
+            "Action": [
+                "s3:GetObject"
+            ],
+            "Effect": "Allow",
+            "Principal": {
+                "AWS": [
+                "*"
+                ]
+            },
+            "Resource": [
+                "arn:aws:s3:::<yourbucketname>/*"
+            ],
+            "Sid": "Public"
+            }
+        ]
+    }
+
+If you are using ``awscli``, you can store this policy in a ``/tmp/policy`` file, and
+apply it using the following command::
+
+    aws s3api put-bucket-policy --bucket <yourbucketname> --policy file:///tmp/policy
diff --git a/docs/admin/importing-music.rst b/docs/admin/importing-music.rst
index acf025c6c2ad552ee18895771132baf97a4ef051..7c04544e9d5b3b7f0e3f37dfef289b6335b5da6f 100644
--- a/docs/admin/importing-music.rst
+++ b/docs/admin/importing-music.rst
@@ -105,8 +105,13 @@ And import music from this share with this command::
     python api/manage.py import_files $LIBRARY_ID "/srv/funkwhale/data/music/nfsshare/**/*.ogg" --recursive --noinput --in-place
 
 On docker setups, it will require a bit more work, because while the ``/srv/funkwhale/data/music`` is mounted
-in containers, symlinked directories are not. To fix that, in your ``docker-compose.yml`` file, ensure each symlinked
-directory is mounted as a volume as well::
+in containers, symlinked directories are not.
+
+To fix that, you can use bind mounts instead of symbolic links, as it replicates the source directory tree. With the previous NFS share, it would go this way::
+
+    mount --bind /media/mynfsshare /srv/funkwhale/data/music/nfsshare
+
+If you want to go with symlinks, ensure each symlinked directory is mounted as a volume as well in your ``docker-compose.yml`` file::
 
     celeryworker:
       volumes:
diff --git a/docs/admin/index.rst b/docs/admin/index.rst
index a385a2e5e90f4d77325d5a5f56044fbfc5a7feb1..8d80e3e0ad47487fd5091f7cc71e2068d0f445fe 100644
--- a/docs/admin/index.rst
+++ b/docs/admin/index.rst
@@ -14,6 +14,7 @@ Setup Guides
    ../installation/index
    configuration
    importing-music
+   external-storages
 
 Administration
 --------------
@@ -22,6 +23,7 @@ Administration
    :maxdepth: 2
 
    django
+   commands
    url
    upgrading
 
diff --git a/docs/admin/upgrading.rst b/docs/admin/upgrading.rst
index 5b222ce49f0b159af7c0864654a529fc3ddfd453..23c581cf74ebea233eec97f92cec407fc1935dd8 100644
--- a/docs/admin/upgrading.rst
+++ b/docs/admin/upgrading.rst
@@ -79,7 +79,7 @@ Multi-container installation
     source .env
     # Download newest nginx configuration file
     curl -L -o nginx/funkwhale.template "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/develop/deploy/docker.nginx.template"
-    curl -L -o nginx/funkwhale_proxy.conf "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/develop/deploy/funkwhale_proxy.conf"
+    curl -L -o nginx/funkwhale_proxy.conf "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/develop/deploy/docker.funkwhale_proxy.conf"
     # Pull the new version containers
     docker-compose pull
     # Apply the database migrations
diff --git a/docs/conf.py b/docs/conf.py
index eb3ae5cdd6d0fa3aa892ab05dd8c31f79c468447..bf1afa0a604b6c922d344f3e2bb9823c13975d7e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -164,7 +164,7 @@ texinfo_documents = [
 redirect_files = [
 
     ('importing-music.html', 'admin/importing-music.html'),
-    ('architecture.html', 'developer/architecture.html'),
+    ('architecture.html', 'developers/architecture.html'),
     ('troubleshooting.html', 'admin/troubleshooting.html'),
     ('configuration.html', 'admin/configuration.html'), 
     ('upgrading/index.html', '../admin/upgrading.html'),
diff --git a/docs/developers/authentication.rst b/docs/developers/authentication.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0d32139c0ed3eb80b99a7c2ec5a81aee700d1cbb
--- /dev/null
+++ b/docs/developers/authentication.rst
@@ -0,0 +1,97 @@
+API Authentication
+==================
+
+Each Funkwhale API endpoint supports access from:
+
+- Anonymous users (if the endpoint is configured to do so, for exemple via the ``API Authentication Required`` setting)
+- Logged-in users
+- Third-party apps (via OAuth2)
+
+To seamlessly support this range of access modes, we internally use oauth scopes
+to describes what permissions are required to perform any given operation.
+
+OAuth
+-----
+
+Create an app
+:::::::::::::
+
+To connect to Funkwhale API via OAuth, you need to create an application. There are
+two ways to do that:
+
+1. By visiting ``/settings/applications/new`` when logged in on your Funkwhale instance.
+2. By sending a ``POST`` request to ``/api/v1/oauth/apps/``, as described in `our API documentation <https://docs.funkwhale.audio/swagger/>`_.
+
+Both method will give you a client ID and secret.
+
+Getting an access token
+:::::::::::::::::::::::
+
+Once you have a client ID and secret, you can request access tokens
+using the `authorization code grant flow <https://tools.ietf.org/html/rfc6749#section-4.1>`_.
+
+We support the ``urn:ietf:wg:oauth:2.0:oob`` redirect URI for non-web applications, as well
+as traditionnal redirection-based flow.
+
+Our authorization endpoint is located at ``/authorize``, and our token endpoint at ``/api/v1/oauth/token/``.
+
+Refreshing tokens
+:::::::::::::::::
+
+When your access token is expired, you can `request a new one as described in the OAuth specification <https://tools.ietf.org/html/rfc6749#section-6>`_.
+
+Security considerations
+:::::::::::::::::::::::
+
+- Grant codes are valid for a 5 minutes after authorization request is approved by the end user.
+- Access codes are valid for 10 hours. When expired, you will need to request a new one using your refresh token.
+- We return a new refresh token everytime an access token is requested, and invalidate the old one. Ensure you store the new refresh token in your app.
+
+
+Scopes
+::::::
+
+Scopes are defined in :file:`funkwhale_api/users/oauth/scopes.py:BASE_SCOPES`, and generally are mapped to a business-logic resources (follows, favorites, etc.). All those base scopes come in two flawours:
+
+- `read:<base_scope>`: get read-only access to the resource
+- `write:<base_scope>`: get write-only access to the ressource
+
+For example, ``playlists`` is a base scope, and ``write:playlists`` is the actual scope needed to perform write
+operations on playlists (via a ``POST``, ``PATCH``, ``PUT`` or ``DELETE``. ``read:playlists`` is used
+to perform read operations on playlists such as fetching a given playlist via ``GET``.
+
+Having the generic ``read`` or ``write`` scope give you the corresponding access on *all* resources.
+
+This is the list of OAuth scopes that third-party applications can request:
+
+
++-------------------------------------------+---------------------------------------------------+
+| Scope                                     | Description                                       |
++===========================================+===================================================+
+| ``read``                                  | Read-only access to all data                      |
+|                                           | (equivalent to all ``read:*`` scopes)             |
++-------------------------------------------+---------------------------------------------------+
+| ``write``                                 | Write-only access to all data                     |
+|                                           | (equivalent to all ``write:*`` scopes)            |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:profile``                  | Access to profile data (email, username, etc.)    |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:libraries``                | Access to library data (uploads, libraries        |
+|                                           | tracks, albums, artists...)                       |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:favorites``                | Access to favorites                               |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:listenings``               | Access to history                                 |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:follows``                  | Access to followers                               |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:playlists``                | Access to playlists                               |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:radios``                   | Access to radios                                  |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:filters``                  | Access to content filters                         |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:notifications``            | Access to notifications                           |
++-------------------------------------------+---------------------------------------------------+
+| ``<read/write>:edits``                    | Access to metadata edits                          |
++-------------------------------------------+---------------------------------------------------+
diff --git a/docs/developers/index.rst b/docs/developers/index.rst
index 69f22f2c6e2417b992da646064b95bb8e76c38ed..966cac3afd0d2867c7899bb34160e2a893ad8f9a 100644
--- a/docs/developers/index.rst
+++ b/docs/developers/index.rst
@@ -12,5 +12,6 @@ Reference
 
    architecture
    ../api
+   ./authentication
    ../federation/index
    subsonic
diff --git a/docs/documentation/identifying.rst b/docs/documentation/identifying.rst
index eed1dc2f3f9bb60d99b57b10e149ba41d4f46422..3f7ee97d17878cd254c4463ee2d3e66eef06f46b 100644
--- a/docs/documentation/identifying.rst
+++ b/docs/documentation/identifying.rst
@@ -24,6 +24,5 @@ If you're not comfortable with writing documents or don't feel like you can, you
 by requesting a document be written. There are three ways to request new documents:
 
 - Open a new issue on `Gitlab <https://dev.funkwhale.audio/funkwhale/funkwhale/issues>`_, providing as much detail as possible
-- Start a new thread on `the forum <https://socialhub.network/c/funkwhale>`_ with more details about your requests
+- Start a new thread on `the forum <https://governance.funkwhale.audio/g/kQgxNq15/funkwhale>`_ with more details about your requests
 - Ask somebody on our `chat room <https://riot.im/app/#/room/#funkwhale:matrix.org>`_
-
diff --git a/docs/federation/index.rst b/docs/federation/index.rst
index e54de3fe4c720998a66e7281d7005843bf14ef14..70f766035fe96b49e179648cbb1989e456bd2953 100644
--- a/docs/federation/index.rst
+++ b/docs/federation/index.rst
@@ -88,8 +88,7 @@ to posting an activity to an outbox, we create an object, with the proper payloa
 Receiving an activity from a remote actor in a local inbox is basically the same, but we skip step 2.
 
 Funkwhale does not support all activities, and we have a basic routing logic to handle
-specific activities, and discard unsupported ones. Unsupported activities are still
-received and stored though.
+specific activities, and discard unsupported ones.
 
 If a delivered activity matches one of our routes, a dedicated handler is called,
 which can trigger additional logic. For instance, if we receive a :ref:`activity-create` activity
@@ -102,6 +101,24 @@ Links:
 - `Delivery logic for activities <https://dev.funkwhale.audio/funkwhale/funkwhale/blob/develop/api/funkwhale_api/federation/tasks.py>`_
 
 
+.. _service-actor:
+
+Service actor
+-------------
+
+In some situations, we will send messages or authenticate our fetches using what we call
+the service actor. A service actor is an ActivityPub actor object that acts on behalf
+of a Funkwhale server.
+
+The actor id usually looks like ``https://yourdomain.com/federation/actors/service``, but
+the reliable way to determine it is to query the nodeinfo endpoint and use the value
+available in the ``metadata > actorId`` field.
+
+Funkwhale generally considers that the service actor has authority to send activities
+associated with any object on the same domain. For instance, the service actor
+could send a :ref:`activity-delete` activity linked to another users' library on the same domain.
+
+
 Supported activities
 --------------------
 
@@ -305,6 +322,59 @@ the audio library's actor are the same.
 
 If no local actor follows the audio's library, the activity will be discarded.
 
+.. _activity-update:
+
+
+Update
+^^^^^^
+
+Supported on
+************
+
+- :ref:`object-library` objects
+- :ref:`object-track` objects
+
+Example
+*******
+
+.. code-block:: json
+
+  {
+    "@context": [
+      "https://www.w3.org/ns/activitystreams",
+      "https://w3id.org/security/v1",
+      {}
+    ],
+    "to": [
+      "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers"
+    ],
+    "type": "Update",
+    "actor": "https://awesome.music/federation/actors/Bob",
+    "object": {}
+  }
+
+.. note::
+
+  Refer to :ref:`object-library` or :ref:`object-track` to see the structure of the ``object`` attribute.
+
+Internal logic
+**************
+
+When a :ref:`activity-update` is received with a :ref:`object-library` or :ref:`object-track` object,
+Funkwhale will try to update the local copy of the corresponding object in it's database.
+
+
+Checks
+******
+
+Checks vary depending of the type of object associated with the update.
+
+For :ref:`object-library` objects, we ensure the actor sending the message is the owner of the library.
+
+For musical entities such as :ref:`object-track`, we ensure the actor sending the message
+matches the :ref:`property-attributedTo` property declared on the local copy on the object,
+or the :ref:`service-actor`.
+
 .. _activity-delete:
 
 Delete
@@ -515,7 +585,7 @@ Example
   {
     "type": "Library",
     "id": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6",
-    "actor": "https://awesome.music/federation/actors/MyNameIsTroll",
+    "attributedTo": "https://awesome.music/federation/actors/Alice",
     "name": "My awesome library",
     "followers": "https://awesome.music/federation/music/libraries/dc702491-f6ce-441b-9da0-cecbed08bcc6/followers",
     "summary": "This library is for restricted use only",
@@ -613,3 +683,19 @@ For :ref:`object-audio` url objects:
 
 - If the audio's library is public, audio file can be accessed without restriction
 - Otherwise, the HTTP request must be signed by an actor with an approved follow on the audio's library
+
+
+Properties
+----------
+
+.. _property-attributedTo:
+
+attributedTo
+------------
+
+Funkwhale will generally use the ``attributedTo`` property to communicate
+who is responsible for a given object. When an object has the ``attributedTo`` attribute,
+the associated actor has the permission to :ref:`activity-update`, :ref:`activity-delete` or
+more generally apply any kind of activity on the object.
+
+In addition, Funkwhale consider all the objects of a domain as attributed to its corresponding :ref:`service-actor`.
diff --git a/docs/installation/debian.rst b/docs/installation/debian.rst
index 06449cf7fc50f730e19fbb7fdf505cea15ade584..40597cbe3fa1c7d19aa581d6c3a30df7f86a4ad3 100644
--- a/docs/installation/debian.rst
+++ b/docs/installation/debian.rst
@@ -51,7 +51,7 @@ Create the user and the directory:
 
 .. code-block:: shell
 
-    sudo useradd -r -s /usr/bin/nologin -d /srv/funkwhale -m funkwhale
+    sudo useradd -r -s /usr/sbin/nologin -d /srv/funkwhale -m funkwhale
     cd /srv/funkwhale
 
 Log in as the newly created user from now on:
diff --git a/docs/swagger.yml b/docs/swagger.yml
index d83171698e4e71ced2459ae9cd9b42690aa7628d..47fd8d4b521fa447cb37e855be05ca48455547eb 100644
--- a/docs/swagger.yml
+++ b/docs/swagger.yml
@@ -7,7 +7,7 @@
 #  /api/v1/radios
 #  /api/v1/history
 
-openapi: "3.0.0"
+openapi: "3.0.2"
 info:
   description: |
     Interactive documentation for [Funkwhale](https://funkwhale.audio) API.
@@ -43,9 +43,9 @@ info:
   title: "Funkwhale API"
 
 servers:
-  - url: https://demo.funkwhale.audio/api/v1
+  - url: https://demo.funkwhale.audio
     description: Demo server
-  - url: https://{domain}/api/v1
+  - url: https://{domain}
     description: Custom server
     variables:
       domain:
@@ -59,6 +59,38 @@ servers:
 
 components:
   securitySchemes:
+    oauth2:
+      type: oauth2
+      description: This API uses OAuth 2 with the Authorization Code flow. You can register an app using the /oauth/apps/ endpoint.
+      flows:
+        authorizationCode:
+          # Swagger doesn't support relative URLs yet (cf https://github.com/swagger-api/swagger-ui/pull/5244)
+          authorizationUrl: /authorize
+          tokenUrl: /api/v1/oauth/token/
+          refreshUrl: /api/v1/oauth/token/
+          scopes:
+            "read": "Read-only access to all user data"
+            "write": "Write-only access on all user data"
+            "read:profile": "Read-only access to profile data"
+            "read:libraries": "Read-only access to library and uploads"
+            "read:playlists": "Read-only access to playlists"
+            "read:listenings": "Read-only access to listening history"
+            "read:favorites": "Read-only access to favorites"
+            "read:radios": "Read-only access to radios"
+            "read:edits": "Read-only access to edits"
+            "read:notifications": "Read-only access to notifications"
+            "read:follows": "Read-only to follows"
+            "read:filters": "Read-only to to content filters"
+            "write:profile": "Write-only access to profile data"
+            "write:libraries": "Write-only access to libraries"
+            "write:playlists": "Write-only access to playlists"
+            "write:follows": "Write-only access to follows"
+            "write:favorites": "Write-only access to favorits"
+            "write:notifications": "Write-only access to notifications"
+            "write:radios": "Write-only access to radios"
+            "write:edits": "Write-only access to edits"
+            "write:filters": "Write-only access to content-filters"
+            "write:listenings": "Write-only access to listening history"
     jwt:
       type: http
       scheme: bearer
@@ -67,6 +99,7 @@ components:
 
 security:
   - jwt: []
+  - oauth2: []
 
 tags:
   - name: Auth and security
@@ -81,7 +114,41 @@ tags:
     description: Favorites, playlists, radios
 
 paths:
-  /token/:
+  /api/v1/oauth/apps/:
+    post:
+      tags:
+        - "auth"
+      description:
+        Register an OAuth application
+      security: []
+      responses:
+        201:
+          content:
+            application/json:
+              schema:
+                allOf:
+                  - $ref: "#/definitions/OAuthApplication"
+                  - $ref: "#/definitions/OAuthApplicationCreation"
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              type: "object"
+              properties:
+                name:
+                  type: "string"
+                  example: "My Awesome Funkwhale Client"
+                  summary: "A human readable name for your app"
+                redirect_uris:
+                  type: "string"
+                  example: "https://myapp/oauth2/funkwhale"
+                  summary: "A list of redirect uris, separated by spaces"
+                scopes:
+                  type: "string"
+                  summary: "A list of scopes requested by your app, separated by spaces"
+                  example: "read write:playlists write:favorites"
+  /api/v1/token/:
     post:
       tags:
         - "Auth and security"
@@ -180,11 +247,14 @@ paths:
               schema:
                 $ref: "#/definitions/Me"
 
-  /artists/:
+  /api/v1/artists/:
     get:
       summary: List artists
       tags:
         - "Library and metadata"
+      security:
+        - oauth2:
+          - "read:libraries"
       parameters:
         - name: "q"
           in: "query"
@@ -221,12 +291,14 @@ paths:
                         type: "array"
                         items:
                           $ref: "#/definitions/Artist"
-  /artists/{id}/:
+  /api/v1/artists/{id}/:
     get:
       summary: Retrieve a single artist
       parameters:
         - $ref: "#/parameters/ObjectId"
-
+      security:
+        - oauth2:
+          - "read:libraries"
       tags:
         - "Library and metadata"
       responses:
@@ -240,9 +312,12 @@ paths:
             application/json:
               schema:
                 $ref: "#/definitions/ResourceNotFound"
-  /artists/{id}/libraries/:
+  /api/v1/artists/{id}/libraries/:
     get:
       summary: List available user libraries containing work from this artist
+      security:
+        - oauth2:
+          - "read:libraries"
       parameters:
         - $ref: "#/parameters/ObjectId"
         - $ref: "#/parameters/PageNumber"
@@ -262,11 +337,15 @@ paths:
               schema:
                 $ref: "#/definitions/ResourceNotFound"
 
-  /albums/:
+  /api/v1/albums/:
     get:
       summary: List albums
       tags:
         - "Library and metadata"
+
+      security:
+        - oauth2:
+          - "read:libraries"
       parameters:
         - name: "q"
           in: "query"
@@ -311,12 +390,15 @@ paths:
                         type: "array"
                         items:
                           $ref: "#/definitions/Album"
-  /albums/{id}/:
+  /api/v1/albums/{id}/:
     get:
       summary: Retrieve a single album
       parameters:
         - $ref: "#/parameters/ObjectId"
 
+      security:
+        - oauth2:
+          - "read:libraries"
       tags:
         - "Library and metadata"
       responses:
@@ -331,7 +413,7 @@ paths:
               schema:
                 $ref: "#/definitions/ResourceNotFound"
 
-  /albums/{id}/libraries/:
+  /api/v1/albums/{id}/libraries/:
     get:
       summary: List available user libraries containing tracks from this album
       parameters:
@@ -339,6 +421,9 @@ paths:
         - $ref: "#/parameters/PageNumber"
         - $ref: "#/parameters/PageSize"
 
+      security:
+        - oauth2:
+          - "read:libraries"
       tags:
         - "Library and metadata"
       responses:
@@ -353,11 +438,15 @@ paths:
               schema:
                 $ref: "#/definitions/ResourceNotFound"
 
-  /tracks/:
+  /api/v1/tracks/:
     get:
       summary: List tracks
       tags:
         - "Library and metadata"
+
+      security:
+        - oauth2:
+          - "read:libraries"
       parameters:
         - name: "q"
           in: "query"
@@ -425,12 +514,15 @@ paths:
                         type: "array"
                         items:
                           $ref: "#/definitions/Track"
-  /tracks/{id}/:
+  /api/v1/tracks/{id}/:
     get:
       parameters:
         - $ref: "#/parameters/ObjectId"
       summary: Retrieve a single track
 
+      security:
+        - oauth2:
+          - "read:libraries"
       tags:
         - "Library and metadata"
       responses:
@@ -445,14 +537,16 @@ paths:
               schema:
                 $ref: "#/definitions/ResourceNotFound"
 
-  /tracks/{id}/libraries/:
+  /api/v1/tracks/{id}/libraries/:
     get:
       summary: List available user libraries containing given track
       parameters:
         - $ref: "#/parameters/ObjectId"
         - $ref: "#/parameters/PageNumber"
         - $ref: "#/parameters/PageSize"
-
+      security:
+        - oauth2:
+          - "read:libraries"
       tags:
         - "Library and metadata"
       responses:
@@ -526,9 +620,13 @@ paths:
             application/json:
               schema:
                 $ref: "#/definitions/ResourceNotFound"
-  /licenses/:
+
+  /api/v1/licenses/:
     get:
       summary: List licenses
+      security:
+        - oauth2:
+          - "read:libraries"
       tags:
         - "Library and metadata"
       parameters:
@@ -548,17 +646,20 @@ paths:
                         items:
                           $ref: "#/definitions/License"
 
-  /licenses/{code}/:
-    parameters:
-      - name: code
-        in: path
-        description: License code
-        required: true
-        schema:
-          type: string
-          example: cc0-1.0
+  /api/v1/licenses/{code}/:
     get:
       summary: Retrieve a single license
+      security:
+        - oauth2:
+          - "read:libraries"
+      parameters:
+        - name: code
+          in: path
+          description: License code
+          required: true
+          schema:
+            type: string
+            example: cc0-1.0
 
       tags:
         - "Library and metadata"
@@ -937,6 +1038,34 @@ properties:
       - "mp3"
 
 definitions:
+  OAuthApplication:
+    type: "object"
+    properties:
+      client_id:
+        type: "string"
+        example: "VKIZWv7FwBq56UMfUtbCSIgSxzUTv1b6nMyOkJvP"
+      created:
+        type: "string"
+        format: "date-time"
+      updated:
+        type: "string"
+        format: "date-time"
+      scopes:
+        type: "string"
+        description: "Coma-separated list of scopes requested by the app"
+
+  OAuthApplicationCreation:
+    type: "object"
+    properties:
+      client_secret:
+        type: "string"
+        example: "qnKDX8zjIfC0BG4tUreKlqk3tNtuCfJdGsaEt5MIWrTv0YLLhGI6SGqCjs9kn12gyXtIg4FWfZqWMEckJmolCi7a6qew4LawPWMfnLDii4mQlY1eQG4BJbwPANOrDiTZ"
+      redirect_uris:
+        type: "string"
+        format: "uri"
+        description: "Coma-separated list of redirect uris allowed for the app"
+
+
   ResultPage:
     type: "object"
     properties:
@@ -1030,12 +1159,20 @@ definitions:
         type: "integer"
         format: "int64"
         example: 42
+      fid:
+        type: string
+        format: uri
+        description: "The artist Federation ID (unique accross federation)"
       name:
         type: "string"
         example: "System of a Down"
       creation_date:
         type: "string"
         format: "date-time"
+      is_local:
+        type: "boolean"
+        description: "Indicates if the object was initally created locally or on another server"
+
   Artist:
     type: "object"
     allOf:
@@ -1057,6 +1194,10 @@ definitions:
         type: "integer"
         format: "int64"
         example: 16
+      fid:
+        type: string
+        format: uri
+        description: "The album Federation ID (unique accross federation)"
       artist:
         type: "integer"
         format: "int64"
@@ -1076,6 +1217,9 @@ definitions:
         type: "boolean"
       cover:
         $ref: "#/definitions/Image"
+      is_local:
+        type: "boolean"
+        description: "Indicates if the object was initally created locally or on another server"
 
   Album:
     type: "object"
@@ -1187,6 +1331,10 @@ definitions:
         type: "integer"
         format: "int64"
         example: 66
+      fid:
+        type: string
+        format: uri
+        description: "The track Federation ID (unique accross federation)"
       artist:
         type: "integer"
         format: "int64"
@@ -1221,6 +1369,9 @@ definitions:
         type: "string"
         description: "Identifier of the license that is linked to the track"
         example: "cc-by-nc-nd-4.0"
+      is_local:
+        type: "boolean"
+        description: "Indicates if the object was initally created locally or on another server"
 
   AlbumTrack:
     type: "object"
diff --git a/docs/users/apps.rst b/docs/users/apps.rst
index 6f346c9015cd78616649ec78ed9ca45b56ab3d75..c8303b5f78848a40bd01250ec8d3fabb21e157c5 100644
--- a/docs/users/apps.rst
+++ b/docs/users/apps.rst
@@ -40,10 +40,10 @@ Those features as missing:
 
 .. note::
 
-    If you know or use some recent, well-maintained, Subsonic clients,
+    If you know or use some recent, well-maintained Subsonic clients,
     please get in touch so we can add them to this list.
 
-    Especially we're still lacking an iOS client!
+    In particular we're still lacking an iOS client!
 
 
 Enabling Subsonic on your Funkwhale account
@@ -166,7 +166,7 @@ Once installed, add the following to your /etc/mopidy/mopidy.conf::
     [subidy]
     enabled=True
     url=https://path.to/your/funkwhale/server
-    username=funkwhale
+    username=your_funkwhale_username
     password=your_subsonic_password
     #legacy_auth=(optional - setting to yes may solve some connection errors)
     #api_version=(optional - specify which API version to use. Subsonic 6.2 uses 1.14.0)
@@ -179,6 +179,10 @@ This will show your artists, albums, and playlists when you start ncmpcpp.
 
 [Optional]: enable and start mopidy as a service to start the server at boot.
 
+.. note::
+
+   This also works with the `mopidy-funkwhale plugin <https://dev.funkwhale.audio/funkwhale/mopidy>`_
+
 Mobydick (Desktop)
 ^^^^^^^^^^^^^^^^^^
 
diff --git a/docs/users/queue.rst b/docs/users/queue.rst
index a2790e8fa3324e414256b86ac68a6dc0cd7ae36e..7df5c4d7f7ac6694e2c6bb5e45ce6020ae368926 100644
--- a/docs/users/queue.rst
+++ b/docs/users/queue.rst
@@ -27,18 +27,17 @@ Add an Album to the Queue
 
 To add a whole album to the queue:
 
-- Navigate to ``https://your-instance/library/playlists`` or click on "Browse" in the "Music" library on the left-hand side then select "Playlists" along the top
-- Find the playlist you wish to add
-- Click on the three dot menu  to "Play" and select "Add to Queue", "Play Next", or "Play Now"
+- Search for an album, or navigate to its album page in the library
+- Click on the down arrow next to "Play" and select "Add to Queue", "Play Next", or "Play Now"
 
 Add a Playlist to the Queue
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 To add a playlist to the queue:
 
-- Search for an album, or navigate to its album page in the library
-- Click on the down arrow next to "Play" and select "Add to Queue", "Play Next", or "Play Now"
-
+- Navigate to ``https://your-instance/library/playlists`` or click on "Browse" in the "Music" library on the left-hand side then select "Playlists" along the top
+- Find the playlist you wish to add
+- Click on the three dot menu  to "Play" and select "Add to Queue", "Play Next", or "Play Now"
 
 Rearrange Tracks in Your Queue
 ------------------------------
diff --git a/docs/users/tagging.rst b/docs/users/tagging.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f5276e50381566d544122b59a8d650348730d728
--- /dev/null
+++ b/docs/users/tagging.rst
@@ -0,0 +1,59 @@
+Tagging Music With MusicBrainz Picard
+=====================================
+
+In order to get the most out of Funkwhale, it is important to tag files correctly. Good tagging makes managing your library much easier and provides Funkwhale with the information necessary to display album art, metadata, and other useful information. The recommended tool for tagging music is `MusicBrainz Picard <https://picard.musicbrainz.org/>`_.
+
+Tagging Items
+--------------
+
+Tagging a File
+^^^^^^^^^^^^^^
+
+To load a file into MusicBrainz Picard:
+
+* Click on "Add Files"
+* Select the files you want to tag from your computer
+* Picard should automatically start scanning the items. If nothing happens, select the item(s) and click on "Scan"
+* Picard will start assigning suitable tags
+* Hit ctrl+s or click "Save" to save the tags to the file
+
+Tagging a Directory
+^^^^^^^^^^^^^^^^^^^
+
+* Click on "Add Folder"
+* Select the directory of files you want to tag from your computer
+* Picard should automatically start scanning the items. If nothing happens, select the item(s) and click on "Scan"
+* Picard will start assigning suitable tags
+* Hit ctrl+s or click "Save" to save the tags to the file
+
+
+Alternative Versions
+--------------------
+
+Picard is generally accurate when it comes to determining the release of an album/track, but sometimes it can fail to get the right version. You can force it to use a particular version of an album or track using the following method:
+
+Alternative Albums
+^^^^^^^^^^^^^^^^^^
+
+* Load the directory into Picard
+* Once it has tagged the full album, right-click on the album and hover over "other versions"
+* Select the collect release from the list
+* Do this for any duplicate items until all tracks are under the correct release
+* Hit ctrl+s or click "Save" to save the tags to the files
+
+Alternative Tracks
+^^^^^^^^^^^^^^^^^^
+
+If a track is not picking up its release, do the following:
+
+* Right-click on the offending track and select "Search for Similar Tracks..."
+* Search for your release using `MusicBrainz's search syntax <https://musicbrainz.org/doc/Indexed_Search_Syntax>`_
+* Select the correct track from the list and click on "Load into Picard"
+* The track will now inherit tags from the selected track. Hit ctrl+s or click "Save" to save the tags to the file
+
+Adding Items to MusicBrainz
+---------------------------
+
+MusicBrainz is an ever-growing library of music, but it may not yet have an entry for certain items. You can add these yourself by following their `guide <https://musicbrainz.org/doc/How_to_Add_a_Release/>`_.
+
+Once you've added a new item, Picard should automatically pick up the new details based on the files' metadata. This means that it will tag the music not only for you, but for any other user who tries to tag the same item in the future.
diff --git a/docs/users/upload.rst b/docs/users/upload.rst
index 1dfa4d76fb73f2ed3bf2a8ee70a3db69f908f4f6..169c72710fa638d2999f70fef0d3a05995a19299 100644
--- a/docs/users/upload.rst
+++ b/docs/users/upload.rst
@@ -154,3 +154,30 @@ Then select the files you want to delete using the checkboxes on the left ; you
 Finally, select "Delete" in the "Action" menu and click "Go".
 
 This operation does *not* remove metadata, meaning that deleted tracks will remain visible in your library. They just won't be playable anymore.
+
+
+Common errors during import
+---------------------------
+
+.. _invalid_metadata:
+
+Invalid metadata
+::::::::::::::::
+
+This error occurs when the uploaded file miss some mandatory tags, or when some tags have
+incorrect values (e.g an empty title or artist name).
+
+To fix this issue, please retag the file properly as described in :ref:`upload-tagging`
+and reupload it.
+
+
+.. _unknown_error:
+
+Unkwown error
+:::::::::::::
+
+This error can happen for multiple reasons and likely indicates an issue with the Funkwhale
+server (e.g. misconfiguration) or with Funkwhale itself.
+
+If the issue persists when you relaunch the import, get in touch with our instance admin
+or open a support thread on our forum.
diff --git a/front/locales/app.pot b/front/locales/app.pot
index 2472e043af0b110013017cb74fea42f1436584a5..9a5a0e4c996c210eb334c53d577771c6ae0da87a 100644
--- a/front/locales/app.pot
+++ b/front/locales/app.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 16:04+0100\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,1824 +19,3063 @@ msgstr ""
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39 src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40 src/views/content/remote/Card.vue:30
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] ""
-msgstr[1] ""
-
 #: front/src/components/playlists/Card.vue:18
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] ""
 msgstr[1] ""
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr ""
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr ""
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr ""
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
 msgstr ""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr ""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr ""
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
 
 #: front/src/components/audio/artist/Card.vue:41
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] ""
 msgstr[1] ""
 
 #: front/src/components/favorites/List.vue:10
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:145
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr ""
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr ""
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr ""
 
 #: front/src/components/Footer.vue:45
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr ""
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr ""
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr ""
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/Home.vue:101
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+msgctxt "*/*/*"
+msgid "Account"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr ""
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr ""
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr ""
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr ""
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr ""
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr ""
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr ""
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr ""
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr ""
 
-#: front/src/components/audio/SearchBar.vue:26 src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: front/src/components/audio/SearchBar.vue:26 src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr ""
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] ""
-msgstr[1] ""
+#: front/src/views/admin/library/TrackDetail.vue:107
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr ""
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
 msgstr ""
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
+#: front/src/views/admin/library/AlbumDetail.vue:92
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
 msgstr ""
 
 #: front/src/components/audio/Search.vue:19 src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120 src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr ""
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr ""
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr ""
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] ""
+msgstr[1] ""
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr ""
 
+#: front/src/components/federation/FetchButton.vue:21
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:41
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr ""
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr ""
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175 src/components/auth/Settings.vue:225
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr ""
 
-#: front/src/components/audio/SearchBar.vue:25 src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: front/src/components/audio/SearchBar.vue:25 src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
 msgstr ""
 
-#: front/src/components/library/Album.vue:22 src/components/library/Track.vue:33
-msgid "Artist page"
+#: front/src/views/admin/library/ArtistDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
 msgstr ""
 
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr ""
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr ""
+
 #: front/src/components/audio/Search.vue:10 src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119 src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117 src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr ""
 
-#: front/src/components/favorites/List.vue:33 src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34 src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25 src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr ""
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr ""
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr ""
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr ""
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr ""
 
+#: front/src/components/library/Albums.vue:4
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr ""
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr ""
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr ""
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr ""
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58 src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr ""
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr ""
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr ""
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr ""
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr ""
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr ""
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr ""
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr ""
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr ""
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
+#: front/src/components/library/EditForm.vue:75
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr ""
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
 msgid "Close"
 msgstr ""
 
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr ""
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr ""
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr ""
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr ""
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:116
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
 msgstr ""
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr ""
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr ""
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr ""
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr ""
 
 #: front/src/components/auth/Signup.vue:4
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr ""
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:220
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr ""
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr ""
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr ""
 
+#: front/src/components/auth/ApplicationForm.vue:65
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr ""
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:134 src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr ""
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr ""
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr ""
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr ""
 
+#: front/src/components/library/ImportStatusModal.vue:64
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150 src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
-#: front/src/views/content/libraries/Form.vue:29 src/views/playlists/Detail.vue:33
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
+#: front/src/views/content/libraries/Form.vue:29 src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:254
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr ""
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr ""
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr ""
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr ""
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr ""
 
-#: front/src/components/favorites/List.vue:34 src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr ""
+
+#: front/src/components/favorites/List.vue:35 src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26 src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr ""
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+msgctxt "*/*/*/Noun"
+msgid "Description"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48 src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr ""
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr ""
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr ""
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr ""
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:37
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr ""
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr ""
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr ""
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr ""
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr ""
 
-#: front/src/components/audio/track/Table.vue:9 src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr ""
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr ""
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr ""
 
-#: front/src/views/content/libraries/Detail.vue:9
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23 src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
+#: front/src/views/content/libraries/Detail.vue:9 src/views/playlists/Detail.vue:31
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:246
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr ""
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr ""
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr ""
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr ""
+
+#: front/src/components/library/ArtistEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr ""
+
+#: front/src/components/library/TrackEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5 src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr ""
 
-#: front/src/components/library/Album.vue:44 src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr ""
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr ""
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr ""
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr ""
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr ""
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr ""
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr ""
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr ""
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr ""
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr ""
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr ""
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr ""
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr ""
 
+#: front/src/components/auth/Authorize.vue:6
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr ""
 
+#: front/src/components/moderation/FilterModal.vue:13
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr ""
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:73
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr ""
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr ""
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85 src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr ""
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr ""
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:84
-msgid "Filename"
+#: front/src/components/library/TrackDetail.vue:66
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
 msgstr ""
 
-#: front/src/views/admin/library/Base.vue:5 src/views/admin/library/FilesList.vue:21
-msgid "Files"
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
+msgid "Filename"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr ""
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr ""
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
 msgid "Followers"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:93
-msgid "Following"
+#: front/src/components/manage/library/LibrariesTable.vue:53
+msgctxt "Content/*/*/Noun"
+msgid "Followers"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
+msgid "Following"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr ""
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
 msgstr ""
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
+#: front/src/components/auth/Authorize.vue:28
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
 msgstr ""
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr ""
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr ""
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr ""
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr ""
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr ""
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr ""
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr ""
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr ""
 
+#: front/src/components/library/ImportStatusModal.vue:45
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr ""
+
 #: front/src/components/Footer.vue:37
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr ""
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:128
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr ""
 
+#: front/src/components/moderation/FilterModal.vue:40
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr ""
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr ""
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr ""
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr ""
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
 msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
 msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr ""
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr ""
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr ""
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] ""
 msgstr[1] ""
 
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr ""
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr ""
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:42
-#: front/src/components/manage/users/InvitationForm.vue:11
-msgid "Invitation code"
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
+#: front/src/components/auth/Signup.vue:44
+#: front/src/components/manage/users/InvitationForm.vue:11
+msgctxt "Content/*/Input.Label"
+msgid "Invitation code"
 msgstr ""
 
-#: front/src/views/admin/users/Base.vue:8 src/views/admin/users/InvitationsList.vue:3
+#: front/src/views/admin/users/Base.vue:8
 #: front/src/views/admin/users/InvitationsList.vue:24
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr ""
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr ""
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr ""
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr ""
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr ""
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+msgctxt "*/*/*/Noun"
 msgid "Libraries"
 msgstr ""
 
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+msgctxt "*/*/*"
+msgid "Libraries"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr ""
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+msgctxt "*/*/*"
 msgid "Library"
 msgstr ""
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr ""
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr ""
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr ""
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr ""
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr ""
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr ""
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr ""
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr ""
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr ""
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr ""
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr ""
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr ""
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr ""
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr ""
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:353 src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604 src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:356 src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607 src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:359 src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610 src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr ""
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr ""
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr ""
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr ""
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr ""
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr ""
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr ""
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr ""
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr ""
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr ""
 
+#: front/src/components/auth/Profile.vue:12
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr ""
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:97 src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/components/Sidebar.vue:96 src/components/manage/users/UsersTable.vue:177
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr ""
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr ""
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr ""
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr ""
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr ""
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr ""
 
-#: front/src/components/audio/track/Row.vue:40 src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124 src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: front/src/components/audio/track/Row.vue:40 src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr ""
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+msgctxt "*/*/*"
+msgid "Name"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:9
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr ""
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr ""
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr ""
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr ""
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
+msgstr ""
+
+#: front/src/components/library/TrackDetail.vue:25
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
 msgstr ""
 
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr ""
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr ""
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
 msgstr ""
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81 src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr ""
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr ""
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr ""
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr ""
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr ""
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr ""
 
-#: front/src/components/favorites/List.vue:31 src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/favorites/List.vue:32 src/components/library/Radios.vue:41
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr ""
 
-#: front/src/components/favorites/List.vue:23 src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24 src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15 src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr ""
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23 src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr ""
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr ""
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr ""
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr ""
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr ""
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:226
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:176
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:9 src/components/library/Track.vue:40
+#: front/src/components/audio/PlayButton.vue:9
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr ""
 
-#: front/src/components/audio/album/Card.vue:50
-#: front/src/components/audio/artist/Card.vue:44 src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/audio/album/Card.vue:48
+#: front/src/components/audio/artist/Card.vue:44
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11 src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr ""
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr ""
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr ""
+
+#: front/src/views/playlists/Detail.vue:91
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr ""
 
 #: front/src/views/playlists/Detail.vue:12
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] ""
 msgstr[1] ""
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr ""
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr ""
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr ""
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr ""
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225 src/views/playlists/List.vue:106
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr ""
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr ""
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr ""
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
 msgstr ""
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr ""
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr ""
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr ""
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1845,1053 +3084,1873 @@ msgstr ""
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr ""
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr ""
 
-#: front/src/components/library/Library.vue:10 src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13 src/components/library/Radios.vue:142
+msgctxt "*/*/*"
 msgid "Radios"
 msgstr ""
 
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Radios"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr ""
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:27
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr ""
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr ""
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr ""
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125 src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16 src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr ""
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
 msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
 msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr ""
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr ""
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr ""
 
+#: front/src/components/library/ArtistDetail.vue:12
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr ""
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr ""
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr ""
 
-#: front/src/components/favorites/List.vue:38 src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr ""
+
+#: front/src/components/favorites/List.vue:39 src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30 src/components/library/Radios.vue:52
+#: front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr ""
 
+#: front/src/components/library/ArtistDetail.vue:9
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr ""
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:166
-msgid "Scan skipped (previous scan is too recent)"
+#: front/src/views/content/remote/Card.vue:35
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
+msgid "Scan skipped (previous scan is too recent)"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr ""
 
-#: front/src/components/library/Artists.vue:10 src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10 src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5 src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr ""
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr ""
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:174
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
 msgstr ""
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr ""
-
 #: front/src/components/manage/users/InvitationsTable.vue:153
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr ""
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr ""
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr ""
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr ""
-
-#: front/src/components/library/Album.vue:33 src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr ""
 
-#: front/src/components/library/Library.vue:32 src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35 src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22 src/views/admin/users/Base.vue:21
 #: front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr ""
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] ""
 msgstr[1] ""
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr ""
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr ""
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] ""
 msgstr[1] ""
 
 #: front/src/components/audio/artist/Card.vue:30
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] ""
 msgstr[1] ""
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr ""
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr ""
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr ""
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr ""
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr ""
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
 msgstr ""
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr ""
-
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
-msgid "Size"
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+msgctxt "Content/*/*/Noun"
+msgid "Size"
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr ""
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr ""
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr ""
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr ""
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
+#: front/src/components/audio/PlayButton.vue:23 src/components/radios/Button.vue:4
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:86
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:95
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr ""
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr ""
+
+#: front/src/components/manage/users/UsersTable.vue:43
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr ""
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
+#: front/src/views/content/libraries/Detail.vue:28
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr ""
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr ""
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr ""
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr ""
+
+#: front/src/components/library/ArtistEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr ""
+
+#: front/src/components/library/TrackEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr ""
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr ""
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr ""
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr ""
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr ""
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/library/FileUpload.vue:38
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr ""
 
-#: front/src/components/Home.vue:121
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr ""
+
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr ""
 
+#: front/src/components/playlists/Form.vue:14
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr ""
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr ""
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr ""
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr ""
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr ""
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr ""
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
 msgstr ""
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr ""
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr ""
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr ""
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will log you out from existing devices that use the current password."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:253
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:36
-msgid "This will log you out from existing devices that use the current password."
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr ""
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21 src/edits.js:39
+msgctxt "*/*/*/Noun"
 msgid "Title"
 msgstr ""
 
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr ""
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr ""
 
-#: front/src/components/audio/SearchBar.vue:27 src/components/library/Track.vue:262
+#: front/src/components/audio/SearchBar.vue:27
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+msgctxt "*/*/*/Noun"
+msgid "Track"
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
 msgid "Track"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
 msgstr ""
 
-#: front/src/components/library/Track.vue:85
-msgid "Track information"
+#: front/src/views/admin/library/TrackDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
 msgstr ""
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
+msgid "Track information"
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
 msgstr ""
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr ""
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr ""
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr ""
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr ""
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr ""
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr ""
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr ""
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:100 src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104 src/views/content/remote/Card.vue:109
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr ""
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
 msgstr ""
 
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr ""
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr ""
 
+#: front/src/components/auth/ApplicationForm.vue:64
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr ""
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr ""
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr ""
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr ""
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr ""
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr ""
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr ""
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
 msgstr ""
 
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
+msgstr ""
+
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr ""
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr ""
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr ""
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr ""
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr ""
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr ""
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr ""
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr ""
 
-#: front/src/components/library/Album.vue:88 src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr ""
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr ""
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr ""
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr ""
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35 src/views/admin/Settings.vue:81
-#: front/src/views/admin/users/Base.vue:5 src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: front/src/components/mixins/Translations.vue:61 src/views/admin/Settings.vue:81
+#: front/src/views/admin/users/Base.vue:5 src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr ""
 
 #: front/src/components/Footer.vue:29
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr ""
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr ""
 
-#: front/src/components/library/Album.vue:37 src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr ""
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr ""
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr ""
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr ""
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+msgctxt "*/*/*"
+msgid "Visibility"
 msgstr ""
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr ""
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr ""
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr ""
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
+#: front/src/components/federation/FetchButton.vue:69
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
 msgstr ""
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr ""
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr ""
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
+#: front/src/components/auth/ApplicationForm.vue:3
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
 msgstr ""
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr ""
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr ""
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr ""
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr ""
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr ""
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr ""
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr ""
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr ""
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr ""
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr ""
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr ""
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr ""
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr ""
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr ""
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:261
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr ""
 
-#: front/src/components/Sidebar.vue:158
-msgid "You have a radio playing"
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:71
-msgid "You may have a connectivity issue."
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
+msgid "You have a radio playing"
 msgstr ""
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "You may have a connectivity issue."
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr ""
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr ""
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:215
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr ""
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr ""
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr ""
 
+#: front/src/components/auth/Settings.vue:14
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr ""
+
+#: front/src/edits.js:47
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr ""
+
+#: front/src/edits.js:54
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:183
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] ""
+msgstr[1] ""
+
+#: front/src/components/audio/PlayButton.vue:220
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] ""
+msgstr[1] ""
diff --git a/front/locales/ar/LC_MESSAGES/app.po b/front/locales/ar/LC_MESSAGES/app.po
index 9cf735552565dbe16200bda164ca419c7d617b71..33cae0a29f6c92b7686215ba49f87d894dae1f9b 100644
--- a/front/locales/ar/LC_MESSAGES/app.po
+++ b/front/locales/ar/LC_MESSAGES/app.po
@@ -1,9 +1,10 @@
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: Arabic (FunkWhale)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-17 08:33+0000\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-05-07 09:29+0000\n"
 "Last-Translator: ButterflyOfFire <butterflyoffire+funkwhale@protonmail.com>\n"
 "Language-Team: Arabic <https://translate.funkwhale.audio/projects/funkwhale/"
 "funkwhale/front/ar/>\n"
@@ -16,19 +17,28 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\"، لِـ %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } مِن %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(فارغ)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "الدخول إلى حسابك على فانك وايل Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] ""
@@ -38,9 +48,11 @@ msgstr[3] ""
 msgstr[4] ""
 msgstr[5] ""
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } مقطع"
@@ -50,7 +62,9 @@ msgstr[3] "%{ count } مَقطَع"
 msgstr[4] "%{ count } مَقاطِع"
 msgstr[5] "%{ count } مَقاطِع"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+#, fuzzy
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } مقاطع في %{ albumsCount } ألبومات"
@@ -60,27 +74,21 @@ msgstr[3] "%{ count } مَقطَع في %{ albumsCount } ألبومات"
 msgstr[4] "%{ count } مَقاطِع في %{ albumsCount } ألبومات"
 msgstr[5] "%{ count } مَقاطِع في %{ albumsCount } ألبومات"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
+msgstr[0] "مقطع يناسب عامل التصفية"
+msgstr[1] "مقطع يناسب عامل التصفية"
+msgstr[2] "مقطع يناسب عامل التصفية"
+msgstr[3] "مقطع يناسب عامل التصفية"
+msgstr[4] "مقطع يناسب عامل التصفية"
+msgstr[5] "مقطع يناسب عامل التصفية"
 
 #: front/src/components/playlists/Card.vue:18
+#, fuzzy
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} مَقطَع"
@@ -91,34 +99,48 @@ msgstr[4] "%{ count } مَقاطِع"
 msgstr[5] "%{ count } مَقاطِع"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr ""
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } سا %{ minutes } د"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } د"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
-msgstr ""
+msgstr "لقد قَبِل %{ username } طلبك لمتابعة المكتبة \"%{ library }\""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
-msgstr ""
+msgstr "لقد قام %{ username } بمتابعة مكتبتك \"%{ library }\""
+
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "يريد %{ username } متابعة مكتبتك \"%{ library }\""
 
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "الملف الشخصي لِـ %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
 
 #: front/src/components/audio/artist/Card.vue:41
+#, fuzzy
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "ألبوم واحد"
@@ -129,6 +151,8 @@ msgstr[4] "%{ count } ألبومات"
 msgstr[5] "%{ count } ألبومات"
 
 #: front/src/components/favorites/List.vue:10
+#, fuzzy
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "%{ count } مفضّلة"
@@ -138,83 +162,200 @@ msgstr[3] "%{ count } مفضّلة"
 msgstr[4] "%{ count } مفضّلات"
 msgstr[5] "%{ count } مفضّلات"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+#, fuzzy
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "مكتبة موسيقية ذات جودة عالية"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "حدث خطأ في الشبكة أثناء تحميل هذا الملف"
 
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "حدث خطأ أثناء عملية حفظ التغييرات"
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "عن %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "عن %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "عن فانك وايل Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "صفحة الألبوم"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "عن مثيل الخادوم هذا"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "تم قبوله"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "تم قبوله"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "عُطّل النفاذ"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr "الوصول إلى الملفات الصوتية والمكتبات والفنانين والألبومات والمَقاطِع"
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "إختيار عامل تصفية"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "عُطّل النفاذ"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "إضافة إلى المفضلة"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "كتم الإشعارات"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "إضافة إلى قائمة المقاطع الموسيقية …"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "عُطّل النفاذ"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
 msgstr "صِلوا إلى موسيقاكم عبر واجهة نظيفة التصميم تُركّز فعلًا على الأهمّ"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "تاريخ النفاذ"
+msgstr "عُطّل النفاذ"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "الحسابات"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "الحسابات"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "بيانات الحساب"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "إعدادات الحساب"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "إعدادات الحساب"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "حالة الحساب"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "البريد الإلكتروني الخاص بالحساب"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+#, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "الحسابات"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "الإجراء"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] ""
@@ -224,615 +365,1103 @@ msgstr[3] ""
 msgstr[4] ""
 msgstr[5] ""
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "الإجراءات"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "النشاط"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "النشاط"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "عرض النشاط"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
-msgstr ""
+msgstr "إضافة"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
-msgstr ""
+msgstr "إضافة نطاق"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+#, fuzzy
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "إضافة قاعدة إشراف جديدة"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
-msgstr ""
+msgstr "إضافة قاعدة إشراف جديدة"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "إضافة المحتوى و إدارته"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "إضافة محتوى"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "إضافة عامل تصفية"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "قم بإضافة عوامل تصفية لتخصيص إذاعتك"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "أضِف إلى قائمة الانتظار الحالية"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "إضافة إلى المفضلة"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "إضافة إلى قائمة المقاطع الموسيقية …"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "أضِف إلى قائمة الانتظار"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "أضفه إلى قائمة التشغيل هذه"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "إضافة مقطع موسيقي"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "المدير"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "الإدارة"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "الألبوم"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "الألبوم"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "مِن ألبومات هذا الفنان"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "عنوان الألبوم"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "صفحة الألبوم"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "عنوان الألبوم"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "الألبومات"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "مِن ألبومات هذا الفنان"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "الكل"
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr "ترخيص التطبيق"
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "حدث خطأ أثناء عملية حفظ التغييرات"
 
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "حدث خطأ أثناء عملية حفظ التغييرات"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "حدث خطأ أثناء عملية حفظ التغييرات"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "طرأ هناك خطأ ما، ذلك قد يعني أن السيرفر غير متصل أو أنّ الإتصال به غير ممكن"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr "حدث خطأ مجهول"
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "الإجراء"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr "تفاصيل التطبيق"
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr "مُعرِّف التطبيق"
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "قبول"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+#, fuzzy
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "قبول"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "أمتأكد من أنك تريد الخروج ؟"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "الفنان"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "الفنان"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "إسم الفنان"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "صفحة الفنان"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "إسم الفنان"
 
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "فنان ، ألبوم ، مقطع موسيقي …"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "الفنانون"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "الفنانون"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "تصاعدي"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "أطلب إعادة تعيين كلمة المرور"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "محتوى مسموع"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "اختصارات المُشغّل الصوتي"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr "ترخيص %{ app }"
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr "التطبيقات المُرخّصة"
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "قوائم المقاطع الموسيقية المتوفرة"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "الصورة الرمزية"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "العودة إلى صفحة تسجيل الدخول"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "تحديث الإعدادات"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "معدل البت"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "حجب الكل"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "تصفّح"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "تصفح المكتبة"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "تصفّح الإذاعات"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "استعراض الفنانين"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "تصفّح قوائم المَقاطِع الموسيقية"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "تصفّح الإذاعات"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "المحرّر"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "حسب %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr "إن قمت بإلغاء متابعة هذه المكتبة فسوف لن تتمكن مِن الوصول إلى محتواها."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "إلغاء"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+#, fuzzy
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
-msgstr ""
-
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "لا يمكن تغيير كلمة المرور"
+msgstr "تاريخ الإنشاء"
 
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "لا يمكن تحميل هذا الملف، تحقق أنّ حجم الملف ليس ضخما"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "تغيير اللغة"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
-msgstr "تغيير الكلمة السرية"
+msgstr "تغيير كلمتي السرية"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
-msgstr "تغيير كلمة المرور"
+msgstr "تغيير الكلمة السرية"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "عدّل كلمتك السرية"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
-msgstr "هل تريد تغيير كلمتك السريّة ؟"
+msgstr "هل تريد تغيير كلمتك السريّة؟"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "تمت مزامنة التعديلات مع السيرفر"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "سوف تتأثر كذلك الكلمة السرية لواجهة برمجة تطبيقات صاب سونيك إن قمت بتعديل كلمتك السرية."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "سوف ينجرّ ما يلي عند تعديل كلمتك السرية"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "قاعة المحادثة"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "اختر خادومك"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "مكتبة موسيقية ذات جودة عالية"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "امسح"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "امسح"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "مسح قائمة المَقاطع الموسيقية"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "مسح قائمة الانتظار الخاصة بك"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "إضغط مرة واحدة و استمع لساعات مِن الموسيقى عبر الإذاعات المُدمَجة"
 
-#: front/src/components/library/FileUpload.vue:75
-msgid "Click to select files to upload or drag and drop files or directories"
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
 msgstr ""
 
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
+msgid "Click to select files to upload or drag and drop files or directories"
+msgstr "اضغط لاختيار ملفات أو قم بسحب وإلقاء ملفات أو مجلدات"
+
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "إغلاق"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+#, fuzzy
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "إغلاق"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr "إغلاق وإعادة إنعاش الصفحة"
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "الرمز"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "تصغير"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "الإعداد"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "تأكيد"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "أكّد بريدك الإلكتروني"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "رمز التأكيد"
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "إختيار عامل تصفية"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "إختيار عامل تصفية"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
 msgstr ""
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "المساهمة"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "نسخ"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
 msgstr "نسخ المَقاطِع مِن قائمة الإنتظار الحالية إلى قائمة التشغيل"
 
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
+
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
-msgstr ""
+msgstr "انسخ والصق هذا الرمز في نص HTML على موقعك"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "الحقوق"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "لم نتمكن مِن تأكيد عنوان بريدك الإلكتروني"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "تعذر جلب المكتبة البُعدية"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "أغلِفة الألبومات و كلمات الأغاني، هدفنا هو دمجها جميعا ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "إنشاء"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "أنشئ حسابا على فانك وايل"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "أنشئ قائمة مَقاطِع موسيقية جديدة"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "أنشئ قائمة مَقاطِع موسيقية جديدة"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "أنشئ مكتبة جديدة"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "أنشئ قائمة مَقاطِع موسيقية جديدة"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "أنشئ حسابا"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "أنشئ قائمة مَقاطع موسيقية"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "أنشئ مكتبة"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "أنشئ حسابي"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "أنشئ قائمة مَقاطع موسيقية"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "أنشئ إذاعتك"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "تاريخ الإنشاء"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "الصورة الرمزية الحالية"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "المكتبة الحالية"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "المَقطَع الحالي"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "الاستعمال الحالي"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "التاريخ"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "معلومات عن المَقطَع"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "تخفيض الصوت"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "حذف"
 
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "حذف قائمة الأغاني"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr "حذف تطبيق \"%{ application }\"؟"
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "حذف المكتبة"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "حذف قاعدة الإشراف"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "حذف قائمة الأغاني"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "حذف الإذاعة"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "أتريد حذف هذه المكتبة؟"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "أتريد حذف هذه المكتبة؟"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "أتريد حذف هذه المكتبة؟"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "أتريد حذف قاعدة الإشراف هذه؟"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "أتريد حذف قاعدة الإشراف هذه؟"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "أتريد حذف هذه المكتبة؟"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "تنازليًا"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "الوصف"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "التفاصيل"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "الوصف"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "التفاصيل"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr ""
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr ""
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "تعطيل النفاذ"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "تعطيل النفاذ عبر صاب سونيك Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "تعطيل النفاذ عبر واجهة برمجة التطبيقات صاب سونيك ؟"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "معطل"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr "القرص رقم"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "إكتشف كيفية استخدام فانك وايل Funkwhale عبر التطبيقات الأخرى"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "الاسم المعروض"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "إعرضها للعامة"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "هل تودّ إفراغ قائمة المَقاطِع الموسيقية \"%{ playlist }\" ؟"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "هل تؤكّد هذا الإجراء ؟"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "متأكّد مِن أنك تريد حذف قائمة المَقاطِع الموسيقية \"%{ playlist }\" ؟"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "أتريد حقا حذف إذاعة \"%{ radio }\" ؟"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "أتريد حقا حذف إذاعة \"%{ radio }\" ؟"
+
+#: front/src/components/common/ActionTable.vue:37
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] ""
@@ -842,998 +1471,1715 @@ msgstr[3] ""
 msgstr[4] ""
 msgstr[5] ""
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "هل تريد استرجاع قائمة الإنتظار السابقة للأغاني ؟"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "الدليل"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "النطاق"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "النطاقات"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "تنزيل"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
-msgstr ""
+msgstr "اسحب والقي أعمدةً قصد ترتيب المقاطِع على قائمة التشغيل"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "المدّة"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "عنوان البريد الإلكتروني مؤكَّد"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "سهل للإستخدام"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "تعديل"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "تعديل"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "حدث خطأ أثناء تطبيق الإجراء"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "تعديل معلومات مثيل الخادوم"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "تعديل…"
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "تحديث قاعدة الإشراف"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "شغِّل هذا المَقطَع"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "شغِّل هذا المَقطَع"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "شغِّل هذا المَقطَع"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "تعديل"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "تعديل"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "البريد الإلكتروني"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "عنوان البريد الإلكتروني"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "ادمج"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "رمز الإدماج"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
-msgstr ""
+msgstr "ادرج هذا الألبوم على موقعك"
+
+#: front/src/components/library/ArtistBase.vue:37
+#, fuzzy
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "ادمج هذا المَقطع على موقعك"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "ادمج هذا المَقطع على موقعك"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr "أدخِل عنوان رابط لمكتبة ما"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
-msgstr ""
+msgstr "الرسائل المُرسَلة"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "تم تنشيطه"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "إنهاء التعديل"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "أدخِل عنوان رابط لمكتبة ما"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "أدخِل إسم إذاعة…"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr "أدخل اسم ألبوم ما…"
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "أدخِل إسم فنان…"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "أدخِل إسم قائمة مَقاطِعٍ موسيقية…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+#, fuzzy
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "ادخل عنوان البريد الإلكتروني المُقترن بحسابك"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "أدخِل عنوان بريدك الإلكتروني"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "أدخِل رمز الدعوة"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "أدخِل طلب بحثِك…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "أدخِل إسم المستخدِم"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "أدخل إسم المستخدِم أو البريد الإلكتروني"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "خطأ"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "سِجِل الأخطاء"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "سِجِل الأخطاء"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "فيه خطأ"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "حدث خطأ أثناء تطبيق الإجراء"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "حدث خطأ أثناء إرسال طلب إعادة تعيين الكلمة السرية"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "حدث خطأ أثناء تطبيق الإجراء"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "حدث خطأ أثناء عملية تعديل الكلمة السرية"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "حدث خطأ أثناء إنشاء النطاق"
 
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "حدث خطأ أثناء إنشاء القاعدة"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "حدث خطأ أثناء إنشاء الدعوة"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "حدث خطأ أثناء إنشاء القاعدة"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "حدث خطأ أثناء إنشاء الدعوة"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "حدث خطأ أثناء عملية جلب معلومات العقدة"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "حدث خطأ أثناء حفظ الإعدادات"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "حدث خطأ أثناء حفظ الإعدادات"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+#, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "حدث خطأ أثناء حفظ الإعدادات"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "فيه خطأ"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "الملفات الخاطئة"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "الجميع"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "كل مَن هم على مثيل الخادوم هذا"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+#, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "كافة مَن هم على مثيلات الخوادم"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "إستثني"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "تاريخ نهاية الصلاحية"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "منتهية الصلاحيّة"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "إنتهت صلاحيتها/ أو مستعمَلة"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "فشل"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "المَقاطع الصوتية المخفقة:"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "المَقاطع الصوتية المخفقة:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "المفضلة"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "المفضلة"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "الفديرالية"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "الفديرالية"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr "الحقل"
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "إسم الملفّ"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "الملفّات"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "إسم عامل التصفية"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "إكتمل"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr "أول زيارة"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "تاريخ أول اكتشاف"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "إتبع"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "متابعة المكتبات عن بُعد"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "طلب متابعة مُعلّق في انتظار القبول"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "المتابِعون"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "المتابِعون"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "يُتابِع"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "مِن ألبوم %{ album } لِـ %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "إتبع"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "تعطيل النفاذ"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "فانك وايل Funkwhale متوافق مع برمجيات تشغيل الموسيقى التي تدعم واجهة برمجية تطبيقات صاب سونيك."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "فانك وايل Funkwhale سهلٌ جدًا للإستخدام."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "طُوِّر فانك وايل Funkwhale لتسهيل الإستماع إلى الموسيقى التي تحبونها و لاكتشاف فنّانين جُدد."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "فانك وايل Funkwhale مجاني و يُعيد التحكّم في موسيقاكم بين أيديكم."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "فانك وايل Funkwhale يُحافظ على موسيقاكم"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "الاختصارات العامة"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "تحصّل على دعوة جديدة"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "أنقلني إلى المكتبة"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "احصلوا على بيانات وصفية ذات جودة عن موسيقاكم بفضل <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "إبدأ هنا"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "الحصول على مساعدة"
+
 #: front/src/components/Footer.vue:37
+#, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "الحصول على مساعدة"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "هيا"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "إنتقل إلى الصفحة الرئيسية"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "استعراض الفنانين"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
+msgstr "إخفاء الحساب أو محتوى النطاق مِن الجميع باستثناء المتابِعين."
+
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "إضافة محتوى"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
 msgstr ""
 
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "الرئيسية"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "ساعات مِن الموسيقى"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr ""
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "تاريخ الإستيراد"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "استيراد الموسيقى من منصات مختلفة، مثل يوتيوب أو ساوند كلاود"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "حالة الإستيراد"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "مصدر الإستيراد"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "حالة الإستيراد"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+#, fuzzy
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "حالة الإستيراد"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "تم استيراده"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "تاريخ الإستيراد"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr "تعذر الاتصال بالخادم البُعدي"
+
+#: front/src/components/moderation/FilterModal.vue:26
+#, fuzzy
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "تمت إضافتها مؤخرا"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "في المفضلة"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr "في اقتراحات الإذاعات"
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "غير ناشط"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "زيادة حجم الصوت"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr ""
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
+msgstr[0] "%{ count } مقطع"
+msgstr[1] "%{ count } مَقطَع"
+msgstr[2] "%{ count } مَقطعين"
+msgstr[3] "%{ count } مَقطَع"
+msgstr[4] "%{ count } مَقاطِع"
+msgstr[5] "%{ count } مَقاطِع"
+
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "بيانات مثيل الخادم"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "بيانات مثيل الخادم"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "معلومات عن مثيل الخادوم"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "إذاعات مثيل الخادوم"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "إعدادات مثيل الخادوم"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "بيانات مثيل الخادم"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "رمز الدعوة"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "رمز الدعوة (اختياري)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "الدعوات"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "متعقّب المشاكل"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "حافظوا على أثر موسيقاكم و أغانيكم المفضّلة"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr "اختصارات لوحة المفاتيح"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "الحسابات المعروفة"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "المكتبات المعروفة"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "آخر نشاط"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "آخِر فحص"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "آخر تعديل"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "آخر زيارة"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "آخِر زيارة"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "آخِر تحديث:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "إبدأ"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "إعرف المزيد عن مثيل الخادوم هذا"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "أتركه فارغًا للحصول على رمز عشوائي"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "أتركه فارغًا للحصول على ودجات تناسبي"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Libraries"
 msgstr "المكتبات"
 
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Libraries"
+msgstr "المكتبات"
+
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "تم تحديث المكتبة"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr ""
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "المكتبة"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "تم انشاء المكتبة"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "تم تحديث المكتبة"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "تم حذف المكتبة"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "ملفّات المكتبة"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "تم تحديث المكتبة"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "الرخصة"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+#, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "جارٍ تحميل المتابِعين…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "جارٍ تحميل المتابِعين…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "جارٍ تحميل المكتبات…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "جارٍ تحميل بيانات المكتبة…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "عملية تحميل الإشعارات جارية…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
-msgstr "عملية تحميل المكتبات البُعدية جارية…"
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "جارٍ تحميل المكتبات البُعدية…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "جارٍ تحميل بيانات الإستخدام…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "جارٍ تحميل مفضلاتك…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+#, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "حساب محلي"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "الدخول"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "الدخول إلى حسابك على فانك وايل Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "الخروج"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "مُتّصل كـ %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "الدخول"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "حالة الحساب"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "خروج"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
 msgstr "يبدو أنه ليس لديك أية مكتبة بعد، حان الأوان لإنشاء واحدة."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr ""
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "الكلمات"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "القائمة الرئيسية"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "إدارة المكتبة"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "إدارة قوائم المَقاطِع الموسيقية"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "إدارة المستخدِمين"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "إدارة القوائم الخاصة الموسيقى"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "تحديد الكل كمقروء"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "تحديد كمقروء"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "تحديد كغير مقروء"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr "مُشغّل الوسائط"
 
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "عضو منذ %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "تطبيقات الكمبيوتر والأجهزة المحمولة"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+#, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "الإشراف"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
+msgstr "قواعد الإشراف تساعدكم على التحكم في كيفية تفاعل مثيل خادومكم مع النطاقات و الحسابات الأخرى."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "تاريخ التعديل"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "تاريخ التعديل"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "الموسيقى"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "كتم"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "كتم النشاط"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "كتم الإشعارات"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "حسابي"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "وصفي الرائع"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "مكتبتي الرائعة"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "قائمتي الرائعة للمَقاطِع الموسيقية"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "إذاعتي الرائعة"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "مكتباتي"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "غير متوفر"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "الإسم"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "الإسم"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "الإسم"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "الكلمة السرية الجديدة"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "سوف يتم إضافة المَقاطِع الجديدة هنا آليًا."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "المَقطَع التالي"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "لا"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "لا تحتاج إلى تنصيب إضافاتٍ أو مُلحَقاتٍ : كل ما تحتاج إليه هي مكتبة موسيقية على الويب"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "لم نتمكّن مِن العثور على أي ألبوم يناسب طلب بحثك"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "لم نتمكّن مِن العثور على أي فنان يناسب طلب بحثك"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "لا تتوفّر هناك كلمات لهذا المَقطَع."
 
+#: front/src/components/library/TrackDetail.vue:25
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "ليس لدينا أية بيانات عن رخصة هذا المَقطع"
+
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "ليس هناك أية مكتبة مطابِقة."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
-msgstr "لم تتلق أي اشعار بعد."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr "ليس هناك أي إشعار للعرض."
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr ""
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "لا أحد غيري"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "لا أحد يتبع هذه المكتبة"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "غير مستعمَل"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "الإشعارات"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "الإشعارات"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "موقع الويب الرسمي"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
-msgstr "الكلمة السرية الجديدة"
+msgstr "الكلمة السرية القديمة"
+
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "مفتوح"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "تحديث قاعدة الإشراف"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "افتح الصفحة الشخصية"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "إطّلع عليه على ميوزيك براينز"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "افتح الصفحة الشخصية"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "افتح الصفحة الشخصية"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "افتح موقع الويب"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "أو قم بتخصيص قاعدتك"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "الترتيب"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "الترتيب"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "اتجاه الترتيب"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "المالك"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "الصفحة غير موجودة"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "الصفحة غير موجودة !"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
-msgstr ""
+msgstr "تتابُع الصفحات"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "كلمة السر"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "تم تحديث كلمة السر"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "تم تحديث كلمة السر بنجاح"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "ألبِث المَقطَع"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr "إيقاف/تشغيل المقطع الحالي"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "تم توقيفه مؤقتا"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "معلّق"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "في انتظار التسريح"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "الملفات المعلّقة"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "طلبات المتابَعة المعلَّقة"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "الملفات المعلّقة"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "الملفات المعلّقة"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "الصّلاحيّات"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "الصّلاحيّات"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "غنّي"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "تشغيل الكل"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "إعزف كافة الألبومات"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "إعزف التالي"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "شغِّل المَقطَع التالي"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "إعزف الآن"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "شغِّل المَقطَع السابق"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "شغِّل هذا المَقطَع"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "إعزف المَقطَع"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "تشغيل…"
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "قائمة المَقاطِع"
 
 #: front/src/views/playlists/Detail.vue:12
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] ""
@@ -1844,76 +3190,124 @@ msgstr[4] ""
 msgstr[5] ""
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "تم إنشاء قائمة تشغيل الموسيقى"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "محرّر قوائم تشغيل الموسيقى"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "إسم قائمة المَقاطِع"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "تم تحديث قائمة تشغيل الموسيقى"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "مدى رؤية القائمة"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "قوائم المَقاطِع"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "قوائم المَقاطِع"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "قوائم تشغيل الموسيقى ؟ متوفّرة لدينا"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "يرجى التأكّد مِن صحة الكلمة السرية"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "الرجاء التأكّد مِن صحة اسم المستخدِم و الكلمة السرية"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "نسق PNG أو GIF أو JPG. الحجم الأقصى 2 ميغابيت. سيتم تغيير حجمها إلى 400×400 بكسل."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "تتابُع الصفحات"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
+msgstr "إخفاء الحساب أو محتوى النطاق مِن الجميع باستثناء المتابِعين."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "معاينة"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "المَقطَع السابق"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "خطأ أثناء المسح"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "واصل"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "المواصلة إلى صفحة تسجيل الدخول"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "جارٍ العمل"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "افتح الصفحة الشخصية"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1922,294 +3316,557 @@ msgstr "جارٍ العمل"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
-msgstr ""
+msgstr "تفريغ"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
-msgstr ""
+msgstr "تنظيف الملفات الخاطئة وحذفها؟"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "هل تريد إزالة الملفات المعلّقة؟"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "هل تريد إزالة الملفات المتخطاة؟"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "قائمة الإنتظار"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "تم خلط قائمة الإنتظار !"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "الإذاعة"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "مُنشِئ الإذاعات و الراديو"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "تم إنشاء الإذاعة"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "إسم الإذاعة"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "تم تحديث الإذاعة"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "الإذاعات"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "الإذاعات"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr "السبب"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
-msgstr ""
+msgstr "الطلبات الواردة لمتابعة المكتبات"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "الرسائل الواردة"
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "تمت إضافتها مؤخرا"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "تمت إضافتها مؤخرا"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "تمت إضافتها إلى المفضلة حديثا"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "مَقاطِع أستُمِع إليها مؤخرا"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "إنعاش"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "إنعاش"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
+msgstr "تحديث معلومات العُقدة"
+
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "تحديث معلومات العُقدة"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "تحديث محتوى الجدول"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "مُسجّل منذ %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "إنّ التسجيلات مُغلَقة حاليًا على هذا الخادوم، يلزمك رمز دعوة للتسجيل فيه."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "مستخدِم عادي"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "رفض"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "ارفض الوسائط"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "تم رفضه"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "إعادة محاولة الإستيراد"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "آخِر زيارة"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "المكتبات البُعدية"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr ""
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "حذف"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "حذف الصورة الرمزية"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "حذف الصورة الرمزية"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "حذف مِن المفضلة"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
 msgstr ""
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
 msgstr ""
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "طلب كلمة سرية جديدة"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "متأكد مِن أنك تريد إعادة طلب كلمة سرية جديدة لواجهة برمجة تطبيقات صاب سونيك API ؟"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "طلب كلمة سرية"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "إعادة تعيين كلمتك السرية"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "إعادة محاولة الإستيراد"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "عدد نتائج البحث في كل صفحة"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "العودة إلى صفحة تسجيل الدخول"
 
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "عرض الملفات"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "القاعدة"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "احفظ"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "بدأ الإستكشاف"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "قم بالمسح الآن"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "تصاعدي"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "المسح معلق"
-
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "تم مسحها"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "تمت عملية المسح بأخطاء"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "جارٍ المسح… (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "البحث"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "البحث عن مكتبة بُعدية"
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "البحث حسب العنوان أو إسم فنان أو نطاق…"
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "البحث عبر اسم نطاق أو مستخدِم أو نبذة…"
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "البحث عبر اسم نطاق أو مستخدِم أو نبذة…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "البحث عبر اسم نطاق أو مستخدِم أو نبذة…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "البحث حسب العنوان أو إسم فنان أو ألبوم…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "البحث حسب العنوان أو إسم فنان أو ألبوم…"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
 msgstr "البحث عبر اسم نطاق أو مستخدِم أو نبذة…"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
 msgstr "البحث باستخدام اسم…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
 msgstr "البحث حسب العنوان أو إسم فنان أو ألبوم…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "البحث حسب العنوان أو إسم فنان أو نطاق…"
-
 #: front/src/components/manage/users/InvitationsTable.vue:153
+#, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "البحث باسم مستخدِم أو عنوان بريد إلكتروني أو رمز…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "البحث باسم مستخدِم أو عنوان بريد إلكتروني أو إسم…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "البحث عن فنانين أو ألبومات أو مَقاطِع صوتية…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "البحث عن بعض مِن الموسيقى"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "البحث في lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "البحث في ويكيبيديا"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr "القائمة الثانوية"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "الأقسام"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "إختيار عامل تصفية"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] ""
@@ -2219,39 +3876,48 @@ msgstr[3] ""
 msgstr[4] ""
 msgstr[5] ""
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "تحديد الصفحة الحالية فقط"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "الإعدادات"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "تم تحديث الإعدادات"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "تم تحديث الإعدادات بنجاح."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "رابط المشاركة"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"قم بمشاركة هذا الرابط مع مستخدمين آخرين ليتمكنوا مِن طلب الوصول إلى مكتبتك."
+msgstr "قم بمشاركة هذا الرابط مع مستخدمين آخرين ليتمكنوا مِن طلب الوصول إلى مكتبتك."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "رابط المشاركة"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "اعرض %{ count } مقاطع"
@@ -2262,6 +3928,7 @@ msgstr[4] "اعرض %{ count } مَقاطِع"
 msgstr[5] "اعرض %{ count } مَقاطِع"
 
 #: front/src/components/audio/artist/Card.vue:30
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] ""
@@ -2271,733 +3938,1369 @@ msgstr[3] ""
 msgstr[4] ""
 msgstr[5] ""
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "عرض اختصارات لوحة المفاتيح المتوفّرة"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "عرض الإشعارات المقروءة"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "إظهار/إخفاء الكلمة السرية"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "عرض النتائج %{ start }-%{ end } مِن %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "خلط قائمة الإنتظار"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "خلط قائمة الإنتظار"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "التسجيل"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "التسجيل"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "تاريخ التسجيل"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
-msgstr "كتم النشاط"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "كتم الإشعارات"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+#, fuzzy
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "الحجم"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "الحجم"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "تمّ تجاهله"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "الملفات التي تمّ تجاهلها"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "البرمجيات"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "المعذرة، إنّ الصفحة التي قمت بطلبها غير موجودة :"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "شفرة المصدر"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "عضو في الفريق"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "إبدأ"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "إيقاف الإذاعة"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "الإحصائيات"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:86
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "الحالة"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "الحالة"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "الحالة"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "الحالة"
+
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "الحالة"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "إيقاف"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "الحالة"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "إيقاف الإذاعة"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "إرسال"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "صاب سونيك"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "الكلمة السرية لواجهة برمجة التطبيقات صاب سونيك Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "لا يمكننا تحميل هذا المَقطَع"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "لا يمكننا تحميل هذا المَقطَع"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "لا يمكننا تحميل هذا المَقطَع"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "الخيارات المتاحة"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "الملخص"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "المنتدى"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr ""
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "مزامنة التغييرات مع الخادم…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "تم نسخ النص إلى الحافظة!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "حسنًا الأمر سهل : أحببنا غروف شارْك و أردنا تصميم مشروع أحسَن منه بكثير."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "تم تصميم شعار فانك وايل funkwhale بفضل و كَرَم Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr "سوف يتم حذف المكتبة و كل ما تحتويه مِن مقاطِع. لا يمكن الغاء هذا الإجراء."
+
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
 msgstr ""
-"سوف يتم حذف المكتبة و كل ما تحتويه مِن مقاطِع. لا يمكن الغاء هذا الإجراء."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr "الملفات الموسيقية التي هي في صدد الإرسال موسومة بطريقة صحيحة:"
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
-msgstr ""
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "سيتم تشغيل المقطَع اللاحق تلقائيا خلال بضع ثوان…"
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "المنصّة مجانية و مفتوحة المصدر، بإمكانكم تنصيبها و تعديلها كما يحلو لكم دون قيود"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "تم إنشاء قائمة تشغيل الموسيقى"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "لا يمكن الغاء هذا الإجراء."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "واجهة برمجة تطبيقات صاب سونيك غير متوفرة غلى مثيل خادوم فانك وايل الحالي."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "لا يمكننا إضافة المَقطَع إلى قائمة التشغيل"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "لا يمكن الغاء هذا الإجراء."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "نسق ملفات الموسيقى المُرسَلة يجب أن تكون OGG أو Flac أو MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
 msgstr "هناك عدة أساليب لجلب محتويات جديدة و عرضها هنا."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "لا يمكن الغاء هذا الإجراء."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "هذا الألبوم متوفر على المكتبات التالية:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "هذا الفنان متوفر على المكتبات التالية:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr ""
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr "مثيل الخادوم هذا يُتيح مساحة تخرين تُقدَّر بـ %{quota} لكل مستخدِم."
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "هذا أنت !"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "تحتوي هذه المكتبة على الموسيقى الخاصة بي، أتمنى أنها ستلقَى إعجابك."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "تم ارسال المقطع ولكن لم تتم معالجته بعد على الخادم"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "إنّ المقطع متوفّر مِن قبل في إحدى مكتباتك"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
 msgstr ""
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "هذا المقطع متوفر كذلك على المكتبات التالية:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "سوف يؤدي ذلك إلى الحذف الكُلّي لقائمة التشغيل هذه و لا يُمكن إلغاء العملية و العودة."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "سوف يؤدي ذلك إلى الحذف الكُلّي لهذه الإذاعة و لا يُمكن إلغاء العملية و العودة."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr ""
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr ""
-"ذلك سوف يؤدي إلى حذف بياناتك المحلية نهائيا و إخراجك. أمتأكد أنك ترغب في "
-"المواصلة؟"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
+msgstr "سيؤدي ذلك إلى إخراجك مِن الأجهزة الحالية التي تستخدم هذه الكلمة السرية."
+
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "سوف يؤدي ذلك إلى الحذف الكُلّي لقائمة التشغيل هذه و لا يُمكن إلغاء العملية و العودة."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/playlists/Editor.vue:54
+#, fuzzy
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
-msgstr ""
+msgstr "سوف يؤدي ذلك إلى الحذف الكُلّي لقائمة التشغيل هذه و لا يُمكن إلغاء العملية و العودة."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "العنوان"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Title"
 msgstr "العنوان"
 
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr "العنوان"
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "الحجم الإجمالي"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "الحجم الإجمالي للملفات المتوفّرة في هذه المكتبة"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "العدد الإجمالي للمستخدِمين"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "المَقطَع"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "إنّ المقطع متوفّر مِن قبل في إحدى مكتباتك"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "المَقطَع"
+
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
 
-#: front/src/components/library/Track.vue:85
+#: front/src/views/admin/library/TrackDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "اسم المَقطَع"
+
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "معلومات عن المَقطَع"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "مقطع يناسب عامل التصفية"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "اسم المَقطَع"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr ""
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "المَقاطِع"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "مَقاطِع"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "المَقاطِع"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "مَقاطِع لهذا الفنان"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "مَقاطِع تم الإعجاب بها"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "مَقاطِع أستُمِع إليها"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "مقطع يناسب عامل التصفية"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "النوع"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "النوع"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr ""
+msgstr "تحديث قاعدة الإشراف"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "إلغاء المتابعة"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "أتريد إلغاء متابعة هذه المكتبة؟"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "لسوء الحظ، لم يأخذ أصحاب مثيل الخادوم هذا الوقت الكافي لاستكمال هذه الصفحة."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "موسيقى بلا حدود"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "إلغاء الكتم"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "تحديث"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "تحديث قائمة المَقاطِع الموسيقية"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "تحديث الصورة الرمزية"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "تحديث المكتبة"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "تحديث قاعدة الإشراف"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "تحديث قائمة المَقاطِع الموسيقية"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "تحديث الإعدادات"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "قم بتحديث كلمتك السرية"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "أرسل"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "إرسال صورة رمزية جديدة"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "إرسال محتوى صوتي"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "تاريخ التحميل"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "تاريخ التحميل"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "تم رفض الإرسال، تحقق أن حجم الملف ليس ضخما و أنّ مساحة التخرين المسموح بها كافية"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
-"تم رفض الإرسال، تحقق أن حجم الملف ليس ضخما و أنّ مساحة التخرين المسموح بها "
-"كافية"
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "إرسال مقاطع موسيقية جديدة"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "حصة التحميل"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
+msgstr "انتهت مهلة الإرسال، الرجاء إعادة المحاولة"
+
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "تم تحميلها"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "عملية الإرسال جارية"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "الإرسال جارٍ…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "المُرسَلة"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "المُرسَلة"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "المُرسَلة"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "إستخدم مثيل خادوم آخَر"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "استخدم هذه الإستمارة لطلب إعادة ضبط كلمة المرور. سنرسل بريدا الكترونيا إلى العنوان المعين مرفوقا بتعليمات لإعادة ضبط كلمتك السرية."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "مُستخدَم"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "المستخدِم"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "نشاط المستخدِم"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "مكتبات المستخدِم"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "إذاعات المستخدِمين"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "إسم المستخدِم"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "إسم المستخدِم أو عنوان البريد الإلكتروني"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "مستخدِم"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "المستخدِمون"
 
 #: front/src/components/Footer.vue:29
+#, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "لاستخدام فانك وايل"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "الإصدار %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "عرض الملفات"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "إطّلع عليه على ميوزيك براينز"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "المشاهدة"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "المشاهدة: كل مَن هم على مثيل الخادوم هذا"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "العرض: للجميع، بما في ذلك لمثيلات الخوادم الأخرى"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "المشاهدة: لا أحد غيري"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "المشاهدة"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
-msgstr ""
+msgstr "مستوى الصوت %{ number }"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "لا يمكننا إضافة المَقطَع إلى قائمة التشغيل"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "لا يمكننا إنشاء قائمة التشغيل"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "لا يمكننا إنشاء حسابك"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "لا يمكننا تحميل هذا المَقطَع"
+#: front/src/components/federation/FetchButton.vue:69
+#, fuzzy
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "جارٍ تحميل مفضلاتك…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "تعذر علينا تسجيل دخولك"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "تعذّر علينا حفظ صورتك الرمزية"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "تعذّر علينا حفظ إعداداتك"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "لا يمكننا إنشاء حسابك"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "لا نتعقّبك و لا نزعجك بالإعلانات"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "ليس لدينا أية بيانات عن حقوق التأليف لهذا المَقطع"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "ليس لدينا أية بيانات عن رخصة هذا المَقطع"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "ننصحكم باستخدام برنامج Picard لهذا الغرض."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "نعتقد أنّ الاستماع إلى الموسيقى ينبغي أن يكون سهلًا."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "المعذرة، إنّ الصفحة التي قمت بطلبها غير موجودة :"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "مرحبًا"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "أهلا وسهلا بك على فانك وايل Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "لماذا فانك وايل Funkwhale ؟"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "طول الودجات"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "عرض الودجات"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "نعم"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "نعم، أؤكد الخروج !"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "إنك بصدد إرسال موسيقى إلى مكتبتك الصوتية. قبل المواصلة، ندعوك إلى التحقق من أنّ:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "أنت متّصل حاليا بصفة %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr ""
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "يمكِنك دعوة أصدقائك و عائلتك للإنظمام إلى مثيل خادومك للإستمتاع بموسيقاك"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "بإمكانك الآن استعمال الخدمة مِن دون قيود."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "يمكنك إنشاء قناتك الإذاعية الخاصة بك عبر هذه الواجهة و تشغيل مقاطعك كيفما شئت."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "ليس لدينا أية بيانات عن رخصة هذا المَقطع"
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "ليس لدينا أية بيانات عن رخصة هذا المَقطع"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
-msgstr ""
+msgstr "ليس لدينا أية بيانات عن رخصة هذا المَقطع"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
+msgstr "ليس لدينا أية بيانات عن رخصة هذا المَقطع"
+
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
 msgstr ""
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "إنك تستمع إلى إذاعة"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr "ربما عندك مشكلة في الاتصال."
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "يلزمك اختيار مثيل خادوم قصد المواصلة"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr ""
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "يتوجب عليك تحديث كلمتك السرية على العملاء الآخرين اللذين يشتغلون بها."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "تم إنشاء قائمة تشغيل الموسيقى"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "إشعاراتك"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "مفضّلاتك"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "موسيقاك، كما يحلو لك"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "إشعاراتك"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "تم تحديث كلمتك السرية بنجاح."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "تم تحديث الإعدادات"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr ""
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "تتابُع الصفحات"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "الحقوق"
+
+#: front/src/components/library/AlbumBase.vue:183
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+#: front/src/components/audio/PlayButton.vue:220
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
diff --git a/front/locales/de/LC_MESSAGES/app.po b/front/locales/de/LC_MESSAGES/app.po
index a65275c31b45618e209eead9635866022d16d9e0..b6a0983b722c591d64657ddca3cfc52628f5da54 100644
--- a/front/locales/de/LC_MESSAGES/app.po
+++ b/front/locales/de/LC_MESSAGES/app.po
@@ -7,9 +7,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-22 08:45+0000\n"
-"Last-Translator: jovuit <jo.vuitton@gmail.com>\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-03-11 09:11+0000\n"
+"Last-Translator: gerry_the_hat <gerd-schumann@web.de>\n"
 "Language-Team: none\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
@@ -19,1888 +19,3232 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\", von %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } von %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(leer)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Melde Dich bei Deinem Funkwhale-Konto an"
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } von %{ total } ausgewählt"
 msgstr[1] "%{ count } von %{ total } ausgewählt"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
-msgstr[0] "%{ count } Track"
-msgstr[1] "%{ count } Tracks"
+msgstr[0] "%{ count } Titel"
+msgstr[1] "%{ count } Titel"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
-msgstr[0] "%{ count } Track in %{ albumsCount } Alben"
-msgstr[1] "%{ count } Tracks in %{ albumsCount } Alben"
+msgstr[0] "%{ count } Titel in %{ albumsCount } Alben"
+msgstr[1] "%{ count } Titel in %{ albumsCount } Alben"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
-msgstr[0] "%{ count } Track entspricht dem ausgewählten Filter"
-msgstr[1] "%{ count } Tracks entsprechen dem ausgewählten Filter"
-
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "1 Track wurde zur Wiedergabeliste hinzugefügt"
-msgstr[1] "%{ count } Tracks wurden zur Wiedergabeliste hinzugefügt"
+msgstr[0] "%{ count } Track entspricht den ausgewählten Filtern"
+msgstr[1] "%{ count } Tracks entsprechen den ausgewählten Filtern"
 
 #: front/src/components/playlists/Card.vue:18
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
-msgstr[0] "%{ count} Track"
-msgstr[1] "%{ count} Tracks"
+msgstr[0] "%{ count} Titel"
+msgstr[1] "%{ count} Titel"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ current } von %{ max } belegt"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } h %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
-msgstr ""
-"Das Abonnieren zur Meditahek \"%{ library }\" wurde von %{ username } "
-"zugesagt"
+msgstr "Die Abonnieren-Anfrage zur Meditahek \"%{ library }\" wurde von %{ username } bestätigt"
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr "%{ username } hat deine Mediathek \"%{ library }\" abonniert"
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } möchte deine Mediathek \"%{ library }\" abonnieren"
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Profil von %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">Ãœber "
-"%{instanceName}</translate>"
 
 #: front/src/components/audio/artist/Card.vue:41
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 Album"
 msgstr[1] "%{ count } Alben"
 
 #: front/src/components/favorites/List.vue:10
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 Favorit"
 msgstr[1] "%{ count } Favoriten"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Eine übersichtliche Mediathek"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Beim Hochladen ist ein Netzwerkfehler aufgetreten"
 
+#: front/src/components/library/EditForm.vue:145
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Kurze Beschreibung der Änderungen."
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "Ãœber %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "Ãœber %{ instanceName }"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "Ãœber Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Mehr erfahren"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "Ãœber diese Instanz"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Akzeptieren"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Akzeptiert"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Zugriff deaktiviert"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
-msgstr "Greife auf deine Musik mit einer übersichtliche Oberfläche zu, die sich auf das konzentriert, was wirklich wichtig ist"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Filter auswählen"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Zugriff deaktiviert"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Zu deinen Favoriten hinzufügen"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr "In den Favoriten- oder Abspiellisten anderer Nutzer"
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Benachrichtigungen stummschalten"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Zu einer Wiedergabeliste hinzufügen…"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Zugriff deaktiviert"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr "Greife auf Deine Musik mit einer übersichtlichen Oberfläche zu, die sich auf das beschränkt, was wirklich wichtig ist"
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "Zugriffsdatum"
+msgstr "Zugriff deaktiviert"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Konten"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Konten"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
-msgstr "Kontodaten"
+msgstr "Kontoübersicht"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Kontoeinstellungen"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Kontoeinstellungen"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Kontostatus"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
-msgstr "E-Mail-Adresse des Kontos"
+msgstr "Konto-E-Mail-Adresse"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+#, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Konten"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Aktion"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "Die Aktion %{ action } wurde erfolgreich für %{ count } Element gestartet"
 msgstr[1] "Die Aktion %{ action } wurde erfolgreich für %{ count } Elemente gestartet"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Aktionen"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Aktiv"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Aktivität"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
-msgstr "Sichtbarkeit der Aktivität"
+msgstr "Sichtbarkeit der Aktivitäten"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Hinzufügen"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Domain hinzufügen"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Moderationsregel hinzufügen"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Moderationsregel hinzufügen"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Inhalte hochladen und verwalten"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
-msgstr "Inhalt hinzufügen"
+msgstr "Inhalte hinzufügen"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Filter hinzufügen"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Füge Filter hinzu, um dein Radio zu personalisieren"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
-msgstr "Zur Wiedergabeliste hinzufügen"
+msgstr "Zur Warteschlange hinzufügen"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Zu deinen Favoriten hinzufügen"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
-msgstr "Zu einer Playlist hinzufügen…"
+msgstr "Zu einer Wiedergabeliste hinzufügen…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
-msgstr "Zur Wiedergabeliste hinzufügen"
+msgstr "Zur Warteschlange hinzufügen"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
-msgstr "Zu dieser Playlist hinzufügen"
+msgstr "Zur Wiedergabeliste hinzufügen"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
-msgstr "Track hinzufügen"
+msgstr "Titel hinzufügen"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Admin"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
-msgstr "Administration"
+msgstr "Verwaltung"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Album"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Album mit einem Track, von %{ artist }"
-msgstr[1] "Album mit %{ count } Tracks, von %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Album"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Alben von diesem/-r Künstler/in"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "Albumname"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Albumseite"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Albumname"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Alben"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
-msgstr "Alben von diesem Künstler·in"
+msgstr "Alben von diesem/-r Künstler/in"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Alles"
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "%{ count } von %{ total } ausgewählt"
+msgstr[1] "%{ count } von %{ total } ausgewählt"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
-msgstr "Beim Speichern deiner Änderungen ist ein Fehler aufgetreten"
+msgstr "Beim Speichern Deiner Änderungen ist ein Fehler aufgetreten"
+
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Beim Speichern Deiner Änderungen ist ein Fehler aufgetreten"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Beim Speichern Deiner Änderungen ist ein Fehler aufgetreten"
 
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
-msgstr "Ein unbekannter Fehler ist aufgetreten, vielleicht ist der Server ausgeschaltet oder er kann nicht erreicht werden"
+msgstr "Ein unbekannter Fehler ist aufgetreten. Eventuell ist der Server ausgeschaltet oder er kann nicht erreicht werden"
+
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Aktion"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
+msgstr "Bestätigen"
+
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+#, fuzzy
+msgctxt "Content/*/*/Short"
+msgid "Approved"
 msgstr "Bestätigt"
 
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr "Bestätigt und verarbeitet"
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
-msgstr "Möchtest du dich wirklich ausloggen?"
+msgstr "Möchtest du dich wirklich abmelden?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Künstler·in"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Künstler·in"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Künstlername"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Künstlerseite"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Künstlername"
 
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
-msgstr "Künstler, Künstlerin, Album, Track…"
+msgstr "Künstler·in, Album, Titel…"
+
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Künstler·innen"
 
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
-msgstr "Künstler und Künstlerinnen"
+msgstr "Künstler·innen"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
-msgstr "Zunehmend"
+msgstr "Aufsteigend"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
-msgstr "Eine Kennwortzurücksetzung beantragen"
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+msgstr "Zurücksetzen des Kennworts beantragen"
+
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Audio-Inhalt"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Audio-Player-Tastenkombinationen"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
-msgstr "Verfügbare Playlists"
+msgstr "Verfügbare Wiedergabelisten"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Profilbild"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Zurück zur Anmeldung"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Einstellungen aktualisieren"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Bitrate"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "Alles blockieren"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"Alles von diesem Konto bzw. Domain blockieren. Die Verbindung mit dieser "
-"Entität wird unterbrochen, und der entsprechende Inhalt (Tracks, "
-"Mediatheken, Abonnement, usw.) wird gelöscht"
+msgstr "Alles von diesem Konto oder dieser Domain blockieren. Das unterbindet jedwede Interaktion mit dieser Instanz, und alle zugehörigen Inhalte (Titel, Mediatheken, Abonnements, usw.) werden gelöscht"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Durchsuchen"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Die Mediathek durchsuchen"
 
+#: front/src/components/library/Albums.vue:4
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Alben durchsuchen"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Künstler·innen durchsuchen"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
-msgstr "Playlists durchsuchen"
+msgstr "Wiedergabelisten durchsuchen"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Radios durchsuchen"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Editor"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "Von %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
-msgstr ""
-"Wenn du dieser Mediathek nicht mehr folgst, verlierst du den Zugriff auf "
-"ihre Inhalte."
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+msgstr "Wenn du diese Mediathek nicht mehr folgst, verlierst du den Zugriff auf alle ihre Inhalte."
+
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
-msgstr "Cache-Volumen"
+msgstr "Cache-Größe"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
-msgstr "Kandidaten"
-
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Das Kennwort kann nicht geändert werden"
+msgstr "Entsprechende Tracks"
 
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
-msgstr ""
-"Die Datei kann nicht hochgeladen werden. Bitte prüfe, dass sie nicht zu groß "
-"ist"
+msgstr "Die Datei kann nicht hochgeladen werden. Bitte prüfe, dass sie nicht zu groß ist"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Sprache ändern"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
-msgstr "Mein Kennwort wechseln"
+msgstr "Mein Kennwort ändern"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
-msgstr "Kennwortwechsel"
+msgstr "Kennwort ändern"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
-msgstr "Kennwortwechsel"
+msgstr "Kennwort ändern"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
-msgstr "Dein Kennwort wechseln?"
+msgstr "Möchtest du dein Kennwort ändern?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Änderungen synchronisiert"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
-msgstr "Mit Änderung deines Kennworts wird das Kennwort für die Subsonic-API zurückgesetzt, sofern du eins erstellt hast."
+msgstr "Beim Ändern deines Kennworts wird das Kennwort für die Subsonic-API zurückgesetzt, sofern du eins erstellt hast."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
-msgstr "Wenn du dein Kennwort änderst, hat dies folgende Auswirkungen"
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
+msgstr "Wenn du dein Kennwort änderst, hat dies folgende Auswirkungen:"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Chat-Raum"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Wähle deine Instanz"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Eine übersichtliche Mediathek"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Löschen"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Löschen"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
-msgstr "Playlist leeren"
+msgstr "Wiedergabeliste leeren"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
-msgstr "Wiedergabeliste leeren"
+msgstr "Warteschlange leeren"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
-msgstr "Einmal clicken, und Musik studenlang dank der Radios anhören"
+msgstr "Klicke einmal und höre dank der eingebauten Radios studenlang Musik"
+
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
-msgstr "Zum Hochladen klicken oder Dateien und Ordner hier her ziehen"
+msgstr "Zum Hochladen klicken oder Dateien und Ordner hierher ziehen und ablegen"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "Schließen"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+#, fuzzy
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "Schließen"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
-msgstr "Kode"
+msgstr "Code"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
-msgstr "Minimieren"
+msgstr "Zuklappen"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Einstellungen"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Bestätigen"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "E-Mail-Adresse bestätigen"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Bestätigungscode"
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr "Filter erfolgreich hinzugefügt"
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Filter auswählen"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Filter auswählen"
+
+#: front/src/components/auth/Settings.vue:119
+#, fuzzy
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr "Mit Filtern können Inhalte verborgen werden, die nicht angezeigt werdern sollen."
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
-msgstr "Der Inhalt wurde aktualisiert und wird beim Neuladen der Seite gezeigt"
+msgstr "Der Inhalt wurde aktualisiert. Um den neuesten Inhalt zu sehen, geh auf Aktualisieren"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Mitmachen"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Kopieren"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
-msgstr "Die Wiedergabeliste zur Playlist hinzufügen"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
+msgstr "Die Warteschlange zur Wiedergabeliste hinzufügen"
+
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
-msgstr "Füge dieses Kode in deine HTML-Webseite ein"
+msgstr "Füge diesen Code in Deine HTML-Webseite ein"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
-msgstr "Urheberecht"
+msgstr "Urheberrecht"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Deine E-Mail-Adresse konnte nicht bestätigt werden"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
-msgstr "Die Fernmediathek konnte nicht abgerufen werden"
-
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-"Ein Fehler ist bei der Verarbeitung des Tracks aufgetreten. Überprüfe bitte, "
-"dass er richtig verschlagwortet ist"
+msgstr "Die entfernte Mediathek konnte nicht abgerufen werden"
 
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
-msgstr "Albumcover, Songtexte, unser Ziel ist es, alle zu haben ;)"
+msgstr "Albumcover, Liedtexte - unser Ziel ist es, alle zu haben ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Erstellen"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
-msgstr "Erstelle ein Funkwhale-Konto"
+msgstr "Funkwhale-Konto erstellen"
+
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Eine neue Wiedergabeliste erstellen"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Eine neue Wiedergabeliste erstellen"
 
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
-msgstr "Eine neue Mediathek erstellen"
+msgstr "Neue Mediathek anlegen"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
-msgstr "Eine neue Playlist erstellen"
+msgstr "Eine neue Wiedergabeliste erstellen"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Konto erstellen"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Eine Wiedergabeliste erstellen"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Mediathek erstellen"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Mein Konto erstellen"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
-msgstr "Eine Playlist erstellen"
+msgstr "Eine Wiedergabeliste erstellen"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Dein eigenes Radio erstellen"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Erstelldatum"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Aktuelles Profilbild"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Aktuelle Mediathek"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
-msgstr "Aktueller Track"
+msgstr "Aktueller Titel"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Aktuelle Nutzung"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Datum"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Titelinformation"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Lautstärke verringern"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Löschen"
 
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Wiedergabeliste löschen"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Mediathek löschen"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Moderationsregel löschen"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
-msgstr "Playlist löschen"
+msgstr "Wiedergabeliste löschen"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Radio löschen"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Diese Mediathek löschen?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Diese Mediathek löschen?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Diese Mediathek löschen?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Diese Moderationsregel löschen?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Diese Moderationsregel löschen?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Diese Mediathek löschen?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Absteigend"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Beschreibung"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Detail"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Beschreibung"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Details"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
-msgstr ""
-"Stelle das Speichervolumen der nutzenden Person fest. Beim Leerlassen wird "
-"der Standardwert dieser Instanz verwendet."
+msgstr "Lege das Speichervolumen des Nutzers fest. Wird kein Wert angegeben, wird der Standardwert der Instanz verwendet."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
-msgstr "Stelle fest, wer deine Aktivität sehen kann"
+msgstr "Lege fest, wer deine Aktivität sehen kann"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Zugriff deaktivieren"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Subsonic-Zugriff deaktivieren"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Subsonic-API-Zugriff deaktivieren?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Deaktiviert"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
-msgstr "Entdecke, wie du Funkwhale von anderen Apps benutzen kannst"
+msgstr "Entdecke, wie du Funkwhale von anderen Apps aus benutzen kannst"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Anzeigename"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
-msgstr "Öffentlich zeigen"
+msgstr "Öffentlich anzeigen"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Lade bitte keine Datei aus diesem Konto oder Domain (Audio-Inhalt, Album-"
-"Cover, Profilbild, usw.). Der existierende Inhalt wird ebenfalls gelöscht."
+msgstr "Lade keine Medien (Audio-Inhalt, Album-Cover, Profilbild, usw.) aus diesem Konto oder Domain. Alle existierenden Inhalte werden ebenfalls gelöscht."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
-msgstr "Möchtest du die Playlist \"%{ playlist }\" wirklich leeren?"
+msgstr "Möchtest du die Wiedergabeliste \"%{ playlist }\" wirklich leeren?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
-msgstr "Aktion bestätigen?"
+msgstr "Vorgang bestätigen?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
-msgstr "Möchtest du die Playlist \"%{ playlist }\" löschen?"
+msgstr "Möchtest du die Wiedergabeliste \"%{ playlist }\" löschen?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Möchtest du das Radio \"%{ radio }\" löschen?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Möchtest du Inhalte von \"%{ name }\" verbergen?"
+
+#: front/src/components/common/ActionTable.vue:37
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Möchtest du %{ action } auf %{ count } Element ausführen?"
 msgstr[1] "Möchtest du %{ action } auf %{ count } Elemente ausführen?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
-msgstr "Möchtest du die Wiedergabeliste zurückerstellen?"
+msgstr "Möchtest du die vorherige Warteschlange wiederherstellen?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Dokumentation"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Domain"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Domains"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Herunterladen"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
-msgstr "Um die Playlist umzuordnen, klicke und schiebe die Tracks hin und her"
+msgstr "Klicke die Titel an und verschiebe sie, um die Wiedergabeliste umzuordnen"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Dauer"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "E-Mail-Adresse bestätigt"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
-msgstr "Leicht zu bedienen"
+msgstr "Benutzerfreundlich"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Bearbeiten"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Bearbeiten"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Fehler beim Ausführen des Vorgangs"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
-msgstr "Die Infos dieser Instanz bearbeiten"
+msgstr "Instanzdaten bearbeiten"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Moderationsregel ändern"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Diesen Titel ändern"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Diesen Titel ändern"
+
+#: front/src/components/library/TrackEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Diesen Titel ändern"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Bearbeiten…"
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Bearbeiten"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Bearbeiten"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "E-Mail-Adresse"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "E-Mail-Adresse"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Integrieren"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
-msgstr "Kode integrieren"
+msgstr "Code integrieren"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
-msgstr "Integriere dieses Album auf deiner Webseite"
+msgstr "Bette dieses Album auf Deiner Webseite ein"
+
+#: front/src/components/library/ArtistBase.vue:37
+#, fuzzy
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Bette diesen Track auf Deiner Webseite ein"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
-msgstr "Integriere diesen Track auf deiner Webseite"
+msgstr "Bette diesen Track auf Deiner Webseite ein"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
-msgstr "Ausgehende Abonnements"
+msgstr "Ausgehende Mediatheks-Abonnements"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr "Verschickte Nachrichten"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "Aktiviert"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
-msgstr "Bearbeitung abschließen"
+msgstr "Bearbeitung beenden"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
-msgstr "Gebe eine Mediathek-URL ein"
+msgstr "Gib eine Mediathek-URL ein"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Name des Radios eingeben…"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr "Album Titel eingeben..."
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Künstlername eingeben…"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
-msgstr "Playlist-Name eingeben…"
+msgstr "Name der Wiedergabeliste eingeben…"
+
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Gib die E-Mail-Adresse ein, die mit deinem Konto verknüpft ist"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Gib deine E-Mail-Adresse ein"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
-msgstr "Gib deinen Einladungskode ein (Groß- und Kleinschreibung wird nicht berücksichtigt)"
+msgstr "Gib deinen Einladungscode ein (Groß- und Kleinschreibung wird nicht berücksichtigt)"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Suche eingeben…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Benutzername eingeben"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Benutzername oder E-Mail-Adresse eingeben"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Fehler"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Fehlerbericht"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Fehlerbericht"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Ein Fehler ist aufgetreten"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
-msgstr "Fehler bei der Ausführung der Aktion"
+msgstr "Fehler beim Ausführen des Vorgangs"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
-msgstr "Fehler bei der Zurücksetzung des Kennworts"
+msgstr "Fehler beim Zurücksetzen des Kennworts"
+
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Fehler beim Ausführen des Vorgangs"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
-msgstr "Fehler bei der Änderung deines Kennworts"
+msgstr "Fehler beim Ändern deines Kennworts"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
-msgstr "Fehler bei der Erstellung des Domains"
+msgstr "Fehler beim Erstellen der Domain"
+
+#: front/src/components/moderation/FilterModal.vue:13
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Fehler beim Erstellen der Regel"
 
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Fehler bei der Erstellung der Einladung"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
-msgstr "Fehler bei der Erstellung der Regel"
+msgstr "Fehler beim Erstellen der Regel"
+
+#: front/src/components/auth/Authorize.vue:7
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Fehler bei der Erstellung der Einladung"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
-msgstr "Fehler beim Abrufen des Knoten"
+msgstr "Fehler beim Abrufen der Knoten-Information"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Fehler beim Speichern der Einstellungen"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
-msgstr "Fehler bei der Speicherung der Einstellungen"
+msgstr "Fehler beim Speichern der Einstellungen"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Fehler beim Speichern der Einstellungen"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Ein Fehler ist aufgetreten"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Fehlgeschlagene Dateien"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Alle"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
-msgstr "Alle auf dieser Instanz"
+msgstr "Jerder auf dieser Instanz"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+#, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
-msgstr "Alle, auf alle Instanzen"
+msgstr "Jeder, auf allen Instanzen"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Ausschließen"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Ablaufdatum"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Abgelaufen"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Abgelaufen bzw. benutzt"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
-"Begründe hier die Moderationsregel, sodass du es nicht vergisst. Je nach den "
-"Einstellungen deiner Instanz können die Nutzenden die Moderationsregeln "
-"ansehen, um die Moderation ggf. besser verstehen zu können."
+msgstr "Erkläre, warum Du die Regel festlegst. Abhängig von Deiner Instanzkonfiguration hilft Dir das, Dich daran zu erinnern, warum Du bzgl. des Kontos oder dieser Domäne so gehandelt hast. Dies kann öffentlich eingesehen werden damit die Benutzer verstehen, welche Moderationsregeln gelten."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "Fehlgeschlagen"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
-msgstr "Fehlgeschlagene Tracks:"
+msgstr "Fehlgeschlagene Titel:"
+
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Fehlgeschlagene Titel:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Favoriten"
 
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Favoriten"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Föderation"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Föderation"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr "Feld"
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Dateiname"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Dateien"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Filtername"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Beendet"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
-msgstr "Erstmal gesehen"
+msgstr "Erstmals gesehen"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
-msgstr "Erstmal gesehen"
+msgstr "Erstmals gesehen"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Abonnieren"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
-msgstr "Entfernte Mediatheken abonnieren"
+msgstr "Fernmediatheken abonnieren"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
-msgstr "Ausstehende Abonnieren-Anfrage"
+msgstr "Ausstehende Abonnements-Anfrage"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Abonnenten"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Abonnenten"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Abonniert"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Aus dem Album %{ album } von %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Abonnieren"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Zugriff deaktivieren"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
-msgstr ""
-"Funkwhale ist mit anderen Mediaplayer kompatibel, die die Subsonic-API "
-"unterstützen."
+msgstr "Funkwhale ist kompatibel mit anderen Mediaplayern, die die Subsonic-API unterstützen."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
-msgstr "Funkwhale ist sehr einfach zu benutzen."
+msgstr "Funkwhale ist absolut einfach zu benutzen."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
-msgstr "Funkwhale hat es leicht gemacht, deine Lieblingsmusik anzuhören und neue Künstler und Künstlerinnen zu entdecken."
+msgstr "Funkwhale macht es Dir leicht, Deine Lieblingsmusik anzuhören und neue Künstler·innen zu entdecken."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
-msgstr "Funkwhale ist kostenlos und ermöglicht eine komplette Steuerung deiner Musik."
+msgstr "Funkwhale ist kostenlos und gibt dir die Kontrolle über deine Musik."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale kümmert sich um deine Musik"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "Allgemeine Tastenkombinationen"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Eine neue Einladung bekommen"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Bring mich zur Mediathek"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "Dank <a href=\"https://musicbrainz.org\" target=\"_blank\">MusicBrainz</a> kannst du deine Musik mit hochwertigen Metadaten verschlagworten"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Loslegen"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Hilfe bekommen"
+
 #: front/src/components/Footer.vue:37
+#, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
-msgstr "Hilfe erhalten"
+msgstr "Hilfe bekommen"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Los!"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Zurück zur Startseite"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "verborgene Künstler·innen"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
-msgstr "Den Konto- bzw. Domaininhalt allen außer Abonnenten verstecken."
+msgstr "Den Konto- bzw. Domaininhalt vor allen außer Abonnenten verbergen."
+
+#: front/src/components/moderation/FilterModal.vue:40
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Inhalte verbergen"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr "Inhalte dieses Künsters verbergen"
+
+#: front/src/components/audio/Player.vue:615
+#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr "Inhalte dieses Künsters verbergen"
 
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Start"
 
 #: front/src/components/instance/Stats.vue:36
-#, fuzzy
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
-msgstr "Musikstunden"
+msgstr "Stunden Musik"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
-msgstr ""
-"Der Zugriff auf Funkwhale von anderen Apps benötigt ein zusätzliches "
-"Kennwort. Du kannst dieses Kennwort hier erstellen."
+msgstr "Der Zugriff auf Funkwhale von diesen Apps benötigt ein zusätzliches Kennwort. Du kannst dieses Kennwort hier erstellen."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
-msgstr "Wenn die angegebene E-Mail-Adresse mit einem Benutzerkonto verknüpft ist, wirst du in Kürze eine E-Mail mit einer Anleitung zur Rücksetzung deines Passworts bekommen."
+msgstr "Ist die angegebene E-Mail-Adresse mit einem Benutzerkonto verknüpft, wirst du in Kürze eine E-Mail mit einer Anleitung zum Rücksetzen deines Passworts bekommen."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Importsdatum"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importiere Musik aus mehreren Plattformen, wie YouTube oder SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Importstatus"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Importreferenz"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Importstatus"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+#, fuzzy
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "Importstatus"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importiert"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Importsdatum"
+#: front/src/components/federation/FetchButton.vue:47
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr "Es lässt sich keine Verbindung zur angegebenen Adresse herstellen"
+
+#: front/src/components/moderation/FilterModal.vue:26
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Kürzlich hinzugefügt"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "In den Favoriten"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr "In den Favoriten- oder Abspiellisten anderer Nutzer"
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Inaktiv"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "Lautstärke erhöhen"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Gebe die E-Mail-Adresse ein, die zu deinem Konto verknüpft ist"
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
-msgstr[0] "Aus der Wiedergabeliste hinzufügen (%{ count } Track)"
-msgstr[1] "Aus der Wiedergabeliste hinzufügen (%{ count } Tracks)"
+msgstr[0] "Aus der Warteschlange hinzufügen (%{ count } Track)"
+msgstr[1] "Aus der Warteschlange hinzufügen (%{ count } Tracks)"
+
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Instanzdaten"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Instanzdaten"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
-msgstr "Infos über diese Instanz"
+msgstr "Informationen über diese Instanz"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Radios der Instanz"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Instanzeinstellungen"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Instanzdaten"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr "Das Dateiformat ist ungültig. Stelle bitte sicher, dass du eine Audio-Datei hochladen möchtest. Die folgenden Dateiformate sind unterstützt: %{ extensions }"
+
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
-"Das Dateiformat ist ungültig. Stelle bitte sicher, dass du eine Audio-Datei "
-"hochladen möchtest. Die folgenden Dateiformaten sind unterstützt: %{ "
-"extensions }"
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
-msgstr "Einladungskode"
-
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Einladungskode (ggf.)"
+msgstr "Einladungscode"
 
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Einladungen"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Bugtracker"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr "Es lässt sich keine Verbindung zur angegebenen Adresse herstellen"
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
-msgstr "Behalte einen Ãœberblick auf deine Lieblingsmusik"
+msgstr "Behalte einen Überblick über deine Lieblingsmusik"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr "Tastenkombinationen"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Bekannte Konten"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Bekannte Mediatheken"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Letzte Aktivität"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "Letzte Überprüfung"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Letzte Bearbeitung"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "Zuletzt gesehen"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Zuletzt gesehen am"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Letzte Aktualisierung:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Starten"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Mehr über diese Instanz erfahren"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
-msgstr "Leerlassen für einen beliebigen Kode"
+msgstr "Leerlassen für einen zufälligen Code"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
-msgstr "Leerlassen für einen reaktionsfähiges Grafikobjekt"
+msgstr "Leerlassen für ein reaktionsfähiges Widget"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Mediatheken"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Mediatheken"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Mediathek aktualisiert"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
-msgstr "Mediatheken helfen dir deine Musiksammlungen zu verwalten und zu teilen. Du kannst deine eigene Musiksammlung zu Funkwhale hochladen und mit deinen Freunden oder deiner Familie teilen."
+msgstr "Bibliotheken helfen Dir deine Musiksammlungen zu organisieren und teilen. Du kannst deine eigene Musiksammlung zu Funkwhale hochladen und mit deinen Freunden und deiner Familie teilen."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Mediathek"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Mediathek erstellt"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Mediathek aktualisiert"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Mediathek gelöscht"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
-msgstr "Dateien aus der Mediathek"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
+msgstr "Mediathek-Dateien"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Mediathek aktualisiert"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "Lizenz"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+#, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Abonnenten werden geladen…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Abonnenten werden geladen…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Die Mediatheken werden geladen…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Die Mediathekdaten werden geladen…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Die Benachrichtigungen werden geladen…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
-msgstr "Laden der entfernten Mediatheken…"
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "Die Fernmediatheken werden geladen…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Die Nutzungsdaten werden geladen…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Deine Favoriten werden geladen…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+#, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Lokales Konto"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
-msgstr "Einloggen"
+msgstr "Anmelden"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
-msgstr "Logge dich bei deinem Funkwhale-Konto ein"
+msgstr "Melde Dich bei Deinem Funkwhale-Konto an"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
-msgstr "Ausloggen"
+msgstr "Abmelden"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
-msgstr "Als %{ username } angemeldet"
+msgstr "Angemeldet als %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
-msgstr "Einloggen"
+msgstr "Anmelden"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
-msgstr "Kontostatus"
+msgstr "Anmeldestatus"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
-msgstr "Ausloggen"
+msgstr "Abmelden"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
-msgstr ""
-"Es sieht aus, als hättest du noch keine Mediathek, höchste Zeit eine "
-"anzulegen."
+msgstr "Es sieht aus, als hättest du noch keine Mediathek, höchste Zeit eine anzulegen."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
-msgstr "Wiederholung deaktiviert. Schalte die Wiederholung des aktuellen Tracks beim Klicken."
+msgstr "Wiederholung deaktiviert. Klicke um den aktuellen Track zu wiederholen."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
-msgstr "Wiederholung des aktuellen Tracks. Wiederhole die ganze Wiedergabeliste beim Klicken."
+msgstr "Wiederholung des aktuellen Titels. Klicken um die ganze Warteschlange zu wiederholen."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
-msgstr "Wiederholung auf die ganze Wiedergabeliste. Deaktiviere die Wiederholung beim Klicken."
+msgstr "Wiederholung der kompletten Warteschlange. Deaktiviere die Wiederholung durch Klicken."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Liedtext"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "Hauptmenü"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Mediathek verwalten"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
-msgstr "Playlists verwalten"
+msgstr "Wiedergabelisten verwalten"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Nutzende verwalten"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
-msgstr "Verwalte deine Playlists"
+msgstr "Verwalte deine Wiedergabelisten"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
-msgstr "Als gelesen markieren"
+msgstr "Alles als gelesen markieren"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Als gelesen markieren"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Als ungelesen markieren"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
-msgstr "Audio-Player"
+msgstr "Medienspieler"
+
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Mitglied seit %{ date }"
 
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "Mobile und desktopbasierte Anwendungen"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+#, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Moderation"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
-"Moderationsregeln lassen dich bestimmen, wie deine Instanz mit einem "
-"bestimmten Domain oder Konto interagiert."
+msgstr "Moderationsregeln lassen Dich festlegen, wie Deine Instanz mit einer bestimmten Domain oder einem bestimmten Konto interagiert."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Änderungsdatum"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Änderungsdatum"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Musik"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Stummschalten"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Aktivität stummschalten"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Benachrichtigungen stummschalten"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Mein Konto"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
-msgstr "Meine super Beschreibung"
+msgstr "Meine klasse Beschreibung"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Meine fantastische Mediathek"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
-msgstr "Meine super Playlist"
+msgstr "Meine super Wiedergabeliste"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Mein super Radio"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Meine Mediatheken"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "k.A."
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Name"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Name"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Name"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Neues Kennwort"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Neue Tracks werden hier automatisch hinzugefügt."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr "Neuer Wert"
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Nächster Track"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Nein"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Keine Erweiterungen, keine Plugins: du brauchst nur eine online Mediathek"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
-msgstr "Keine passendes Album gefunden"
+msgstr "Kein passendes Album gefunden"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
-msgstr "Kein passende Künstler oder Künstlerin gefunden"
+msgstr "Keinen passenden Künstler oder Künstlerin gefunden"
+
+#: front/src/components/library/TrackDetail.vue:14
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
+msgstr "Kein Liedtext für diesen Titel verfügbar"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
-msgstr "Kein verfügbarer Songtext für diesen Track."
+#: front/src/components/library/TrackDetail.vue:25
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Keine Lizenzdaten für diesen Titel verfügbar"
 
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Keine passende Mediathek gefunden."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
-msgstr "Noch keine Benachrichtigungen."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr "Keine Benachrichtigungen zum Anzeigen."
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr "Nichts gefunden."
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Niemand außer mir"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Niemand folgt dieser Mediathek"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Nicht verwendet"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Benachrichtigungen"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Benachrichtigungen"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Offizielle Webseite"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Altes Kennwort"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr "Alter Wert"
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Frei"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Moderationsregel ändern"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Profil öffnen"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Auf MusicBrainz ansehen"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "Profil öffnen"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Profil öffnen"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Webseite öffnen"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "Oder die Moderationsregel anpassen"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Sortierung"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
-msgstr "Sortierung"
+msgstr "Reihenfolge"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
-msgstr "Reihenfolge"
+msgstr "Sortierreihenfolge"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Besitzer"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Seite nicht gefunden"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Seite nicht gefunden!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr "Seitennummerierung"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Kennwort"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Kennwort aktualisiert"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Kennwort erfolgreich aktualisiert"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
-msgstr "Track pausen"
+msgstr "Titel pausieren"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
-msgstr "Track pausen bzw. wiedergeben"
+msgstr "Titel pausieren bzw. wiedergeben"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "Pausiert"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "Ausstehend"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
-msgstr "Steht auf Bestätigung aus"
+msgstr "Bestätigung steht aus"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Ausstehende Dateien"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Ausstehende Abonnieren-Anfrage"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Ausstehende Dateien"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Ausstehende Dateien"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Permissions"
 msgstr "Berechtigungen"
 
-#: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
-msgid "Play"
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Permissions"
+msgstr "Berechtigungen"
+
+#: front/src/components/audio/PlayButton.vue:9
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Play"
 msgstr "Abspielen"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Alles abspielen"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Alle Alben abspielen"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Danach abspielen"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Nächster Track abspielen"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Jetzt abspielen"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Vorheriger Track abspielen"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr "Spiele ähnliche Stücke"
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Diesen Track abspielen"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Abspielen"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Abspielen..."
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
-msgstr "Playlist"
+msgstr "Wiedergabeliste"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
-msgstr[0] "Playlist mit %{ count } Track, von %{ username }"
-msgstr[1] "Playlist mit %{ count } Tracks, von %{ username }"
+msgstr[0] "Wiedergabeliste mit %{ count } Track, von %{ username }"
+msgstr[1] "Wiedergabeliste mit %{ count } Tracks, von %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
-msgstr "Playlist erstellt"
+msgstr "Wiedergabeliste erstellt"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
-msgstr "Playlisteditor"
+msgstr "Wiedergabelisteneditor"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
-msgstr "Playlistname"
+msgstr "Name der Wiedergabeliste"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
-msgstr "Playlist aktualisiert"
+msgstr "Wiedergabeliste aktualisiert"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
-msgstr "Sichtbarkeit der Playlist"
+msgstr "Sichtbarkeit der Wiedergabeliste"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Playlists"
-msgstr "Playlists"
+msgstr "Wiedergabelisten"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Playlists"
+msgstr "Wiedergabelisten"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
-msgstr "Playlists? Haben wir auch!"
+msgstr "Wiedergabelisten? Haben wir auch!"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
-msgstr "Prüfe bitte, dass dein Kennwort richtig ist"
+msgstr "Prüfe bitte genau, ob dein Kennwort stimmt"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
-msgstr "Bitte prüfe, dass dein Benutzername und dein Kennwort miteinander stimmen"
+msgstr "Bitte prüfe genau, ob deine Benutzernamen- und Kennwortkombination stimmen"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
-msgstr "PNG, GIF oder JPG. Max. 2 Mb. Das Bild wird ggf. auf 400x400 px verkleinert."
+msgstr "PNG, GIF oder JPG. Max. 2 MB. Das Bild wird ggf. auf 400x400 Bildpunkte verkleinert."
+
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Seitennummerierung"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
-"Die Benachrichtigungen von diesem Konto bzw. Domain werden an allen "
-"gesperrt, außer Abonnenten."
+msgstr "Verhindert, dass Konto oder Domain Benachrichtigungen auslösen. Ausnahme sind Abonnenten."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "Vorschau"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Vorheriger Track"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
-msgstr "Fehler beim Scannen"
+msgstr "Fehler beim Durchsuchen"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Fortfahren"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
-msgstr "Jetzt einloggen"
+msgstr "Weiter zum Anmelden"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "In Bearbeitung"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Profil öffnen"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1909,1102 +3253,1958 @@ msgstr "In Bearbeitung"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
-msgstr "Säubern"
+msgstr "Entfernen"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
-msgstr "Fehlerhafte Dateien entfernen?"
+msgstr "Fehlerhafte Dateien löschen?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
-msgstr "Ausstehende Dateien löschen?"
+msgstr "Ausstehende Dateien entfernen?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
-msgstr "Übersprungene Dateien löschen?"
+msgstr "Ãœbersprungene Dateien entfernen?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
-msgstr "Wiedergabeliste"
+msgstr "Warteschlange"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
-msgstr "Wiedergabeliste gemischt!"
+msgstr "Warteschlange gemischt!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Radioeditor"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Radio erstellt"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Radioname"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Radio aktualisiert"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radios"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radios"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr "Begründung"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr "Empfangene Abonnements"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "Empfangene Nachrichten"
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Kürzlich hinzugefügt"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
-msgstr "Neulich hinzugefügt"
+msgstr "Kürzlich hinzugefügt"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
-msgstr "Neulich zu den Favoriten hinzugefügt"
+msgstr "Kürzlich zu den Favoriten hinzugefügt"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
-msgstr "Neulich angehört"
+msgstr "Kürzlich angehört"
+
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Aktualisieren"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Aktualisieren"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr "Knoteninformationen aktualisieren"
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Knoteninformationen aktualisieren"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "Tabelleninhalt aktualisieren"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Angemeldet seit %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
-msgstr ""
-"Die Registrierung neuer Nutzenden ist geschlossen. Die Registrierung erfolgt "
-"nur mit einem Einladungscode."
+msgstr "Die Anmeldung auf dieser Instanz ist geschlossen. Du brauchst einen Einladungskode, um dich anmelden zu können."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
-msgstr "Standardkonto"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
+msgstr "herkömmlicher Benutzer"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
-msgstr "Ablehnen"
+msgstr "Abweisen"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
-msgstr "Media abweisen"
+msgstr "Medien abweisen"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
-msgstr "Abgelehnt"
+msgstr "Abgewiesen"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Import erneut starten"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Zuletzt gesehen am"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Fernmediatheken"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
-msgstr ""
-"Fernmediatheken gehören anderen Nutzenden im Netzwerk. Du kannst auf sie "
-"zugreifen solange sie öffentlich sind oder dir Zugang gewährt wurde."
+msgstr "Entfernte Mediatheken sind im Besitz anderer Nutzer des Netzwerks. Du kannst darauf zugreifen, wenn diese öffentlich sind, oder du die Erlaubnis hast."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
-msgstr "Löschen"
+msgstr "Entfernen"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Profilbild löschen"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Profilbild löschen"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Aus den Favoriten entfernen"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
-"Die importierten Tracks, die noch nicht vom Server verarbeitet wurden, "
-"werden vollständig gelöscht. Du erhältst den entsprechenden Speicherplatz "
-"zurück."
+msgstr "Die importierten Titel, die noch nicht vom Server verarbeitet wurden, werden vollständig entfernt. Du erhältst den entsprechenden Speicherplatz zurück."
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
-"Die hochgeladenen Dateien, die beim Import übersprungen wurden, werden "
-"vollständig gelöscht. Du erhältst den entsprechenden Speicherplatz zurück."
+msgstr "Die hochgeladenen Titel, die beim Import übersprungen wurden, werden vollständig entfernt. Du erhältst den entsprechenden Speicherplatz zurück."
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr ""
-"Die hochgeladenen Dateien, die vom Server nicht verarbeitet wurden, werden "
-"vollständig gelöscht. Du erhältst den entsprechenden Speicherplatz zurück."
+msgstr "Die hochgeladenen Titel, die vom Server nicht verarbeitet wurden, werden vollständig entfernt. Du erhältst den entsprechenden Speicherplatz zurück."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Neues Kennwort beantragen"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Neues Subsonic-API-Kennwort beantragen?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Kennwort beantragen"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Kennwort zurücksetzen"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Import erneut starten"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Ergebnisse pro Seite"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr "Begrenze auf unbestätigte Änderungen"
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
-msgstr "Zurück zur Anmeldeseite"
+msgstr "Zurück zur Anmeldung"
+
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Dateien ansehen"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "Regel"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Speichern"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Scan gestartet"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Jetzt scannen"
 
-#: front/src/views/content/remote/Card.vue:166
-msgid "Scan skipped (previous scan is too recent)"
-msgstr "Scan übersprungen (letzter Scan ist zu jung)"
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Aufsteigend"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "Scan steht aus"
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
+msgid "Scan skipped (previous scan is too recent)"
+msgstr "Scan ausgelassen (der letzte Scan fand kurz zuvor statt)"
 
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Scan abgeschlossen"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Scan mit Fehlern abgeschlossen"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Scan läuft… (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Suchen"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Eine Fernmediathek suchen"
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Nach Titel, Künstler·innen oder Domain suchen…"
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Suche nach Domain, Benutzernamen, Biografie…"
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Suche nach Domain, Benutzernamen, Biografie…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Suche nach Domain, Benutzernamen, Biografie…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Nach Titel, Künstler und Album suchen…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Nach Titel, Künstler und Album suchen…"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
-msgstr "Domain, Benutzernamen, Biografie suchen…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Suche nach Domain, Benutzernamen, Biografie…"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
-msgstr "Namen suchen…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Suchen nach Name…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
-msgstr "Titel, Künstler, Album suchen…"
-
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "Titel, Künstler, Künstlerin oder Domain suchen…"
+msgstr "Nach Titel, Künstler und Album suchen…"
 
 #: front/src/components/manage/users/InvitationsTable.vue:153
+#, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Benutzernamen, E-Mail-Adresse, Kode suchen…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Benutzernamen, E-Mail-Adresse, Namen suchen…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
-msgstr "Künstler, Künstlerinnen, Alben, Tracks suchen…"
+msgstr "Nach Künstler·innen, Alben und Titeln suchen…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Musik suchen"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Auf lyrics.wikia.com suchen"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Auf Wikipedia suchen"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
-msgstr "Nebenmenü"
+msgstr "Untermenü"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Abschnitte"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Filter auswählen"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "1 Element auswählen"
 msgstr[1] "Alle %{ total } Elemente auswählen"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Nur die aktuelle Seite auswählen"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Einstellungen"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Einstellungen aktualisiert"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Einstellungen erfolgreich aktualisiert."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Freigabe-Link"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"Teile diesen Link mit anderen Nutzenden, damit diese Zugriff auf deine "
-"Mediathek anfordern können."
+msgstr "Teile diesen Link mit anderen Nutzenden, damit diese Zugriff auf deine Mediathek anfordern können."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Freigabe-Link"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "%{ count } weiteren Track zeigen"
 msgstr[1] "%{ count } weitere Tracks zeigen"
 
 #: front/src/components/audio/artist/Card.vue:30
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "1 weiteres Album zeigen"
 msgstr[1] "%{ count } weitere Alben zeigen"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr "Zeige alle Änderungen"
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "Verfügbare Tastenkombinationen zeigen"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Gelesene Benachrichtigungen zeigen"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Passwort verstecken bzw. zeigen"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Ergebnisse %{ start } bis %{ end } von %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
-msgstr "Wiedergabeliste mischen"
+msgstr "Warteschlange mischen"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
-msgstr "Wiedergabeliste mischen"
+msgstr "Warteschlange mischen"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Anmeldung"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Anmeldung"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Anmeldedatum"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
-msgstr "Aktivität stummschalten"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "Benachrichtigungen stummschalten"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+#, fuzzy
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Größe"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Größe"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
-msgstr "Ausgelassen"
+msgstr "Ãœbersprungen"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
-msgstr "Ausgelassene Dateien"
+msgstr "Ãœbersprungene Dateien"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "Software"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Entschuldigung, die aufgerufene Seite existiert nicht:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Quellcode"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Teammember"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Starten"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Radio einschalten"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Statistik"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
-"Statistiken betrachten ausschließlich die Aktivität und den Inhalt, die von "
-"deiner Instanz bekannt sind, und stellen nicht die gesamte Aktivität dieses "
-"Kontos dar"
+msgstr "Statistiken betrachten ausschließlich die Aktivität und den Inhalt, die von deiner Instanz bekannt sind, und stellen nicht die gesamte Aktivität dieses Kontos dar"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
-"Statistiken betrachten ausschließlich die Aktivität und den Inhalt, die von "
-"deiner Instanz bekannt sind, und stellen nicht die gesamte Aktivität dieses "
-"Domains dar"
+msgstr "Statistiken betrachten ausschließlich die Aktivität und den Inhalt, die von deiner Instanz bekannt sind, und stellen nicht die gesamte Aktivität dieses Domains dar"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "Statistiken betrachten ausschließlich die Aktivität und den Inhalt, die von deiner Instanz bekannt sind, und stellen nicht die gesamte Aktivität dieses Kontos dar"
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Status"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Status"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Status"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Status"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Status"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Abbrechen"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Status"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
-msgstr "Radio stoppen"
+msgstr "Radio ausschalten"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Abschicken"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr "Senden und anwenden"
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Subsonic-API-Kennwort"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Dieser Track kann nicht geladen werden"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Dieser Track kann nicht geladen werden"
+
+#: front/src/components/library/TrackEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Dieser Track kann nicht geladen werden"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Empfehlungen"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Zusammenfassung"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr "Zusammenfassung (optional)"
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "Hilfe-Forum"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr "Unterstützte Dateierweiterungen: %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Synchronisierung der Änderungen auf dem Server…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Text in die Zwischenablage kopiert!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
-msgstr "So einfach ist es: wir liebten Grooveshark, doch wollen wir noch besser machen."
+msgstr "So einfach ist es: wir liebten Grooveshark und wollen noch etwas viel besseres aufbauen."
+
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
 
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
-msgstr "Das Funkwhale-Logo wurde mit Lieb von Francis Gading erbracht."
+msgstr "Das Funkwhale-Logo wurde gestaltet und freundlicherweise zur Verfügung gestellt von Francis Gading."
+
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr "Die angegebene Adresse ist kein Funkwhale-Server"
 
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr "Die Mediathek und all ihre Titel werden gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden."
+
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
 msgstr ""
-"Die Mediathek und all ihre Dateien werden gelöscht. Dieser Vorgang ist "
-"unwiderruflich."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
-msgstr "Die Musikdateien, die du hochlädst sind richtig verschlagwortet:"
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
+msgstr "Die Musikdateien, die du hochlädst, sind richtig verschlagwortet."
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
-msgstr "Der nächste Track wird in wenigen Sekunden automatisch wiedergegeben…"
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "Der nächste Titel wird automatisch in wenigen Sekunden wiedergegeben…"
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
-msgstr "Die Plattform ist kostenlos und Open-Source, du kannst sie herunterladen, installieren und anpassen ohne Sorge"
+msgstr "Die Plattform ist kostenlos und Open-Source, du kannst sie installieren und anpassen ohne Beschränkung"
+
+#: front/src/components/playlists/Form.vue:14
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Die Wiedergabeliste konnte nicht erstellt werden"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Der Vorschlag wird entgültig gelöscht. Das kann nicht rückgängig gemacht werden."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr "Der Server läuft wahrscheinlich nicht"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "Die Subsonic-API ist auf dieser Instanz nicht verfügbar."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr "Der Vorschlag wird entgültig gelöscht. Das kann nicht rückgängig gemacht werden."
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Dieser Titel kann nicht zu einer Wiedergabeliste hinzugefügt werden"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr "Der Titel kann nicht geladen werden"
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Der Vorschlag wird entgültig gelöscht. Das kann nicht rückgängig gemacht werden."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Die hochgeladenen Musikdateien sind im OGG-, Flac- oder MP3-Format"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
-msgstr "Es gibt zahlreiche Wege, neue Inhalte abzurufen und zu veröffentlichen."
+msgstr "Es gibt zahlreiche Wege, neue Inhalte abzurufen und hier zu veröffentlichen."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "Dieser Vorgang ist unwiderruflich."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Dieses Album ist in den folgenden Mediatheken enthalten:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
-msgstr "Dieser Künstler ist in den folgenden Mediatheken enthalten:"
+msgstr "Dieser Künstler kommt in den folgenden Mediatheken vor:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
-msgstr "Diese Domain wird von besonderen Moderationsregeln verwaltet"
+msgstr "Für diese Domain gelten besondere Moderationsregeln"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr "Diese Instanz bietet den Nutzenden bis zu %{quota} Speicherplatz."
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "Das bist du!"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
-msgstr ""
-"Diese Mediathek enthält meine persönliche Musik. Ich hoffe sie gefällt euch."
+msgstr "Diese Mediathek enthält meine persönliche Musik. Ich hoffe sie gefällt euch."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
-"Diese Mediathek ist privat. Dein Zugriff auf sie braucht die Zusage ihrer "
-"besitzenden Person"
+msgstr "Diese Mediathek ist privat. Dein Zugriff auf sie benötigt die Genehmigung des Eigentümers / der Eigentümerin"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
-msgstr "Diese Mediathek ist öffentlich. Du kannst dem Inhalt frei zugreifen"
+msgstr "Diese Mediathek ist öffentlich. Du kannst auf den Inhalt ohne Einschränkungen zugreifen"
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
+msgstr "Durch diese Aktion können mehrere Elemente betroffen sein. Überlege, ob du es wirklich so willst."
+
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
 msgstr ""
-"Durch diese Aktion können mehrere Elemente betroffen werden, prüfe bitte "
-"nach, das du es wirklich willst."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Diese Referenz wird verwendet, um importierte Dateien zu gruppieren."
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Bei der Verarbeitung des Titels ist ein Fehler aufgetreten. Überprüfe bitte, dass er richtig verschlagwortet ist"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "Der Titel wurde hochgeladen, er ist aber noch nicht vom Server verarbeitet worden"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "Eine deiner Mediatheken enthält bereits diesen Titel"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
-msgstr "Dieser Track ist in keiner deiner verfügbaren Mediatheken enthalten"
+msgstr "Dieser Titel ist in keiner deiner verfügbaren Mediatheken enthalten"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Dieser Track ist in den folgenden Mediatheken enthalten:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
-msgstr "Die Playlist wird dauerhaft gelöscht und kann nicht zurückerstellt werden."
+msgstr "Die Wiedergabeliste wird dauerhaft gelöscht und kann nicht zurückerstellt werden."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
-msgstr "Das Radio wird dauerhaft gelöscht und kann nicht zurückerstellt werden."
+msgstr "Das Radio wird dauerhaft gelöscht und kann nicht wiederhergestellt werden."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Der Zugriff zur Subsonic-API von diesem Konto wird deaktiviert."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr ""
-"Deine lokalen Daten werden gelöscht, und du wirst abgemeldet. Möchtest du "
-"fortfahren?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
-msgstr "Du wirst von den bestehenden Geräten abgemeldet, die dieses Passwort nutzen."
+msgstr "Du wirst von den vorhandenen Geräten abgemeldet, die dieses Passwort nutzen."
+
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Die Wiedergabeliste wird dauerhaft gelöscht und kann nicht zurückerstellt werden."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
-msgstr "Alle Tracks dieses Playlists werden dauerhauft gelöscht und können nicht zurückerstellt werden."
+msgstr "Damit werden alle Titel von der Playlist gelöscht. Das kann nicht rückgängig gemacht werden."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Title"
 msgstr "Titel"
 
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Titel"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr "Titel"
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr "Wähle bitte nun die Funkhwhale-Instanz aus, zu der Du dich verbinden möchtest. Gib die Adresse direkt an, oder wähle einen der Vorschläge aus."
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
-msgstr "Wiedergabelistewiederholung umschalten"
+msgstr "Warteschlangenwiederholung umschalten"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "Gesamtvolumen"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
-msgstr "Gesamtvolumen dieser Mediathek"
+msgstr "Gesamtgröße der Dateien in dieser Mediathek"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Gesamtanzahl der Nutzenden"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Track"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "Eine deiner Mediatheken enthält bereits diesen Track"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Track"
 
-#: front/src/components/library/Track.vue:85
-msgid "Track information"
-msgstr "Trackinformation"
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Passender Track"
+#: front/src/views/admin/library/TrackDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Trackname"
 
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
+msgid "Track information"
+msgstr "Titelinformation"
+
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Trackname"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr ""
-"Der Track wurde hochgeladen, er ist aber noch nicht vom Server verarbeitet "
-"worden"
-
-#: front/src/components/instance/Stats.vue:54
-msgid "tracks"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
 msgstr "Tracks"
 
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/instance/Stats.vue:54
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Tracks"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
-msgstr "Tracks von diesem Künstler oder Künstlerin"
+msgstr "Titel von diesem Künstler oder Künstlerin"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Tracks in den Favoriten"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "Angehörte Tracks"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Titel Auswahl Filter"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Typ"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Typ"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr "Von einer Moderationsregel verwaltet"
+msgstr "Unterliegt einer Moderationsregel"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Abonnement beenden"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
-msgstr "Das Abonnement dieser Mediathek beenden?"
+msgstr "Das Abonnement an dieser Mediathek beenden?"
+
+#: front/src/components/About.vue:17
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
+msgstr "Leider haben die Eintümer dieser Instanz diese Seite noch nicht fertig gestellt."
+
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
 msgstr ""
-"Leider wurde diese Seite von den Verwaltenden dieser Instanz noch nicht "
-"ausgefüllt."
 
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
-msgstr "Unbegrenzte Musik"
+msgstr "Unbegrenzt Musik anhören"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Stummschaltung aufheben"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Aktualisieren"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Wiedergabeliste aktualisieren"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Profilbild aktualisieren"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Mediathek aktualisieren"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "Moderationsregel aktualisieren"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
-msgstr "Playlist aktualisiert"
+msgstr "Wiedergabeliste aktualisieren"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Einstellungen aktualisieren"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Dein Kennwort aktualisieren"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Hochladen"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Neues Profilbild hochladen"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Audio-Inhalte hochladen"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Hochladedatum"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Hochladedatum"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "Hochladen abgelehnt. Bitte prüfe, dass die Datei nicht zu groß ist, und dass du noch über genügenden Speicherplatz verfügst"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
-"Hochladen abgelehnt. Bitte prüfe, dass die Datei nicht zu groß ist, und dass "
-"du noch über genügenden Speicherplatz verfügst"
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr ""
-"Lade Musikdatei (MP3, OGG, Flac, usw.) von deiner eigenen Mediathek direkt "
-"von deinem Browser hoch, und höre sie hier an."
+msgstr "Lade Musikdatei (MP3, OGG, Flac, usw.) von deiner eigenen Mediathek direkt im Browser hoch, und höre sie hier an."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Neue Tracks hochladen"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Speichervolumen"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Hochladezeit abgelaufen. Bitte versuche es erneut"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Hochgeladen"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Hochladen läuft"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Hochladen läuft…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Hochladen"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Hochladen"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "Hochladen"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Eine andere Instanz benutzen"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
-msgstr "Mit diesem Formular kannst du ein neues Kennwort beantragen. Wir schicken dir eine E-Mail an die angegebene Adresse mit den Anleitungen."
+msgstr "Mit diesem Formular kannst du ein neues Kennwort beantragen. In Kürze erhältst du von uns eine Nachricht an die angegebene E-Mail-Adresse mit den Anleitungen."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
-"Mit dieser Einstellung kannst du die Moderationsregel temporär umschalten, "
-"ohne sie zu löschen."
+msgstr "Mit dieser Einstellung kannst du die Moderationsregel temporär umschalten, ohne sie zu löschen."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Verwendet"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
-msgstr "Nutzende"
+msgstr "Benutzer"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Aktivität der Nutzenden"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
-msgstr "Mediatheken der nutzenden Person"
+msgstr "Mediatheken der Nutzenden"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
-msgstr "Radios der Nutzende"
+msgstr "Radios der Nutzenden"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Benutzername"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Benutzername oder E-Mail-Adresse"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "Nutzende"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Nutzende"
 
 #: front/src/components/Footer.vue:29
+#, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "Funwhale nutzen"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
-msgstr "Version (%{ version })"
+msgstr "Version %{ version }"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Dateien ansehen"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Auf MusicBrainz ansehen"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Sichtbarkeit"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Sichtbarkeit: alle auf dieser Instanz"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Sichbarkeit: alle, auch auf anderen Instanzen"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Sichtbarkeit: niemand außer mir"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Sichtbarkeit"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr "Band %{ number }"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Dieser Track kann nicht zu einer Playlist hinzugefügt werden"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Die Playlist kann nicht erstellt werden"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Dein Konto kann nicht erstellt werden"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "Dieser Track kann nicht geladen werden"
+#: front/src/components/federation/FetchButton.vue:69
+#, fuzzy
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Deine Favoriten werden geladen…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Wir können dich nicht einloggen"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Dein Profilbild kann nicht gespeichert werden"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Deine Einstellungen können nicht gespeichert werden"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Dein Konto kann nicht erstellt werden"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Weder verfolgen wir dich noch stören wir dich mit Werbung"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "Es sind keine Urheberechtsdaten für diesen Track verfügbar"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "Es sind keine Lizenzdaten für diesen Track"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "Zu diesem Zweck wird Picard empfohlen."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
-msgstr "Weil Musik hören sollte leicht sein."
-
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Entschuldigung, die aufgerufene Seite existiert nicht:"
+msgstr "Wir denken, Musik hören sollte möglichst einfach sein."
 
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Willkommen"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Willkommen auf Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Warum Funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "Grafikobjektshöhe"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "Grafikobjektsbreite"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Ja"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Ja, logge mich aus!"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
 msgstr "Du kannst deine Mediathek mit Anderen teilen, auch wenn sie privat ist."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Die Musik wird bald zu deiner Mediathek hochgeladen. Prüfe bitte vorab, dass:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Du bist als %{ username } angemeldet"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr "Die lädst kein urheberrechtlich geschütztes Material in eine öffentliche Mediathek hoch. Wenn doch, missachtest Du das Gesetz"
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
-msgstr "Abonniere dich zu Mediatheken und greif neuer Musik zu. Öffentliche Mediatheke können sofort abonniert werden; das Abonnieren einer privaten Mediathek benötigt die Bestätigung des Besitzers."
+msgstr "Folge Mediatheken von anderen Hörern, um auf neue Musik zu stoßen. Öffentlichen Mediatheken kann sofort gefolgt werden, wohingegen geschlossene Mediatheken die Erlaubnis von ihrem Eigentümer / von ihrer Eigentümerin bedürfen."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
-msgstr "Du kannst Freunde und Familie auf deiner Instanz einladen, sodass sie deine Musik genießen können"
+msgstr "Du kannst Freunde und Deine Familie auf Deine eigene Instanz einladen, sodass sie Deine Musik genießen können"
+
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
 
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Du kannst jetzt den Service unbegrenzt nutzen."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Dank dieser Schnittstelle kannst du dein eigenes Radio aufbauen, das die entsprechenden Tracks abspielt."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
-msgstr "Damit kannst du deine Playlists und Musik offline genießen, zum Beispiel auf deinem Smartphone bzw. Tablett."
+msgstr "Damit kannst du deine Wiedergabelisten und Musik offline genießen, zum Beispiel auf deinem Smartphone bzw. Tablett."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Du hast keine Moderationsregeln in Kraft für dieses Konto."
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Du hast keine Moderationsregeln in Kraft für dieses Konto."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr "Du hast keine Moderationsregeln in Kraft für dieses Konto."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr "Du hast keine Moderationsregeln in Kraft für diese Domain."
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
+msgstr ""
+
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Du hörst gerade ein Radio an"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr "Du kannst Verbindungsproblemen erfahren."
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Zum Fortfahren wähle bitte eine Instanz aus"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Du wirst von dieser Sitzung ausgeloggt und du musst dich mit deinem neuen Kennwort einloggen"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
-msgstr "Du musst das Kennwort auf deine verbundenen Geräte anpassen, die dieses Kennwort verwenden."
+msgstr "Du musst dann das Kennwort auf allen Deiner verbundenen Geräte aktualisieren."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Dein Avatar kann nicht gespeichert werden"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Deine Benachrichtigungen"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr "Dein Avatar kann nicht gespeichert werden"
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr "Die Änderung wurde erfolgreich übertragen."
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Deine Favoriten"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
-msgstr "Deine Musik, deine Weise"
+msgstr "Deine Musik, so wie du willst"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Deine Benachrichtigungen"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr "Dein Kennwort kann nicht geändert werden"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Dein Kennwort wurde erfolgreich aktualisiert."
 
+#: front/src/components/auth/Settings.vue:14
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Einstellungen konnten nicht aktualisiert werden"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
-msgstr "Dein Subsonic-Kennwort wird mit einem neuen beliebigen Kennwort ersetzt, und du wirst auf allen aktuellen verbundenen Geräten ausgeloggt, die das alte Kennwort nutzen"
+msgstr "Dein Subsonic-Kennwort wird mit einem neuen zufälligen Kennwort ersetzt. Du wirst auf allen aktuell verbundenen Geräten ausgeloggt, die noch das alte Kennwort nutzen"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Seitennummerierung"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Urheberrecht"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Album mit %{ count } Track, von %{ artist }"
+msgstr[1] "Album mit %{ count } Tracks, von %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "1 Titel wurde zur Warteschlange hinzugefügt"
+msgstr[1] "%{ count } Titel wurden zur Warteschlange hinzugefügt"
diff --git a/front/locales/en_GB/LC_MESSAGES/app.po b/front/locales/en_GB/LC_MESSAGES/app.po
new file mode 100644
index 0000000000000000000000000000000000000000..0300026f43472ca639c7546acb08af968ca335d8
--- /dev/null
+++ b/front/locales/en_GB/LC_MESSAGES/app.po
@@ -0,0 +1,2988 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the front package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: front 0.1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-01-29 10:47+0100\n"
+"PO-Revision-Date: 2019-03-07 12:44+0000\n"
+"Last-Translator: gerry_the_hat <gerd-schumann@web.de>\n"
+"Language-Team: none\n"
+"Language: en_GB\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 3.2.2\n"
+
+#: front/src/components/playlists/PlaylistModal.vue:9
+msgid "\"%{ title }\", by %{ artist }"
+msgstr "\"%{ title }\", by %{ artist }"
+
+#: front/src/components/Sidebar.vue:24
+msgid "(%{ index } of %{ length })"
+msgstr "(%{ index } of %{ length })"
+
+#: front/src/components/Sidebar.vue:22
+msgid "(empty)"
+msgstr "(empty)"
+
+#: front/src/components/common/ActionTable.vue:57
+#: front/src/components/common/ActionTable.vue:66
+msgid "%{ count } on %{ total } selected"
+msgid_plural "%{ count } on %{ total } selected"
+msgstr[0] "%{ count } on %{ total } selected"
+msgstr[1] "%{ count } on %{ total } selected"
+
+#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
+#: front/src/views/content/libraries/Card.vue:39 src/views/content/remote/Card.vue:26
+msgid "%{ count } track"
+msgid_plural "%{ count } tracks"
+msgstr[0] "%{ count } track"
+msgstr[1] "%{ count } tracks"
+
+#: front/src/components/library/Artist.vue:13
+msgid "%{ count } track in %{ albumsCount } albums"
+msgid_plural "%{ count } tracks in %{ albumsCount } albums"
+msgstr[0] "%{ count } track in %{ albumsCount } albums"
+msgstr[1] "%{ count } tracks in %{ albumsCount } albums"
+
+#: front/src/components/library/radios/Builder.vue:80
+msgid "%{ count } track matching combined filters"
+msgid_plural "%{ count } tracks matching combined filters"
+msgstr[0] "%{ count } track matching combined filters"
+msgstr[1] "%{ count } tracks matching combined filters"
+
+#: front/src/components/audio/PlayButton.vue:180
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } track was added to your queue"
+msgstr[1] "%{ count } tracks were added to your queue"
+
+#: front/src/components/playlists/Card.vue:18
+msgid "%{ count} track"
+msgid_plural "%{ count } tracks"
+msgstr[0] "%{ count} track"
+msgstr[1] "%{ count } tracks"
+
+#: front/src/views/content/libraries/Quota.vue:11
+msgid "%{ current } used on %{ max } allowed"
+msgstr "%{ current } used on %{ max } allowed"
+
+#: front/src/components/common/Duration.vue:2
+msgid "%{ hours } h %{ minutes } min"
+msgstr "%{ hours } h %{ minutes } min"
+
+#: front/src/components/common/Duration.vue:5
+msgid "%{ minutes } min"
+msgstr "%{ minutes } min"
+
+#: front/src/components/notifications/NotificationRow.vue:40
+msgid "%{ username } accepted your follow on library \"%{ library }\""
+msgstr "%{ username } accepted your follow on library \"%{ library }\""
+
+#: front/src/components/notifications/NotificationRow.vue:39
+msgid "%{ username } followed your library \"%{ library }\""
+msgstr "%{ username } followed your library \"%{ library }\""
+
+#: front/src/components/notifications/NotificationRow.vue:41
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } wants to follow your library \"%{ library }\""
+
+#: front/src/components/auth/Profile.vue:46
+msgid "%{ username }'s profile"
+msgstr "%{ username }'s profile"
+
+#: front/src/components/audio/artist/Card.vue:41
+msgid "1 album"
+msgid_plural "%{ count } albums"
+msgstr[0] "1 album"
+msgstr[1] "%{ count } albums"
+
+#: front/src/components/favorites/List.vue:10
+msgid "1 favorite"
+msgid_plural "%{ count } favorites"
+msgstr[0] "1 favourite"
+msgstr[1] "%{ count } favourites"
+
+#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/library/FileUpload.vue:227
+msgid "A network error occured while uploading this file"
+msgstr "A network error occurred while uploading this file"
+
+#: front/src/components/About.vue:5
+msgid "About %{ instance }"
+msgstr "About %{ instance }"
+
+#: front/src/components/Footer.vue:6
+msgid "About %{instanceName}"
+msgstr "About %{instanceName}"
+
+#: front/src/components/Footer.vue:45
+msgid "About Funkwhale"
+msgstr "About Funkwhale"
+
+#: front/src/components/Footer.vue:10
+msgid "About page"
+msgstr "About page"
+
+#: front/src/components/About.vue:8 src/components/About.vue:67
+msgid "About this instance"
+msgstr "About this instance"
+
+#: front/src/views/content/libraries/Detail.vue:48
+msgid "Accept"
+msgstr "Accept"
+
+#: front/src/views/content/libraries/Detail.vue:40
+msgid "Accepted"
+msgstr "Accepted"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgid "Access disabled"
+msgstr "Access disabled"
+
+#: front/src/components/Home.vue:106
+msgid "Access your music from a clean interface that focus on what really matters"
+msgstr ""
+"Access your music from a clean interface that focuses on what really matters"
+
+#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:20
+msgid "Accessed date"
+msgstr "Access date"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
+msgid "Account data"
+msgstr "Account data"
+
+#: front/src/components/auth/Settings.vue:5
+msgid "Account settings"
+msgstr "Account settings"
+
+#: front/src/components/auth/Settings.vue:263
+msgid "Account Settings"
+msgstr "Account Settings"
+
+#: front/src/components/manage/users/UsersTable.vue:39
+msgid "Account status"
+msgstr "Account status"
+
+#: front/src/views/auth/PasswordReset.vue:14
+msgid "Account's email"
+msgstr "Account's email"
+
+#: front/src/views/admin/moderation/AccountsList.vue:3
+#: front/src/views/admin/moderation/AccountsList.vue:24
+#: front/src/views/admin/moderation/Base.vue:8
+msgid "Accounts"
+msgstr "Accounts"
+
+#: front/src/views/content/libraries/Detail.vue:29
+msgid "Action"
+msgstr "Action"
+
+#: front/src/components/common/ActionTable.vue:99
+msgid "Action %{ action } was launched successfully on %{ count } element"
+msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
+msgstr[0] "Action %{ action } was launched successfully on %{ count } element"
+msgstr[1] "Action %{ action } was launched successfully on %{ count } elements"
+
+#: front/src/components/common/ActionTable.vue:21
+#: front/src/components/library/radios/Builder.vue:64
+msgid "Actions"
+msgstr "Actions"
+
+#: front/src/components/manage/users/UsersTable.vue:53
+msgid "Active"
+msgstr "Active"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:199
+#: front/src/views/admin/moderation/DomainsDetail.vue:144
+msgid "Activity"
+msgstr "Activity"
+
+#: front/src/components/mixins/Translations.vue:7
+#: front/src/components/mixins/Translations.vue:8
+msgid "Activity visibility"
+msgstr "Activity visibility"
+
+#: front/src/views/admin/moderation/DomainsList.vue:18
+msgid "Add"
+msgstr "Add"
+
+#: front/src/views/admin/moderation/DomainsList.vue:13
+msgid "Add a domain"
+msgstr "Add a domain"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgid "Add a new moderation rule"
+msgstr "Add a new moderation rule"
+
+#: front/src/views/content/Home.vue:35
+msgid "Add and manage content"
+msgstr "Add and manage content"
+
+#: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+msgid "Add content"
+msgstr "Add content"
+
+#: front/src/components/library/radios/Builder.vue:50
+msgid "Add filter"
+msgstr "Add filter"
+
+#: front/src/components/library/radios/Builder.vue:40
+msgid "Add filters to customize your radio"
+msgstr "Add filters to customise your radio"
+
+#: front/src/components/audio/PlayButton.vue:64
+msgid "Add to current queue"
+msgstr "Add to current queue"
+
+#: front/src/components/favorites/TrackFavoriteIcon.vue:4
+#: front/src/components/favorites/TrackFavoriteIcon.vue:28
+msgid "Add to favorites"
+msgstr "Add to favourites"
+
+#: front/src/components/playlists/TrackPlaylistIcon.vue:6
+#: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgid "Add to playlist…"
+msgstr "Add to playlist…"
+
+#: front/src/components/audio/PlayButton.vue:14
+msgid "Add to queue"
+msgstr "Add to queue"
+
+#: front/src/components/playlists/PlaylistModal.vue:116
+msgid "Add to this playlist"
+msgstr "Add to this playlist"
+
+#: front/src/components/playlists/PlaylistModal.vue:54
+msgid "Add track"
+msgstr "Add track"
+
+#: front/src/components/manage/users/UsersTable.vue:69
+msgid "Admin"
+msgstr "Admin"
+
+#: front/src/components/Sidebar.vue:79
+msgid "Administration"
+msgstr "Administration"
+
+#: front/src/components/audio/SearchBar.vue:26 src/components/audio/track/Table.vue:8
+#: front/src/components/library/Album.vue:153
+#: front/src/components/manage/library/FilesTable.vue:39
+#: front/src/components/metadata/Search.vue:134
+#: front/src/views/content/libraries/FilesTable.vue:56
+msgid "Album"
+msgstr "Album"
+
+#: front/src/components/library/Album.vue:183
+msgid "Album containing %{ count } track, by %{ artist }"
+msgid_plural "Album containing %{ count } tracks, by %{ artist }"
+msgstr[0] "Album containing %{ count } track, by %{ artist }"
+msgstr[1] "Album containing %{ count } tracks, by %{ artist }"
+
+#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:25
+msgid "Album name"
+msgstr "Album name"
+
+#: front/src/components/library/Track.vue:27
+msgid "Album page"
+msgstr "Album page"
+
+#: front/src/components/audio/Search.vue:19 src/components/instance/Stats.vue:48
+#: front/src/views/admin/moderation/AccountsDetail.vue:321
+#: front/src/views/admin/moderation/DomainsDetail.vue:257
+msgid "Albums"
+msgstr "Albums"
+
+#: front/src/components/library/Artist.vue:44
+msgid "Albums by this artist"
+msgstr "Albums by this artist"
+
+#: front/src/components/manage/users/InvitationsTable.vue:19
+#: front/src/views/content/libraries/FilesTable.vue:13
+msgid "All"
+msgstr "All"
+
+#: front/src/components/playlists/Editor.vue:13
+msgid "An error occured while saving your changes"
+msgstr "An error occurred while saving your changes"
+
+#: front/src/components/auth/Login.vue:10
+msgid "An unknown error happend, this can mean the server is down or cannot be reached"
+msgstr ""
+"An unknown error happened, this can mean the server is down or cannot be "
+"reached"
+
+#: front/src/components/notifications/NotificationRow.vue:66
+msgid "Approve"
+msgstr "Approve"
+
+#: front/src/components/auth/Logout.vue:5
+msgid "Are you sure you want to log out?"
+msgstr "Are you sure you want to log out?"
+
+#: front/src/components/audio/SearchBar.vue:25 src/components/audio/track/Table.vue:7
+#: front/src/components/library/Artist.vue:137
+#: front/src/components/manage/library/FilesTable.vue:38
+#: front/src/components/metadata/Search.vue:130
+#: front/src/views/content/libraries/FilesTable.vue:55
+msgid "Artist"
+msgstr "Artist"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+msgid "Artist name"
+msgstr "Artist name"
+
+#: front/src/components/library/Album.vue:16 src/components/library/Track.vue:33
+msgid "Artist page"
+msgstr "Artist page"
+
+#: front/src/components/audio/Search.vue:65
+msgid "Artist, album, track…"
+msgstr "Artist, album, track…"
+
+#: front/src/components/audio/Search.vue:10 src/components/instance/Stats.vue:42
+#: front/src/components/library/Artists.vue:119 src/components/library/Library.vue:7
+#: front/src/views/admin/moderation/AccountsDetail.vue:313
+#: front/src/views/admin/moderation/DomainsDetail.vue:249
+msgid "Artists"
+msgstr "Artists"
+
+#: front/src/components/favorites/List.vue:33 src/components/library/Artists.vue:25
+#: front/src/components/library/Radios.vue:44
+#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/manage/moderation/AccountsTable.vue:21
+#: front/src/components/manage/moderation/DomainsTable.vue:19
+#: front/src/components/manage/users/UsersTable.vue:19
+#: front/src/views/content/libraries/FilesTable.vue:31
+#: front/src/views/playlists/List.vue:27
+msgid "Ascending"
+msgstr "Ascending"
+
+#: front/src/views/auth/PasswordReset.vue:28
+msgid "Ask for a password reset"
+msgstr "Ask for a password reset"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgid "Audio content"
+msgstr "Audio content"
+
+#: front/src/components/ShortcutsModal.vue:55
+msgid "Audio player shortcuts"
+msgstr "Audio player shortcuts"
+
+#: front/src/components/playlists/PlaylistModal.vue:26
+msgid "Available playlists"
+msgstr "Available playlists"
+
+#: front/src/components/auth/Settings.vue:34
+msgid "Avatar"
+msgstr "Avatar"
+
+#: front/src/views/auth/PasswordReset.vue:25
+#: front/src/views/auth/PasswordResetConfirm.vue:18
+msgid "Back to login"
+msgstr "Back to login"
+
+#: front/src/components/library/Track.vue:129
+#: front/src/components/manage/library/FilesTable.vue:42
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+msgid "Bitrate"
+msgstr "Bitrate"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:19
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgid "Block everything"
+msgstr "Block everything"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
+msgstr ""
+"Block everything from this account or domain. This will prevent any "
+"interaction with the entity, and purge related content (uploads, libraries, "
+"follows, etc.)"
+
+#: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+msgid "Browse"
+msgstr "Browse"
+
+#: front/src/components/Sidebar.vue:65
+msgid "Browse library"
+msgstr "Browse library"
+
+#: front/src/components/library/Artists.vue:4
+msgid "Browsing artists"
+msgstr "Browsing artists"
+
+#: front/src/views/playlists/List.vue:3
+msgid "Browsing playlists"
+msgstr "Browsing playlists"
+
+#: front/src/components/library/Radios.vue:4
+msgid "Browsing radios"
+msgstr "Browsing radios"
+
+#: front/src/components/library/radios/Builder.vue:5
+msgid "Builder"
+msgstr "Builder"
+
+#: front/src/components/audio/album/Card.vue:13
+msgid "By %{ artist }"
+msgstr "By %{ artist }"
+
+#: front/src/views/content/remote/Card.vue:103
+msgid "By unfollowing this library, you loose access to its content."
+msgstr "By unfollowing this library, you lose access to its content."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgid "Cached size"
+msgstr "Cached size"
+
+#: front/src/components/common/DangerousButton.vue:17
+#: front/src/components/library/Album.vue:52 src/components/library/Track.vue:76
+#: front/src/components/library/radios/Filter.vue:53
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:63
+msgid "Cancel"
+msgstr "Cancel"
+
+#: front/src/components/library/radios/Builder.vue:63
+msgid "Candidates"
+msgstr "Candidates"
+
+#: front/src/components/auth/Settings.vue:75
+msgid "Cannot change your password"
+msgstr "Cannot change your password"
+
+#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:224
+msgid "Cannot upload this file, ensure it is not too big"
+msgstr "Cannot upload this file, ensure it is not too big"
+
+#: front/src/components/Footer.vue:21
+msgid "Change language"
+msgstr "Change language"
+
+#: front/src/components/auth/Settings.vue:67
+msgid "Change my password"
+msgstr "Change my password"
+
+#: front/src/components/auth/Settings.vue:94
+msgid "Change password"
+msgstr "Change password"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:4
+#: front/src/views/auth/PasswordResetConfirm.vue:62
+msgid "Change your password"
+msgstr "Change your password"
+
+#: front/src/components/auth/Settings.vue:95
+msgid "Change your password?"
+msgstr "Change your password?"
+
+#: front/src/components/playlists/Editor.vue:21
+msgid "Changes synced with server"
+msgstr "Changes synced with server"
+
+#: front/src/components/auth/Settings.vue:70
+msgid "Changing your password will also change your Subsonic API password if you have requested one."
+msgstr ""
+"Changing your password will also change your Subsonic API password if you "
+"have requested one."
+
+#: front/src/components/auth/Settings.vue:97
+msgid "Changing your password will have the following consequences"
+msgstr "Changing your password will have the following consequences"
+
+#: front/src/components/Footer.vue:40
+msgid "Chat room"
+msgstr "Chat room"
+
+#: front/src/App.vue:13
+msgid "Choose your instance"
+msgstr "Choose your instance"
+
+#: front/src/components/Home.vue:64
+msgid "Clean library"
+msgstr "Clean library"
+
+#: front/src/components/manage/users/InvitationForm.vue:37
+msgid "Clear"
+msgstr "Clear"
+
+#: front/src/components/playlists/Editor.vue:40
+#: front/src/components/playlists/Editor.vue:45
+msgid "Clear playlist"
+msgstr "Clear playlist"
+
+#: front/src/components/audio/Player.vue:366
+msgid "Clear your queue"
+msgstr "Clear your queue"
+
+#: front/src/components/Home.vue:44
+msgid "Click once, listen for hours using built-in radios"
+msgstr "Click once, listen for hours using built-in radios"
+
+#: front/src/components/library/FileUpload.vue:75
+msgid "Click to select files to upload or drag and drop files or directories"
+msgstr "Click to select files to upload or drag and drop files or directories"
+
+#: front/src/components/ShortcutsModal.vue:20
+msgid "Close"
+msgstr "Close"
+
+#: front/src/components/manage/users/InvitationForm.vue:26
+#: front/src/components/manage/users/InvitationsTable.vue:42
+msgid "Code"
+msgstr "Code"
+
+#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/artist/Card.vue:33
+msgid "Collapse"
+msgstr "Collapse"
+
+#: front/src/components/library/radios/Builder.vue:62
+msgid "Config"
+msgstr "Config"
+
+#: front/src/components/common/DangerousButton.vue:21
+msgid "Confirm"
+msgstr "Confirm"
+
+#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
+#: front/src/views/auth/EmailConfirm.vue:51
+msgid "Confirm your e-mail address"
+msgstr "Confirm your e-mail address"
+
+#: front/src/views/auth/EmailConfirm.vue:13
+msgid "Confirmation code"
+msgstr "Confirmation code"
+
+#: front/src/components/common/ActionTable.vue:7
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "Content has been updated. Click refresh to see up-to-date content"
+
+#: front/src/components/Footer.vue:48
+msgid "Contribute"
+msgstr "Contribute"
+
+#: front/src/components/audio/EmbedWizard.vue:19
+#: front/src/components/common/CopyInput.vue:8
+msgid "Copy"
+msgstr "Copy"
+
+#: front/src/components/playlists/Editor.vue:163
+msgid "Copy queued tracks to playlist"
+msgstr "Copy queued tracks to playlist"
+
+#: front/src/components/audio/EmbedWizard.vue:21
+msgid "Copy/paste this code in your website HTML"
+msgstr "Copy/paste this code in your website HTML"
+
+#: front/src/components/library/Track.vue:91
+msgid "Copyright"
+msgstr "Copyright"
+
+#: front/src/views/auth/EmailConfirm.vue:7
+msgid "Could not confirm your e-mail address"
+msgstr "Could not confirm your e-mail address"
+
+#: front/src/views/content/remote/ScanForm.vue:3
+msgid "Could not fetch remote library"
+msgstr "Could not fetch remote library"
+
+#: front/src/views/content/libraries/FilesTable.vue:213
+msgid "Could not process this track, ensure it is tagged correctly"
+msgstr "Could not process this track, ensure it is tagged correctly"
+
+#: front/src/components/Home.vue:85
+msgid "Covers, lyrics, our goal is to have them all ;)"
+msgstr "Covers, lyrics, our goal is to have them all ;)"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgid "Create"
+msgstr "Create"
+
+#: front/src/components/auth/Signup.vue:4
+msgid "Create a funkwhale account"
+msgstr "Create a Funkwhale account"
+
+#: front/src/views/content/libraries/Home.vue:14
+msgid "Create a new library"
+msgstr "Create a new library"
+
+#: front/src/components/playlists/Form.vue:2
+msgid "Create a new playlist"
+msgstr "Create a new playlist"
+
+#: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+msgid "Create an account"
+msgstr "Create an account"
+
+#: front/src/views/content/libraries/Form.vue:26
+msgid "Create library"
+msgstr "Create library"
+
+#: front/src/components/auth/Signup.vue:53
+msgid "Create my account"
+msgstr "Create my account"
+
+#: front/src/components/playlists/Form.vue:34
+msgid "Create playlist"
+msgstr "Create playlist"
+
+#: front/src/components/library/Radios.vue:23
+msgid "Create your own radio"
+msgstr "Create your own radio"
+
+#: front/src/components/manage/users/InvitationsTable.vue:40
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+msgid "Creation date"
+msgstr "Creation date"
+
+#: front/src/components/auth/Settings.vue:54
+msgid "Current avatar"
+msgstr "Current avatar"
+
+#: front/src/views/content/libraries/DetailArea.vue:4
+msgid "Current library"
+msgstr "Current library"
+
+#: front/src/components/playlists/PlaylistModal.vue:8
+msgid "Current track"
+msgstr "Current track"
+
+#: front/src/views/content/libraries/Quota.vue:2
+msgid "Current usage"
+msgstr "Current usage"
+
+#: front/src/views/content/libraries/Detail.vue:27
+msgid "Date"
+msgstr "Date"
+
+#: front/src/components/ShortcutsModal.vue:75
+msgid "Decrease volume"
+msgstr "Decrease volume"
+
+#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:61
+#: front/src/components/manage/users/InvitationsTable.vue:167
+#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/content/libraries/Form.vue:29 src/views/playlists/Detail.vue:33
+msgid "Delete"
+msgstr "Delete"
+
+#: front/src/views/content/libraries/Form.vue:39
+msgid "Delete library"
+msgstr "Delete library"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgid "Delete moderation rule"
+msgstr "Delete moderation rule"
+
+#: front/src/views/playlists/Detail.vue:38
+msgid "Delete playlist"
+msgstr "Delete playlist"
+
+#: front/src/views/radios/Detail.vue:28
+msgid "Delete radio"
+msgstr "Delete radio"
+
+#: front/src/views/content/libraries/Form.vue:31
+msgid "Delete this library?"
+msgstr "Delete this library?"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgid "Delete this moderation rule?"
+msgstr "Delete this moderation rule?"
+
+#: front/src/components/favorites/List.vue:34 src/components/library/Artists.vue:26
+#: front/src/components/library/Radios.vue:47
+#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/manage/moderation/AccountsTable.vue:22
+#: front/src/components/manage/moderation/DomainsTable.vue:20
+#: front/src/components/manage/users/UsersTable.vue:20
+#: front/src/views/content/libraries/FilesTable.vue:32
+#: front/src/views/playlists/List.vue:28
+msgid "Descending"
+msgstr "Descending"
+
+#: front/src/components/library/radios/Builder.vue:25
+#: front/src/views/content/libraries/Form.vue:14
+msgid "Description"
+msgstr "Description"
+
+#: front/src/views/content/libraries/Card.vue:47
+msgid "Detail"
+msgstr "Detail"
+
+#: front/src/views/content/remote/Card.vue:50
+msgid "Details"
+msgstr "Details"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:455
+msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
+msgstr ""
+"Determine how much content the user can upload. Leave empty to use the "
+"default value of the instance."
+
+#: front/src/components/mixins/Translations.vue:8
+#: front/src/components/mixins/Translations.vue:9
+msgid "Determine the visibility level of your activity"
+msgstr "Determine the visibility level of your activity"
+
+#: front/src/components/auth/Settings.vue:103
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgid "Disable access"
+msgstr "Disable access"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgid "Disable Subsonic access"
+msgstr "Disable Subsonic access"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgid "Disable Subsonic API access?"
+msgstr "Disable Subsonic API access?"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:18
+#: front/src/views/admin/moderation/AccountsDetail.vue:128
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgid "Disabled"
+msgstr "Disabled"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgid "Discover how to use Funkwhale from other apps"
+msgstr "Discover how to use Funkwhale from other apps"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:103
+msgid "Display name"
+msgstr "Display name"
+
+#: front/src/components/library/radios/Builder.vue:30
+msgid "Display publicly"
+msgstr "Display publicly"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
+msgstr ""
+"Do not download any media files (audio, album cover, account avatar…) from "
+"this account or domain. This will purge existing content as well."
+
+#: front/src/components/playlists/Editor.vue:42
+msgid "Do you want to clear the playlist \"%{ playlist }\"?"
+msgstr "Do you want to clear the playlist \"%{ playlist }\"?"
+
+#: front/src/components/common/DangerousButton.vue:7
+msgid "Do you want to confirm this action?"
+msgstr "Do you want to confirm this action?"
+
+#: front/src/views/playlists/Detail.vue:35
+msgid "Do you want to delete the playlist \"%{ playlist }\"?"
+msgstr "Do you want to delete the playlist \"%{ playlist }\"?"
+
+#: front/src/views/radios/Detail.vue:26
+msgid "Do you want to delete the radio \"%{ radio }\"?"
+msgstr "Do you want to delete the radio \"%{ radio }\"?"
+
+#: front/src/components/common/ActionTable.vue:36
+msgid "Do you want to launch %{ action } on %{ count } element?"
+msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
+msgstr[0] "Do you want to launch %{ action } on %{ count } element?"
+msgstr[1] "Do you want to launch %{ action } on %{ count } elements?"
+
+#: front/src/components/Sidebar.vue:107
+msgid "Do you want to restore your previous queue?"
+msgstr "Do you want to restore your previous queue?"
+
+#: front/src/components/Footer.vue:31
+msgid "Documentation"
+msgstr "Documentation"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:40
+#: front/src/components/mixins/Translations.vue:34
+#: front/src/views/admin/moderation/AccountsDetail.vue:93
+#: front/src/components/mixins/Translations.vue:35
+msgid "Domain"
+msgstr "Domain"
+
+#: front/src/views/admin/moderation/Base.vue:5
+#: front/src/views/admin/moderation/DomainsList.vue:3
+#: front/src/views/admin/moderation/DomainsList.vue:48
+msgid "Domains"
+msgstr "Domains"
+
+#: front/src/components/library/Track.vue:55
+msgid "Download"
+msgstr "Download"
+
+#: front/src/components/playlists/Editor.vue:49
+msgid "Drag and drop rows to reorder tracks in the playlist"
+msgstr "Drag and drop rows to reorder tracks in the playlist"
+
+#: front/src/components/audio/track/Table.vue:9 src/components/library/Track.vue:111
+#: front/src/components/manage/library/FilesTable.vue:43
+#: front/src/components/mixins/Translations.vue:30
+#: front/src/views/content/libraries/FilesTable.vue:59
+#: front/src/components/mixins/Translations.vue:31
+msgid "Duration"
+msgstr "Duration"
+
+#: front/src/views/auth/EmailConfirm.vue:23
+msgid "E-mail address confirmed"
+msgstr "E-mail address confirmed"
+
+#: front/src/components/Home.vue:93
+msgid "Easy to use"
+msgstr "Easy to use"
+
+#: front/src/views/content/libraries/Detail.vue:9
+msgid "Edit"
+msgstr "Edit"
+
+#: front/src/components/About.vue:22
+msgid "Edit instance info"
+msgstr "Edit instance info"
+
+#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
+msgid "Edit…"
+msgstr "Edit…"
+
+#: front/src/components/auth/Signup.vue:30
+#: front/src/components/manage/users/UsersTable.vue:38
+msgid "Email"
+msgstr "Email"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:111
+msgid "Email address"
+msgstr "Email address"
+
+#: front/src/components/library/Album.vue:38 src/components/library/Track.vue:62
+msgid "Embed"
+msgstr "Embed"
+
+#: front/src/components/audio/EmbedWizard.vue:20
+msgid "Embed code"
+msgstr "Embed code"
+
+#: front/src/components/library/Album.vue:42
+msgid "Embed this album on your website"
+msgstr "Embed this album on your website"
+
+#: front/src/components/library/Track.vue:66
+msgid "Embed this track on your website"
+msgstr "Embed this track on your website"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgid "Emitted library follows"
+msgstr "Emitted library follows"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgid "Emitted messages"
+msgstr "Emitted messages"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:8
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:17
+#: front/src/views/admin/moderation/AccountsDetail.vue:127
+#: front/src/views/admin/moderation/AccountsDetail.vue:131
+msgid "Enabled"
+msgstr "Enabled"
+
+#: front/src/views/playlists/Detail.vue:29
+msgid "End edition"
+msgstr "End edition"
+
+#: front/src/views/content/remote/ScanForm.vue:50
+msgid "Enter a library URL"
+msgstr "Enter a library URL"
+
+#: front/src/components/library/Radios.vue:140
+msgid "Enter a radio name…"
+msgstr "Enter a radio name…"
+
+#: front/src/components/library/Artists.vue:118
+msgid "Enter artist name…"
+msgstr "Enter artist name…"
+
+#: front/src/views/playlists/List.vue:107
+msgid "Enter playlist name…"
+msgstr "Enter playlist name…"
+
+#: front/src/components/auth/Signup.vue:102
+msgid "Enter your email"
+msgstr "Enter your email"
+
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:99
+msgid "Enter your invitation code (case insensitive)"
+msgstr "Enter your invitation code (case insensitive)"
+
+#: front/src/components/metadata/Search.vue:114
+msgid "Enter your search query…"
+msgstr "Enter your search query…"
+
+#: front/src/components/auth/Signup.vue:101
+msgid "Enter your username"
+msgstr "Enter your username"
+
+#: front/src/components/auth/Login.vue:83
+msgid "Enter your username or email"
+msgstr "Enter your username or email"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:19
+#: front/src/views/content/libraries/Form.vue:4
+msgid "Error"
+msgstr "Error"
+
+#: front/src/views/admin/Settings.vue:87
+msgid "Error reporting"
+msgstr "Error reporting"
+
+#: front/src/components/common/ActionTable.vue:92
+msgid "Error while applying action"
+msgstr "Error while applying action"
+
+#: front/src/views/auth/PasswordReset.vue:7
+msgid "Error while asking for a password reset"
+msgstr "Error while asking for a password reset"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:7
+msgid "Error while changing your password"
+msgstr "Error while changing your password"
+
+#: front/src/views/admin/moderation/DomainsList.vue:6
+msgid "Error while creating domain"
+msgstr "Error while creating domain"
+
+#: front/src/components/manage/users/InvitationForm.vue:4
+msgid "Error while creating invitation"
+msgstr "Error while creating invitation"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgid "Error while creating rule"
+msgstr "Error while creating rule"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:126
+msgid "Error while fetching node info"
+msgstr "Error while fetching node info"
+
+#: front/src/components/admin/SettingsGroup.vue:5
+msgid "Error while saving settings"
+msgstr "Error while saving settings"
+
+#: front/src/views/content/libraries/FilesTable.vue:212
+msgid "Errored"
+msgstr "Errored"
+
+#: front/src/views/content/libraries/Quota.vue:75
+msgid "Errored files"
+msgstr "Errored files"
+
+#: front/src/components/playlists/Form.vue:89
+msgid "Everyone"
+msgstr "Everyone"
+
+#: front/src/components/mixins/Translations.vue:11
+#: front/src/components/playlists/Form.vue:85 src/views/content/libraries/Form.vue:73
+#: front/src/components/mixins/Translations.vue:12
+msgid "Everyone on this instance"
+msgstr "Everyone on this instance"
+
+#: front/src/views/content/libraries/Form.vue:74
+msgid "Everyone, across all instances"
+msgstr "Everyone, across all instances"
+
+#: front/src/components/library/radios/Builder.vue:61
+msgid "Exclude"
+msgstr "Exclude"
+
+#: front/src/components/manage/users/InvitationsTable.vue:41
+#: front/src/components/mixins/Translations.vue:22
+#: front/src/components/mixins/Translations.vue:23
+msgid "Expiration date"
+msgstr "Expiry date"
+
+#: front/src/components/manage/users/InvitationsTable.vue:50
+msgid "Expired"
+msgstr "Expired"
+
+#: front/src/components/manage/users/InvitationsTable.vue:21
+msgid "Expired/used"
+msgstr "Expired/used"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
+msgstr ""
+"Explain why you're applying this policy. Depending on your instance "
+"configuration, this will help you remember why you acted on this account or "
+"domain, and may be displayed publicly to help users understand what "
+"moderation rules are in place."
+
+#: front/src/views/content/libraries/FilesTable.vue:16
+msgid "Failed"
+msgstr "Failed"
+
+#: front/src/views/content/remote/Card.vue:58
+msgid "Failed tracks:"
+msgstr "Failed tracks:"
+
+#: front/src/components/Sidebar.vue:66
+msgid "Favorites"
+msgstr "Favourites"
+
+#: front/src/views/admin/Settings.vue:84
+msgid "Federation"
+msgstr "Federation"
+
+#: front/src/components/library/FileUpload.vue:84
+msgid "Filename"
+msgstr "Filename"
+
+#: front/src/views/admin/library/Base.vue:5 src/views/admin/library/FilesList.vue:21
+msgid "Files"
+msgstr "Files"
+
+#: front/src/components/library/radios/Builder.vue:60
+msgid "Filter name"
+msgstr "Filter name"
+
+#: front/src/views/content/libraries/FilesTable.vue:17
+#: front/src/views/content/libraries/FilesTable.vue:216
+msgid "Finished"
+msgstr "Finished"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:42
+#: front/src/components/manage/moderation/DomainsTable.vue:41
+#: front/src/views/admin/moderation/AccountsDetail.vue:159
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgid "First seen"
+msgstr "First seen"
+
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+msgid "First seen date"
+msgstr "First seen date"
+
+#: front/src/views/content/remote/Card.vue:83
+msgid "Follow"
+msgstr "Follow"
+
+#: front/src/views/content/Home.vue:16
+msgid "Follow remote libraries"
+msgstr "Follow remote libraries"
+
+#: front/src/views/content/remote/Card.vue:88
+msgid "Follow request pending approval"
+msgstr "Follow request pending approval"
+
+#: front/src/components/mixins/Translations.vue:38
+#: front/src/views/content/libraries/Detail.vue:7
+#: front/src/components/mixins/Translations.vue:39
+msgid "Followers"
+msgstr "Followers"
+
+#: front/src/views/content/remote/Card.vue:93
+msgid "Following"
+msgstr "Following"
+
+#: front/src/components/library/Track.vue:17
+msgid "From album %{ album } by %{ artist }"
+msgstr "From album %{ album } by %{ artist }"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgid "Funkwhale is compatible with other music players that support the Subsonic API."
+msgstr ""
+"Funkwhale is compatible with other music players that support the Subsonic "
+"API."
+
+#: front/src/components/Home.vue:95
+msgid "Funkwhale is dead simple to use."
+msgstr "Funkwhale is dead simple to use."
+
+#: front/src/components/Home.vue:39
+msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
+msgstr ""
+"Funkwhale is designed to make it easy to listen to music you like, or to "
+"discover new artists."
+
+#: front/src/components/Home.vue:116
+msgid "Funkwhale is free and gives you control on your music."
+msgstr "Funkwhale is free and gives you control of your music."
+
+#: front/src/components/Home.vue:66
+msgid "Funkwhale takes care of handling your music"
+msgstr "Funkwhale takes care of handling your music"
+
+#: front/src/components/ShortcutsModal.vue:38
+msgid "General shortcuts"
+msgstr "General shortcuts"
+
+#: front/src/components/manage/users/InvitationForm.vue:16
+msgid "Get a new invitation"
+msgstr "Get a new invitation"
+
+#: front/src/components/Home.vue:13
+msgid "Get me to the library"
+msgstr "Get me to the library"
+
+#: front/src/components/Home.vue:76
+msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
+msgstr ""
+"Get quality metadata about your music thanks to <a href=\"%{ url }\" target="
+"\"_blank\">MusicBrainz</a>"
+
+#: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgid "Get started"
+msgstr "Get started"
+
+#: front/src/components/Footer.vue:37
+msgid "Getting help"
+msgstr "Getting help"
+
+#: front/src/components/common/ActionTable.vue:34
+#: front/src/components/common/ActionTable.vue:54
+msgid "Go"
+msgstr "Go"
+
+#: front/src/components/PageNotFound.vue:14
+msgid "Go to home page"
+msgstr "Go to home page"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgid "Hide account or domain content, except from followers."
+msgstr "Hide account or domain content, except from followers."
+
+#: front/src/components/library/Home.vue:65
+msgid "Home"
+msgstr "Home"
+
+#: front/src/components/instance/Stats.vue:36
+msgid "Hours of music"
+msgstr "Hours of music"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
+msgstr ""
+"However, accessing Funkwhale from those clients requires a separate password "
+"you can set below."
+
+#: front/src/views/auth/PasswordResetConfirm.vue:24
+msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
+msgstr ""
+"If the email address provided in the previous step is valid and binded to a "
+"user account, you should receive an email with reset instructions in the "
+"next couple of minutes."
+
+#: front/src/components/manage/library/FilesTable.vue:40
+msgid "Import date"
+msgstr "Import date"
+
+#: front/src/components/Home.vue:71
+msgid "Import music from various platforms, such as YouTube or SoundCloud"
+msgstr "Import music from various platforms, such as YouTube or SoundCloud"
+
+#: front/src/components/library/FileUpload.vue:51
+msgid "Import reference"
+msgstr "Import reference"
+
+#: front/src/views/content/libraries/FilesTable.vue:11
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgid "Import status"
+msgstr "Import status"
+
+#: front/src/views/content/libraries/FilesTable.vue:217
+msgid "Imported"
+msgstr "Imported"
+
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgid "Imported date"
+msgstr "Imported date"
+
+#: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgid "In favorites"
+msgstr "In favourites"
+
+#: front/src/components/manage/users/UsersTable.vue:54
+msgid "Inactive"
+msgstr "Inactive"
+
+#: front/src/components/ShortcutsModal.vue:71
+msgid "Increase volume"
+msgstr "Increase volume"
+
+#: front/src/views/auth/PasswordReset.vue:54
+msgid "Input the email address binded to your account"
+msgstr "Input the email address bound to your account"
+
+#: front/src/components/playlists/Editor.vue:31
+msgid "Insert from queue (%{ count } track)"
+msgid_plural "Insert from queue (%{ count } tracks)"
+msgstr[0] "Insert from queue (%{ count } track)"
+msgstr[1] "Insert from queue (%{ count } tracks)"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgid "Instance data"
+msgstr "Instance data"
+
+#: front/src/views/admin/Settings.vue:80
+msgid "Instance information"
+msgstr "Instance information"
+
+#: front/src/components/library/Radios.vue:9
+msgid "Instance radios"
+msgstr "Instance radios"
+
+#: front/src/views/admin/Settings.vue:75
+msgid "Instance settings"
+msgstr "Instance settings"
+
+#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/library/FileUpload.vue:231
+msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr ""
+"Invalid file type, ensure you are uploading an audio file. Supported file "
+"extensions are %{ extensions }"
+
+#: front/src/components/auth/Signup.vue:44
+#: front/src/components/manage/users/InvitationForm.vue:11
+msgid "Invitation code"
+msgstr "Invitation code"
+
+#: front/src/views/admin/users/Base.vue:8 src/views/admin/users/InvitationsList.vue:3
+#: front/src/views/admin/users/InvitationsList.vue:24
+msgid "Invitations"
+msgstr "Invitations"
+
+#: front/src/components/Footer.vue:41
+msgid "Issue tracker"
+msgstr "Issue tracker"
+
+#: front/src/components/Home.vue:50
+msgid "Keep a track of your favorite songs"
+msgstr "Keep track of your favourite songs"
+
+#: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgid "Keyboard shortcuts"
+msgstr "Keyboard shortcuts"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgid "Known accounts"
+msgstr "Known accounts"
+
+#: front/src/views/content/remote/Home.vue:14
+msgid "Known libraries"
+msgstr "Known libraries"
+
+#: front/src/components/manage/users/UsersTable.vue:41
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/views/admin/moderation/AccountsDetail.vue:184
+#: front/src/components/mixins/Translations.vue:33
+msgid "Last activity"
+msgstr "Last activity"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:167
+#: front/src/views/admin/moderation/DomainsDetail.vue:86
+msgid "Last checked"
+msgstr "Last checked"
+
+#: front/src/components/playlists/PlaylistModal.vue:32
+msgid "Last modification"
+msgstr "Last modification"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:43
+msgid "Last seen"
+msgstr "Last seen"
+
+#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:19
+msgid "Last seen date"
+msgstr "Last seen date"
+
+#: front/src/views/content/remote/Card.vue:56
+msgid "Last update:"
+msgstr "Last update:"
+
+#: front/src/components/common/ActionTable.vue:47
+msgid "Launch"
+msgstr "Launch"
+
+#: front/src/components/Home.vue:10
+msgid "Learn more about this instance"
+msgstr "Learn more about this instance"
+
+#: front/src/components/manage/users/InvitationForm.vue:58
+msgid "Leave empty for a random code"
+msgstr "Leave empty for a random code"
+
+#: front/src/components/audio/EmbedWizard.vue:7
+msgid "Leave empty for a responsive widget"
+msgstr "Leave empty for a responsive widget"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:297
+#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/content/Base.vue:5
+msgid "Libraries"
+msgstr "Libraries"
+
+#: front/src/views/content/libraries/Form.vue:2
+msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
+msgstr ""
+"Libraries help you organise and share your music collections. You can upload "
+"your own music collection to Funkwhale and share it with your friends and "
+"family."
+
+#: front/src/components/instance/Stats.vue:30
+#: front/src/components/manage/users/UsersTable.vue:173
+#: front/src/views/admin/moderation/AccountsDetail.vue:464
+msgid "Library"
+msgstr "Library"
+
+#: front/src/views/content/libraries/Form.vue:109
+msgid "Library created"
+msgstr "Library created"
+
+#: front/src/views/content/libraries/Form.vue:129
+msgid "Library deleted"
+msgstr "Library deleted"
+
+#: front/src/views/admin/library/FilesList.vue:3
+msgid "Library files"
+msgstr "Library files"
+
+#: front/src/views/content/libraries/Form.vue:106
+msgid "Library updated"
+msgstr "Library updated"
+
+#: front/src/components/library/Track.vue:100
+msgid "License"
+msgstr "License"
+
+#: front/src/views/content/libraries/Detail.vue:21
+msgid "Loading followers…"
+msgstr "Loading followers…"
+
+#: front/src/views/content/libraries/Home.vue:3
+msgid "Loading Libraries…"
+msgstr "Loading Libraries…"
+
+#: front/src/views/content/libraries/Detail.vue:3
+#: front/src/views/content/libraries/Upload.vue:3
+msgid "Loading library data…"
+msgstr "Loading library data…"
+
+#: front/src/views/Notifications.vue:4
+msgid "Loading notifications…"
+msgstr "Loading notifications…"
+
+#: front/src/views/content/remote/Home.vue:3
+msgid "Loading remote libraries…"
+msgstr "Loading remote libraries…"
+
+#: front/src/views/content/libraries/Quota.vue:4
+msgid "Loading usage data…"
+msgstr "Loading usage data…"
+
+#: front/src/components/favorites/List.vue:5
+msgid "Loading your favorites…"
+msgstr "Loading your favourites…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:18
+msgid "Local account"
+msgstr "Local account"
+
+#: front/src/components/auth/Login.vue:84
+msgid "Log In"
+msgstr "Log In"
+
+#: front/src/components/auth/Login.vue:4
+msgid "Log in to your Funkwhale account"
+msgstr "Log in to your Funkwhale account"
+
+#: front/src/components/auth/Logout.vue:20
+msgid "Log Out"
+msgstr "Log Out"
+
+#: front/src/components/Sidebar.vue:38
+msgid "Logged in as %{ username }"
+msgstr "Logged in as %{ username }"
+
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+msgid "Login"
+msgstr "Login"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:119
+msgid "Login status"
+msgstr "Login status"
+
+#: front/src/components/Sidebar.vue:52
+msgid "Logout"
+msgstr "Logout"
+
+#: front/src/views/content/libraries/Home.vue:9
+msgid "Looks like you don't have a library, it's time to create one."
+msgstr "Looks like you don't have a library, it's time to create one."
+
+#: front/src/components/audio/Player.vue:356 src/components/audio/Player.vue:357
+msgid "Looping disabled. Click to switch to single-track looping."
+msgstr "Looping disabled. Click to switch to single-track looping."
+
+#: front/src/components/audio/Player.vue:359 src/components/audio/Player.vue:360
+msgid "Looping on a single track. Click to switch to whole queue looping."
+msgstr "Looping on a single track. Click to switch to whole queue looping."
+
+#: front/src/components/audio/Player.vue:362 src/components/audio/Player.vue:363
+msgid "Looping on whole queue. Click to disable looping."
+msgstr "Looping on whole queue. Click to disable looping."
+
+#: front/src/components/library/Track.vue:150
+msgid "Lyrics"
+msgstr "Lyrics"
+
+#: front/src/components/Sidebar.vue:210
+msgid "Main menu"
+msgstr "Main menu"
+
+#: front/src/views/admin/library/Base.vue:16
+msgid "Manage library"
+msgstr "Manage library"
+
+#: front/src/components/playlists/PlaylistModal.vue:3
+msgid "Manage playlists"
+msgstr "Manage playlists"
+
+#: front/src/views/admin/users/Base.vue:20
+msgid "Manage users"
+msgstr "Manage users"
+
+#: front/src/views/playlists/List.vue:8
+msgid "Manage your playlists"
+msgstr "Manage your playlists"
+
+#: front/src/views/Notifications.vue:17
+msgid "Mark all as read"
+msgstr "Mark all as read"
+
+#: front/src/components/notifications/NotificationRow.vue:46
+msgid "Mark as read"
+msgstr "Mark as read"
+
+#: front/src/components/notifications/NotificationRow.vue:47
+msgid "Mark as unread"
+msgstr "Mark as unread"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:281
+msgid "MB"
+msgstr "MB"
+
+#: front/src/components/audio/Player.vue:349
+msgid "Media player"
+msgstr "Media player"
+
+#: front/src/components/auth/Profile.vue:12
+msgid "Member since %{ date }"
+msgstr "Member since %{ date }"
+
+#: front/src/components/Footer.vue:32
+msgid "Mobile and desktop apps"
+msgstr "Mobile and desktop apps"
+
+#: front/src/components/Sidebar.vue:97 src/components/manage/users/UsersTable.vue:177
+#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/Base.vue:21
+msgid "Moderation"
+msgstr "Moderation"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgid "Moderation policies help you control how your instance interact with a given domain or account."
+msgstr ""
+"Moderation policies help you control how your instance interact with a given "
+"domain or account."
+
+#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:21
+msgid "Modification date"
+msgstr "Modification date"
+
+#: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+msgid "Music"
+msgstr "Music"
+
+#: front/src/components/audio/Player.vue:355
+msgid "Mute"
+msgstr "Mute"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+msgid "Mute activity"
+msgstr "Mute activity"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+msgid "Mute notifications"
+msgstr "Mute notifications"
+
+#: front/src/components/Sidebar.vue:34
+msgid "My account"
+msgstr "My account"
+
+#: front/src/components/library/radios/Builder.vue:236
+msgid "My awesome description"
+msgstr "My awesome description"
+
+#: front/src/views/content/libraries/Form.vue:70
+msgid "My awesome library"
+msgstr "My awesome library"
+
+#: front/src/components/playlists/Form.vue:74
+msgid "My awesome playlist"
+msgstr "My awesome playlist"
+
+#: front/src/components/library/radios/Builder.vue:235
+msgid "My awesome radio"
+msgstr "My awesome radio"
+
+#: front/src/views/content/libraries/Home.vue:6
+msgid "My libraries"
+msgstr "My libraries"
+
+#: front/src/components/audio/track/Row.vue:40 src/components/library/Track.vue:115
+#: front/src/components/library/Track.vue:124 src/components/library/Track.vue:133
+#: front/src/components/library/Track.vue:142
+#: front/src/components/manage/library/FilesTable.vue:63
+#: front/src/components/manage/library/FilesTable.vue:69
+#: front/src/components/manage/library/FilesTable.vue:75
+#: front/src/components/manage/library/FilesTable.vue:81
+#: front/src/components/manage/users/UsersTable.vue:61
+#: front/src/views/admin/moderation/AccountsDetail.vue:171
+#: front/src/views/admin/moderation/DomainsDetail.vue:90
+#: front/src/views/content/libraries/FilesTable.vue:92
+#: front/src/views/content/libraries/FilesTable.vue:98
+#: front/src/views/admin/moderation/DomainsDetail.vue:109
+#: front/src/views/admin/moderation/DomainsDetail.vue:117
+msgid "N/A"
+msgstr "N/A"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:39
+#: front/src/components/manage/moderation/DomainsTable.vue:38
+#: front/src/components/mixins/Translations.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:31
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+#: front/src/views/content/libraries/Form.vue:10
+#: front/src/components/mixins/Translations.vue:27
+msgid "Name"
+msgstr "Name"
+
+#: front/src/components/auth/Settings.vue:87
+#: front/src/views/auth/PasswordResetConfirm.vue:14
+msgid "New password"
+msgstr "New password"
+
+#: front/src/components/Sidebar.vue:160
+msgid "New tracks will be appended here automatically."
+msgstr "New tracks will be appended here automatically."
+
+#: front/src/components/audio/Player.vue:353
+msgid "Next track"
+msgstr "Next track"
+
+#: front/src/components/Sidebar.vue:119
+msgid "No"
+msgstr "No"
+
+#: front/src/components/Home.vue:100
+msgid "No add-ons, no plugins : you only need a web library"
+msgstr "No add-ons, no plugins : you only need a web library"
+
+#: front/src/components/audio/Search.vue:25
+msgid "No album matched your query"
+msgstr "No album matched your query"
+
+#: front/src/components/audio/Search.vue:16
+msgid "No artist matched your query"
+msgstr "No artist matched your query"
+
+#: front/src/components/library/Track.vue:158
+msgid "No lyrics available for this track."
+msgstr "No lyrics available for this track."
+
+#: front/src/components/federation/LibraryWidget.vue:6
+msgid "No matching library."
+msgstr "No matching library."
+
+#: front/src/views/Notifications.vue:26
+msgid "No notification to show."
+msgstr "No notification to show."
+
+#: front/src/components/mixins/Translations.vue:10
+#: front/src/components/playlists/Form.vue:81 src/views/content/libraries/Form.vue:72
+#: front/src/components/mixins/Translations.vue:11
+msgid "Nobody except me"
+msgstr "Nobody except me"
+
+#: front/src/views/content/libraries/Detail.vue:57
+msgid "Nobody is following this library"
+msgstr "Nobody is following this library"
+
+#: front/src/components/manage/users/InvitationsTable.vue:51
+msgid "Not used"
+msgstr "Not used"
+
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+msgid "Notifications"
+msgstr "Notifications"
+
+#: front/src/components/Footer.vue:47
+msgid "Official website"
+msgstr "Official website"
+
+#: front/src/components/auth/Settings.vue:82
+msgid "Old password"
+msgstr "Old password"
+
+#: front/src/components/manage/users/InvitationsTable.vue:20
+msgid "Open"
+msgstr "Open"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgid "Open profile"
+msgstr "Open profile"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgid "Open website"
+msgstr "Open website"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgid "Or customize your rule"
+msgstr "Or customise your rule"
+
+#: front/src/components/favorites/List.vue:31 src/components/library/Radios.vue:41
+#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/users/UsersTable.vue:17
+#: front/src/views/playlists/List.vue:25
+msgid "Order"
+msgstr "Order"
+
+#: front/src/components/favorites/List.vue:23 src/components/library/Artists.vue:15
+#: front/src/components/library/Radios.vue:33
+#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/manage/moderation/AccountsTable.vue:11
+#: front/src/components/manage/moderation/DomainsTable.vue:9
+#: front/src/components/manage/users/InvitationsTable.vue:9
+#: front/src/components/manage/users/UsersTable.vue:9
+#: front/src/views/content/libraries/FilesTable.vue:21
+#: front/src/views/playlists/List.vue:17
+msgid "Ordering"
+msgstr "Ordering"
+
+#: front/src/components/library/Artists.vue:23
+#: front/src/components/manage/moderation/AccountsTable.vue:19
+#: front/src/components/manage/moderation/DomainsTable.vue:17
+#: front/src/views/content/libraries/FilesTable.vue:29
+msgid "Ordering direction"
+msgstr "Ordering direction"
+
+#: front/src/components/manage/users/InvitationsTable.vue:38
+msgid "Owner"
+msgstr "Owner"
+
+#: front/src/components/PageNotFound.vue:33
+msgid "Page Not Found"
+msgstr "Page Not Found"
+
+#: front/src/components/PageNotFound.vue:7
+msgid "Page not found!"
+msgstr "Page not found!"
+
+#: front/src/components/Pagination.vue:39
+msgid "Pagination"
+msgstr "Pagination"
+
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+msgid "Password"
+msgstr "Password"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgid "Password updated"
+msgstr "Password updated"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:28
+msgid "Password updated successfully"
+msgstr "Password updated successfully"
+
+#: front/src/components/audio/Player.vue:352
+msgid "Pause track"
+msgstr "Pause track"
+
+#: front/src/components/ShortcutsModal.vue:59
+msgid "Pause/play the current track"
+msgstr "Pause/play the current track"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgid "Paused"
+msgstr "Paused"
+
+#: front/src/components/library/FileUpload.vue:107
+#: front/src/views/content/libraries/FilesTable.vue:14
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgid "Pending"
+msgstr "Pending"
+
+#: front/src/views/content/libraries/Detail.vue:37
+msgid "Pending approval"
+msgstr "Pending approval"
+
+#: front/src/views/content/libraries/Quota.vue:22
+msgid "Pending files"
+msgstr "Pending files"
+
+#: front/src/components/Sidebar.vue:212
+msgid "Pending follow requests"
+msgstr "Pending follow requests"
+
+#: front/src/components/manage/users/UsersTable.vue:42
+#: front/src/views/admin/moderation/AccountsDetail.vue:137
+msgid "Permissions"
+msgstr "Permissions"
+
+#: front/src/components/audio/PlayButton.vue:9 src/components/library/Track.vue:40
+msgid "Play"
+msgstr "Play"
+
+#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/artist/Card.vue:44 src/components/library/Album.vue:22
+#: front/src/components/library/Album.vue:67 src/views/playlists/Detail.vue:23
+msgid "Play all"
+msgstr "Play all"
+
+#: front/src/components/library/Artist.vue:26
+msgid "Play all albums"
+msgstr "Play all albums"
+
+#: front/src/components/audio/PlayButton.vue:15
+#: front/src/components/audio/PlayButton.vue:65
+msgid "Play next"
+msgstr "Play next"
+
+#: front/src/components/ShortcutsModal.vue:67
+msgid "Play next track"
+msgstr "Play next track"
+
+#: front/src/components/audio/PlayButton.vue:16
+#: front/src/components/audio/PlayButton.vue:63
+msgid "Play now"
+msgstr "Play now"
+
+#: front/src/components/ShortcutsModal.vue:63
+msgid "Play previous track"
+msgstr "Play previous track"
+
+#: front/src/components/Sidebar.vue:211
+msgid "Play this track"
+msgstr "Play this track"
+
+#: front/src/components/audio/Player.vue:351
+msgid "Play track"
+msgstr "Play track"
+
+#: front/src/components/audio/PlayButton.vue:70
+msgid "Play..."
+msgstr "Play…"
+
+#: front/src/views/playlists/Detail.vue:90
+msgid "Playlist"
+msgstr "Playlist"
+
+#: front/src/views/playlists/Detail.vue:12
+msgid "Playlist containing %{ count } track, by %{ username }"
+msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
+msgstr[0] "Playlist containing %{ count } track, by %{ username }"
+msgstr[1] "Playlist containing %{ count } tracks, by %{ username }"
+
+#: front/src/components/playlists/Form.vue:9
+msgid "Playlist created"
+msgstr "Playlist created"
+
+#: front/src/components/playlists/Editor.vue:4
+msgid "Playlist editor"
+msgstr "Playlist editor"
+
+#: front/src/components/playlists/Form.vue:21
+msgid "Playlist name"
+msgstr "Playlist name"
+
+#: front/src/components/playlists/Form.vue:6
+msgid "Playlist updated"
+msgstr "Playlist updated"
+
+#: front/src/components/playlists/Form.vue:25
+msgid "Playlist visibility"
+msgstr "Playlist visibility"
+
+#: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
+#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
+#: front/src/views/playlists/List.vue:106
+msgid "Playlists"
+msgstr "Playlists"
+
+#: front/src/components/Home.vue:56
+msgid "Playlists? We got them"
+msgstr "Playlists? We got them"
+
+#: front/src/components/auth/Settings.vue:78
+msgid "Please double-check your password is correct"
+msgstr "Please double-check your password is correct"
+
+#: front/src/components/auth/Login.vue:9
+msgid "Please double-check your username/password couple is correct"
+msgstr "Please double-check your username/password couple is correct"
+
+#: front/src/components/auth/Settings.vue:46
+msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
+msgstr "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgid "Prevent account or domain from triggering notifications, except from followers."
+msgstr ""
+"Prevent account or domain from triggering notifications, except from "
+"followers."
+
+#: front/src/components/audio/EmbedWizard.vue:29
+msgid "Preview"
+msgstr "Preview"
+
+#: front/src/components/audio/Player.vue:350
+msgid "Previous track"
+msgstr "Previous track"
+
+#: front/src/views/content/remote/Card.vue:39
+msgid "Problem during scanning"
+msgstr "Problem during scanning"
+
+#: front/src/components/library/FileUpload.vue:58
+msgid "Proceed"
+msgstr "Proceed"
+
+#: front/src/views/auth/EmailConfirm.vue:26
+#: front/src/views/auth/PasswordResetConfirm.vue:31
+msgid "Proceed to login"
+msgstr "Proceed to login"
+
+#: front/src/components/library/FileUpload.vue:17
+msgid "Processing"
+msgstr "Processing"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:188
+#: front/src/components/manage/moderation/DomainsTable.vue:168
+#: front/src/views/content/libraries/Quota.vue:36
+#: front/src/views/content/libraries/Quota.vue:39
+#: front/src/views/content/libraries/Quota.vue:62
+#: front/src/views/content/libraries/Quota.vue:65
+#: front/src/views/content/libraries/Quota.vue:88
+#: front/src/views/content/libraries/Quota.vue:91
+msgid "Purge"
+msgstr "Purge"
+
+#: front/src/views/content/libraries/Quota.vue:89
+msgid "Purge errored files?"
+msgstr "Purge errored files?"
+
+#: front/src/views/content/libraries/Quota.vue:37
+msgid "Purge pending files?"
+msgstr "Purge pending files?"
+
+#: front/src/views/content/libraries/Quota.vue:63
+msgid "Purge skipped files?"
+msgstr "Purge skipped files?"
+
+#: front/src/components/Sidebar.vue:20
+msgid "Queue"
+msgstr "Queue"
+
+#: front/src/components/audio/Player.vue:283
+msgid "Queue shuffled!"
+msgstr "Queue shuffled!"
+
+#: front/src/views/radios/Detail.vue:80
+msgid "Radio"
+msgstr "Radio"
+
+#: front/src/components/library/radios/Builder.vue:233
+msgid "Radio Builder"
+msgstr "Radio Builder"
+
+#: front/src/components/library/radios/Builder.vue:15
+msgid "Radio created"
+msgstr "Radio created"
+
+#: front/src/components/library/radios/Builder.vue:21
+msgid "Radio name"
+msgstr "Radio name"
+
+#: front/src/components/library/radios/Builder.vue:12
+msgid "Radio updated"
+msgstr "Radio updated"
+
+#: front/src/components/library/Library.vue:10 src/components/library/Radios.vue:141
+msgid "Radios"
+msgstr "Radios"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:39
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgid "Reason"
+msgstr "Reason"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgid "Received library follows"
+msgstr "Received library follows"
+
+#: front/src/components/manage/moderation/DomainsTable.vue:40
+#: front/src/components/mixins/Translations.vue:36
+#: front/src/components/mixins/Translations.vue:37
+msgid "Received messages"
+msgstr "Received messages"
+
+#: front/src/components/library/Home.vue:24
+msgid "Recently added"
+msgstr "Recently added"
+
+#: front/src/components/library/Home.vue:11
+msgid "Recently favorited"
+msgstr "Recently favourited"
+
+#: front/src/components/library/Home.vue:6
+msgid "Recently listened"
+msgstr "Recently listened"
+
+#: front/src/views/content/remote/Home.vue:15
+msgid "Refresh"
+msgstr "Refresh"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:135
+msgid "Refresh node info"
+msgstr "Refresh node info"
+
+#: front/src/components/common/ActionTable.vue:272
+msgid "Refresh table content"
+msgstr "Refresh table content"
+
+#: front/src/components/auth/Signup.vue:9
+msgid "Registration are closed on this instance, you will need an invitation code to signup."
+msgstr ""
+"Registration are closed on this instance, you will need an invitation code "
+"to signup."
+
+#: front/src/components/manage/users/UsersTable.vue:71
+msgid "regular user"
+msgstr "regular user"
+
+#: front/src/views/content/libraries/Detail.vue:51
+msgid "Reject"
+msgstr "Reject"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:32
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+msgid "Reject media"
+msgstr "Reject media"
+
+#: front/src/views/content/libraries/Detail.vue:43
+msgid "Rejected"
+msgstr "Rejected"
+
+#: front/src/views/content/libraries/FilesTable.vue:234
+msgid "Relaunch import"
+msgstr "Relaunch import"
+
+#: front/src/views/content/remote/Home.vue:6
+msgid "Remote libraries"
+msgstr "Remote libraries"
+
+#: front/src/views/content/remote/Home.vue:7
+msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
+msgstr ""
+"Remote libraries are owned by other users on the network. You can access "
+"them as long as they are public or you are granted access."
+
+#: front/src/components/library/radios/Filter.vue:59
+msgid "Remove"
+msgstr "Remove"
+
+#: front/src/components/auth/Settings.vue:58
+msgid "Remove avatar"
+msgstr "Remove avatar"
+
+#: front/src/components/favorites/TrackFavoriteIcon.vue:26
+msgid "Remove from favorites"
+msgstr "Remove from favourites"
+
+#: front/src/views/content/libraries/Quota.vue:38
+msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
+msgstr ""
+"Removes uploaded but yet to be processed tracks completely, adding the "
+"corresponding data to your quota."
+
+#: front/src/views/content/libraries/Quota.vue:64
+msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
+msgstr ""
+"Removes uploaded tracks skipped during the import processes completely, "
+"adding the corresponding data to your quota."
+
+#: front/src/views/content/libraries/Quota.vue:90
+msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
+msgstr ""
+"Removes uploaded tracks that could not be processed by the server "
+"completely, adding the corresponding data to your quota."
+
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+msgid "Request a new password"
+msgstr "Request a new password"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgid "Request a new Subsonic API password?"
+msgstr "Request a new Subsonic API password?"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgid "Request a password"
+msgstr "Request a password"
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+msgid "Reset your password"
+msgstr "Reset your password"
+
+#: front/src/components/favorites/List.vue:38 src/components/library/Artists.vue:30
+#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+msgid "Results per page"
+msgstr "Results per page"
+
+#: front/src/views/auth/EmailConfirm.vue:17
+msgid "Return to login"
+msgstr "Return to login"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgid "Rule"
+msgstr "Rule"
+
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:33
+msgid "Save"
+msgstr "Save"
+
+#: front/src/views/content/remote/Card.vue:165
+msgid "Scan launched"
+msgstr "Scan launched"
+
+#: front/src/views/content/remote/Card.vue:63
+msgid "Scan now"
+msgstr "Scan now"
+
+#: front/src/views/content/remote/Card.vue:166
+msgid "Scan skipped (previous scan is too recent)"
+msgstr "Scan skipped (previous scan is too recent)"
+
+#: front/src/views/content/remote/Card.vue:31
+msgid "Scan waiting"
+msgstr "Scan waiting"
+
+#: front/src/views/content/remote/Card.vue:43
+msgid "Scanned"
+msgstr "Scanned"
+
+#: front/src/views/content/remote/Card.vue:47
+msgid "Scanned with errors"
+msgstr "Scanned with errors"
+
+#: front/src/views/content/remote/Card.vue:35
+msgid "Scanning… (%{ progress }%)"
+msgstr "Scanning… (%{ progress }%)"
+
+#: front/src/components/library/Artists.vue:10 src/components/library/Radios.vue:29
+#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/manage/moderation/AccountsTable.vue:5
+#: front/src/components/manage/moderation/DomainsTable.vue:5
+#: front/src/components/manage/users/InvitationsTable.vue:5
+#: front/src/components/manage/users/UsersTable.vue:5
+#: front/src/views/content/libraries/FilesTable.vue:5 src/views/playlists/List.vue:13
+msgid "Search"
+msgstr "Search"
+
+#: front/src/views/content/remote/ScanForm.vue:9
+msgid "Search a remote library"
+msgstr "Search a remote library"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgid "Search by domain, username, bio…"
+msgstr "Search by domain, username, bio…"
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgid "Search by name…"
+msgstr "Search by name…"
+
+#: front/src/views/content/libraries/FilesTable.vue:201
+msgid "Search by title, artist, album…"
+msgstr "Search by title, artist, album…"
+
+#: front/src/components/manage/library/FilesTable.vue:176
+msgid "Search by title, artist, domain…"
+msgstr "Search by title, artist, domain…"
+
+#: front/src/components/manage/users/InvitationsTable.vue:153
+msgid "Search by username, e-mail address, code…"
+msgstr "Search by username, e-mail address, code…"
+
+#: front/src/components/manage/users/UsersTable.vue:163
+msgid "Search by username, e-mail address, name…"
+msgstr "Search by username, e-mail address, name…"
+
+#: front/src/components/audio/SearchBar.vue:20
+msgid "Search for artists, albums, tracks…"
+msgstr "Search for artists, albums, tracks…"
+
+#: front/src/components/audio/Search.vue:2
+msgid "Search for some music"
+msgstr "Search for some music"
+
+#: front/src/components/library/Track.vue:162
+msgid "Search on lyrics.wikia.com"
+msgstr "Search on lyrics.wikia.com"
+
+#: front/src/components/library/Album.vue:27 src/components/library/Artist.vue:31
+#: front/src/components/library/Track.vue:47
+msgid "Search on Wikipedia"
+msgstr "Search on Wikipedia"
+
+#: front/src/components/library/Library.vue:32 src/views/admin/library/Base.vue:17
+#: front/src/views/admin/moderation/Base.vue:22 src/views/admin/users/Base.vue:21
+#: front/src/views/content/Base.vue:19
+msgid "Secondary menu"
+msgstr "Secondary menu"
+
+#: front/src/views/admin/Settings.vue:15
+msgid "Sections"
+msgstr "Sections"
+
+#: front/src/components/library/radios/Builder.vue:45
+msgid "Select a filter"
+msgstr "Select a filter"
+
+#: front/src/components/common/ActionTable.vue:77
+msgid "Select all %{ total } elements"
+msgid_plural "Select all %{ total } elements"
+msgstr[0] "Select all %{ total } elements"
+msgstr[1] "Select all %{ total } elements"
+
+#: front/src/components/common/ActionTable.vue:86
+msgid "Select only current page"
+msgstr "Select only current page"
+
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/manage/users/UsersTable.vue:181
+#: front/src/views/admin/moderation/AccountsDetail.vue:472
+msgid "Settings"
+msgstr "Settings"
+
+#: front/src/components/auth/Settings.vue:10
+msgid "Settings updated"
+msgstr "Settings updated"
+
+#: front/src/components/admin/SettingsGroup.vue:11
+msgid "Settings updated successfully."
+msgstr "Settings updated successfully."
+
+#: front/src/components/manage/users/InvitationForm.vue:27
+msgid "Share link"
+msgstr "Share link"
+
+#: front/src/views/content/libraries/Detail.vue:15
+msgid "Share this link with other users so they can request access to your library."
+msgstr ""
+"Share this link with other users so they can request access to your library."
+
+#: front/src/views/content/libraries/Detail.vue:14
+#: front/src/views/content/remote/Card.vue:73
+msgid "Sharing link"
+msgstr "Sharing link"
+
+#: front/src/components/audio/album/Card.vue:40
+msgid "Show %{ count } more track"
+msgid_plural "Show %{ count } more tracks"
+msgstr[0] "Show %{ count } more track"
+msgstr[1] "Show %{ count } more tracks"
+
+#: front/src/components/audio/artist/Card.vue:30
+msgid "Show 1 more album"
+msgid_plural "Show %{ count } more albums"
+msgstr[0] "Show 1 more album"
+msgstr[1] "Show %{ count } more albums"
+
+#: front/src/components/ShortcutsModal.vue:42
+msgid "Show available keyboard shortcuts"
+msgstr "Show available keyboard shortcuts"
+
+#: front/src/views/Notifications.vue:10
+msgid "Show read notifications"
+msgstr "Show read notifications"
+
+#: front/src/components/forms/PasswordInput.vue:26
+msgid "Show/hide password"
+msgstr "Show/hide password"
+
+#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/moderation/AccountsTable.vue:88
+#: front/src/components/manage/moderation/DomainsTable.vue:74
+#: front/src/components/manage/users/InvitationsTable.vue:76
+#: front/src/components/manage/users/UsersTable.vue:87
+#: front/src/views/content/libraries/FilesTable.vue:114
+msgid "Showing results %{ start }-%{ end } on %{ total }"
+msgstr "Showing results %{ start }-%{ end } on %{ total }"
+
+#: front/src/components/ShortcutsModal.vue:83
+msgid "Shuffle queue"
+msgstr "Shuffle queue"
+
+#: front/src/components/audio/Player.vue:365
+msgid "Shuffle your queue"
+msgstr "Shuffle your queue"
+
+#: front/src/components/auth/Signup.vue:97
+msgid "Sign Up"
+msgstr "Sign Up"
+
+#: front/src/components/manage/users/UsersTable.vue:40
+msgid "Sign-up"
+msgstr "Sign-up"
+
+#: front/src/components/mixins/Translations.vue:31
+#: front/src/views/admin/moderation/AccountsDetail.vue:176
+#: front/src/components/mixins/Translations.vue:32
+msgid "Sign-up date"
+msgstr "Sign-up date"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+msgid "Silence notifications"
+msgstr "Silence notifications"
+
+#: front/src/components/library/FileUpload.vue:85
+#: front/src/components/library/Track.vue:120
+#: front/src/components/manage/library/FilesTable.vue:44
+#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:29
+msgid "Size"
+msgstr "Size"
+
+#: front/src/views/content/libraries/FilesTable.vue:15
+#: front/src/views/content/libraries/FilesTable.vue:204
+msgid "Skipped"
+msgstr "Skipped"
+
+#: front/src/views/content/libraries/Quota.vue:49
+msgid "Skipped files"
+msgstr "Skipped files"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+msgid "Software"
+msgstr "Software"
+
+#: front/src/components/Footer.vue:49
+msgid "Source code"
+msgstr "Source code"
+
+#: front/src/components/auth/Profile.vue:23
+#: front/src/components/manage/users/UsersTable.vue:70
+msgid "Staff member"
+msgstr "Staff member"
+
+#: front/src/components/radios/Button.vue:4
+msgid "Start"
+msgstr "Start"
+
+#: front/src/views/admin/Settings.vue:86
+msgid "Statistics"
+msgstr "Statistics"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:454
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
+msgstr ""
+"Statistics are computed from known activity and content on your instance, "
+"and do not reflect general activity for this account"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:358
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
+msgstr ""
+"Statistics are computed from known activity and content on your instance, "
+"and do not reflect general activity for this domain"
+
+#: front/src/components/library/FileUpload.vue:86
+#: front/src/components/manage/users/InvitationsTable.vue:17
+#: front/src/components/manage/users/InvitationsTable.vue:39
+#: front/src/components/manage/users/UsersTable.vue:43
+#: front/src/views/admin/moderation/DomainsDetail.vue:123
+#: front/src/views/content/libraries/Detail.vue:28
+msgid "Status"
+msgstr "Status"
+
+#: front/src/components/radios/Button.vue:3
+msgid "Stop"
+msgstr "Stop"
+
+#: front/src/components/Sidebar.vue:161
+msgid "Stop radio"
+msgstr "Stop radio"
+
+#: front/src/App.vue:22
+msgid "Submit"
+msgstr "Submit"
+
+#: front/src/views/admin/Settings.vue:85
+msgid "Subsonic"
+msgstr "Subsonic"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:2
+msgid "Subsonic API password"
+msgstr "Subsonic API password"
+
+#: front/src/App.vue:26
+msgid "Suggested choices"
+msgstr "Suggested choices"
+
+#: front/src/components/library/FileUpload.vue:3
+msgid "Summary"
+msgstr "Summary"
+
+#: front/src/components/Footer.vue:39
+msgid "Support forum"
+msgstr "Support forum"
+
+#: front/src/components/library/FileUpload.vue:78
+msgid "Supported extensions: %{ extensions }"
+msgstr "Supported extensions: %{ extensions }"
+
+#: front/src/components/playlists/Editor.vue:9
+msgid "Syncing changes to server…"
+msgstr "Syncing changes to server…"
+
+#: front/src/components/common/CopyInput.vue:3
+msgid "Text copied to clipboard!"
+msgstr "Text copied to clipboard!"
+
+#: front/src/components/Home.vue:26
+msgid "That's simple: we loved Grooveshark and we want to build something even better."
+msgstr ""
+"That's simple: we loved Grooveshark and we want to build something even "
+"better."
+
+#: front/src/components/Footer.vue:53
+msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
+msgstr "The funkwhale logo was kindly designed and provided by Francis Gading."
+
+#: front/src/views/content/libraries/Form.vue:34
+msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr "The library and all its tracks will be deleted. This can not be undone."
+
+#: front/src/components/library/FileUpload.vue:39
+msgid "The music files you are uploading are tagged properly:"
+msgstr "The music files you are uploading are tagged properly:"
+
+#: front/src/components/audio/Player.vue:67
+msgid "The next track will play automatically in a few seconds…"
+msgstr "The next track will play automatically in a few seconds…"
+
+#: front/src/components/Home.vue:121
+msgid "The plaform is free and open-source, you can install it and modify it without worries"
+msgstr ""
+"The platform is free and open-source, you can install it and modify it "
+"without worries"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:4
+msgid "The Subsonic API is not available on this Funkwhale instance."
+msgstr "The Subsonic API is not available on this Funkwhale instance."
+
+#: front/src/components/library/FileUpload.vue:43
+msgid "The uploaded music files are in OGG, Flac or MP3 format"
+msgstr "The uploaded music files are in OGG, Flac or MP3 format"
+
+#: front/src/views/content/Home.vue:4
+msgid "There are various ways to grab new content and make it available here."
+msgstr "There are various ways to grab new content and make it available here."
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgid "This action is irreversible."
+msgstr "This action is irreversible."
+
+#: front/src/components/library/Album.vue:85
+msgid "This album is present in the following libraries:"
+msgstr "This album is present in the following libraries:"
+
+#: front/src/components/library/Artist.vue:63
+msgid "This artist is present in the following libraries:"
+msgstr "This artist is present in the following libraries:"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgid "This domain is subject to specific moderation rules"
+msgstr "This domain is subject to specific moderation rules"
+
+#: front/src/views/content/Home.vue:9
+msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr "This instance offers up to %{quota} of storage space for every user."
+
+#: front/src/components/auth/Profile.vue:16
+msgid "This is you!"
+msgstr "This is you!"
+
+#: front/src/views/content/libraries/Form.vue:71
+msgid "This library contains my personal music, I hope you like it."
+msgstr "This library contains my personal music, I hope you like it."
+
+#: front/src/views/content/remote/Card.vue:131
+msgid "This library is private and your approval from its owner is needed to access its content"
+msgstr ""
+"This library is private and approval from its owner is needed to access its "
+"content"
+
+#: front/src/views/content/remote/Card.vue:132
+msgid "This library is public and you can access its content freely"
+msgstr "This library is public and you can access its content freely"
+
+#: front/src/components/common/ActionTable.vue:45
+msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
+msgstr ""
+"This may affect a lot of elements or have irreversible consequences, please "
+"double check this is really what you want."
+
+#: front/src/components/library/FileUpload.vue:52
+msgid "This reference will be used to group imported files together."
+msgstr "his reference will be used to group imported files together."
+
+#: front/src/components/audio/PlayButton.vue:73
+msgid "This track is not available in any library you have access to"
+msgstr "This track is not available in any library you have access to"
+
+#: front/src/components/library/Track.vue:171
+msgid "This track is present in the following libraries:"
+msgstr "This track is present in the following libraries:"
+
+#: front/src/views/playlists/Detail.vue:37
+msgid "This will completely delete this playlist and cannot be undone."
+msgstr "This will completely delete this playlist and cannot be undone."
+
+#: front/src/views/radios/Detail.vue:27
+msgid "This will completely delete this radio and cannot be undone."
+msgstr "This will completely delete this radio and cannot be undone."
+
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgid "This will completely disable access to the Subsonic API using from account."
+msgstr ""
+"This will completely disable access to the Subsonic API using from account."
+
+#: front/src/App.vue:132 src/components/Footer.vue:72
+msgid "This will erase your local data and disconnect you, do you want to continue?"
+msgstr ""
+"This will erase your local data and disconnect you, do you want to continue?"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgid "This will log you out from existing devices that use the current password."
+msgstr ""
+"This will log you out from existing devices that use the current password."
+
+#: front/src/components/playlists/Editor.vue:44
+msgid "This will remove all tracks from this playlist and cannot be undone."
+msgstr "This will remove all tracks from this playlist and cannot be undone."
+
+#: front/src/components/audio/track/Table.vue:6
+#: front/src/components/manage/library/FilesTable.vue:37
+#: front/src/components/mixins/Translations.vue:27
+#: front/src/views/content/libraries/FilesTable.vue:54
+#: front/src/components/mixins/Translations.vue:28
+msgid "Title"
+msgstr "Title"
+
+#: front/src/components/ShortcutsModal.vue:79
+msgid "Toggle queue looping"
+msgstr "Toggle queue looping"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgid "Total size"
+msgstr "Total size"
+
+#: front/src/views/content/libraries/Card.vue:61
+msgid "Total size of the files in this library"
+msgstr "Total size of the files in this library"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:113
+msgid "Total users"
+msgstr "Total users"
+
+#: front/src/components/audio/SearchBar.vue:27 src/components/library/Track.vue:262
+#: front/src/components/metadata/Search.vue:138
+msgid "Track"
+msgstr "Track"
+
+#: front/src/views/content/libraries/FilesTable.vue:205
+msgid "Track already present in one of your libraries"
+msgstr "Track already present in one of your libraries"
+
+#: front/src/components/library/Track.vue:85
+msgid "Track information"
+msgstr "Track information"
+
+#: front/src/components/library/radios/Filter.vue:44
+msgid "Track matching filter"
+msgstr "Track matching filter"
+
+#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:24
+msgid "Track name"
+msgstr "Track name"
+
+#: front/src/views/content/libraries/FilesTable.vue:209
+msgid "Track uploaded, but not processed by the server yet"
+msgstr "Track uploaded, but not processed by the server yet"
+
+#: front/src/components/instance/Stats.vue:54
+msgid "tracks"
+msgstr "tracks"
+
+#: front/src/components/library/Album.vue:75
+#: front/src/components/playlists/PlaylistModal.vue:33
+#: front/src/views/admin/moderation/AccountsDetail.vue:329
+#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
+#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+msgid "Tracks"
+msgstr "Tracks"
+
+#: front/src/components/library/Artist.vue:54
+msgid "Tracks by this artist"
+msgstr "Tracks by this artist"
+
+#: front/src/components/instance/Stats.vue:25
+msgid "Tracks favorited"
+msgstr "Tracks favourited"
+
+#: front/src/components/instance/Stats.vue:19
+msgid "tracks listened"
+msgstr "tracks listened"
+
+#: front/src/components/library/Track.vue:138
+#: front/src/components/manage/library/FilesTable.vue:41
+#: front/src/views/admin/moderation/AccountsDetail.vue:151
+msgid "Type"
+msgstr "Type"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:44
+#: front/src/components/manage/moderation/DomainsTable.vue:42
+msgid "Under moderation rule"
+msgstr "Under moderation rule"
+
+#: front/src/views/content/remote/Card.vue:100 src/views/content/remote/Card.vue:105
+msgid "Unfollow"
+msgstr "Unfollow"
+
+#: front/src/views/content/remote/Card.vue:101
+msgid "Unfollow this library?"
+msgstr "Unfollow this library?"
+
+#: front/src/components/About.vue:17
+msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+msgstr ""
+"Unfortunately, owners of this instance did not yet take the time to complete "
+"this page."
+
+#: front/src/components/Home.vue:37
+msgid "Unlimited music"
+msgstr "Unlimited music"
+
+#: front/src/components/audio/Player.vue:354
+msgid "Unmute"
+msgstr "Unmute"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgid "Update"
+msgstr "Update"
+
+#: front/src/components/auth/Settings.vue:50
+msgid "Update avatar"
+msgstr "Update avatar"
+
+#: front/src/views/content/libraries/Form.vue:25
+msgid "Update library"
+msgstr "Update library"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgid "Update moderation rule"
+msgstr "Update moderation rule"
+
+#: front/src/components/playlists/Form.vue:33
+msgid "Update playlist"
+msgstr "Update playlist"
+
+#: front/src/components/auth/Settings.vue:27
+msgid "Update settings"
+msgstr "Update settings"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:21
+msgid "Update your password"
+msgstr "Update your password"
+
+#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/DetailArea.vue:24
+msgid "Upload"
+msgstr "Upload"
+
+#: front/src/components/auth/Settings.vue:45
+msgid "Upload a new avatar"
+msgstr "Upload a new avatar"
+
+#: front/src/views/content/Home.vue:6
+msgid "Upload audio content"
+msgstr "Upload audio content"
+
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgid "Upload date"
+msgstr "Upload date"
+
+#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:221
+msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr ""
+"Upload denied, ensure the file is not too big and that you have not reached "
+"your quota"
+
+#: front/src/views/content/Home.vue:7
+msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
+msgstr ""
+"Upload music files (MP3, OGG, FLAC, etc.) from your personal library "
+"directly from your browser to enjoy them here."
+
+#: front/src/components/library/FileUpload.vue:31
+msgid "Upload new tracks"
+msgstr "Upload new tracks"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:269
+msgid "Upload quota"
+msgstr "Upload quota"
+
+#: front/src/components/library/FileUpload.vue:229
+msgid "Upload timeout, please try again"
+msgstr "Upload timeout, please try again"
+
+#: front/src/components/library/FileUpload.vue:100
+msgid "Uploaded"
+msgstr "Uploaded"
+
+#: front/src/components/library/FileUpload.vue:5
+msgid "Uploading"
+msgstr "Uploading"
+
+#: front/src/components/library/FileUpload.vue:103
+msgid "Uploading…"
+msgstr "Uploading…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:41
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:305
+#: front/src/views/admin/moderation/DomainsDetail.vue:241
+#: front/src/components/mixins/Translations.vue:38
+msgid "Uploads"
+msgstr "Uploads"
+
+#: front/src/components/Footer.vue:16
+msgid "Use another instance"
+msgstr "Use another instance"
+
+#: front/src/views/auth/PasswordReset.vue:12
+msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
+msgstr ""
+"Use this form to request a password reset. We will send an email to the "
+"given address with instructions to reset your password."
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
+msgstr ""
+"Use this setting to temporarily enable/disable the policy without completely "
+"removing it."
+
+#: front/src/components/manage/users/InvitationsTable.vue:49
+msgid "Used"
+msgstr "Used"
+
+#: front/src/views/content/libraries/Detail.vue:26
+msgid "User"
+msgstr "User"
+
+#: front/src/components/instance/Stats.vue:5
+msgid "User activity"
+msgstr "User activity"
+
+#: front/src/components/library/Album.vue:82 src/components/library/Artist.vue:60
+#: front/src/components/library/Track.vue:168
+msgid "User libraries"
+msgstr "User libraries"
+
+#: front/src/components/library/Radios.vue:20
+msgid "User radios"
+msgstr "User radios"
+
+#: front/src/components/auth/Signup.vue:19
+#: front/src/components/manage/users/UsersTable.vue:37
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/views/admin/moderation/AccountsDetail.vue:85
+#: front/src/components/mixins/Translations.vue:34
+msgid "Username"
+msgstr "Username"
+
+#: front/src/components/auth/Login.vue:15
+msgid "Username or email"
+msgstr "Username or email"
+
+#: front/src/components/instance/Stats.vue:13
+msgid "users"
+msgstr "users"
+
+#: front/src/components/Sidebar.vue:91
+#: front/src/components/manage/moderation/DomainsTable.vue:39
+#: front/src/components/mixins/Translations.vue:35 src/views/admin/Settings.vue:81
+#: front/src/views/admin/users/Base.vue:5 src/views/admin/users/UsersList.vue:3
+#: front/src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:36
+msgid "Users"
+msgstr "Users"
+
+#: front/src/components/Footer.vue:29
+msgid "Using Funkwhale"
+msgstr "Using Funkwhale"
+
+#: front/src/components/Footer.vue:13
+msgid "Version %{version}"
+msgstr "Version %{version}"
+
+#: front/src/views/content/libraries/Quota.vue:29
+#: front/src/views/content/libraries/Quota.vue:56
+#: front/src/views/content/libraries/Quota.vue:82
+msgid "View files"
+msgstr "View files"
+
+#: front/src/components/library/Album.vue:31 src/components/library/Artist.vue:35
+#: front/src/components/library/Track.vue:51
+#: front/src/components/metadata/ArtistCard.vue:49
+#: front/src/components/metadata/ReleaseCard.vue:53
+msgid "View on MusicBrainz"
+msgstr "View on MusicBrainz"
+
+#: front/src/views/content/libraries/Form.vue:18
+msgid "Visibility"
+msgstr "Visibility"
+
+#: front/src/views/content/libraries/Card.vue:59
+msgid "Visibility: everyone on this instance"
+msgstr "Visibility: everyone on this instance"
+
+#: front/src/views/content/libraries/Card.vue:60
+msgid "Visibility: everyone, including other instances"
+msgstr "Visibility: everyone, including other instances"
+
+#: front/src/views/content/libraries/Card.vue:58
+msgid "Visibility: nobody except me"
+msgstr "Visibility: nobody except me"
+
+#: front/src/components/library/Album.vue:61
+msgid "Volume %{ number }"
+msgstr "Volume %{ number }"
+
+#: front/src/components/playlists/PlaylistModal.vue:20
+msgid "We cannot add the track to a playlist"
+msgstr "We cannot add the track to a playlist"
+
+#: front/src/components/playlists/Form.vue:14
+msgid "We cannot create the playlist"
+msgstr "We cannot create the playlist"
+
+#: front/src/components/auth/Signup.vue:13
+msgid "We cannot create your account"
+msgstr "We cannot create your account"
+
+#: front/src/components/audio/Player.vue:64
+msgid "We cannot load this track"
+msgstr "We cannot load this track"
+
+#: front/src/components/auth/Login.vue:7
+msgid "We cannot log you in"
+msgstr "We cannot log you in"
+
+#: front/src/components/auth/Settings.vue:38
+msgid "We cannot save your avatar"
+msgstr "We cannot save your avatar"
+
+#: front/src/components/auth/Settings.vue:14
+msgid "We cannot save your settings"
+msgstr "We cannot save your settings"
+
+#: front/src/components/Home.vue:127
+msgid "We do not track you or bother you with ads"
+msgstr "We do not track you or bother you with ads"
+
+#: front/src/components/library/Track.vue:95
+msgid "We don't have any copyright information for this track"
+msgstr "We don't have any copyright information for this track"
+
+#: front/src/components/library/Track.vue:106
+msgid "We don't have any licensing information for this track"
+msgstr "We don't have any licensing information for this track"
+
+#: front/src/components/library/FileUpload.vue:40
+msgid "We recommend using Picard for that purpose."
+msgstr "We recommend using Picard for that purpose."
+
+#: front/src/components/Home.vue:7
+msgid "We think listening to music should be simple."
+msgstr "We think listening to music should be simple."
+
+#: front/src/components/PageNotFound.vue:10
+msgid "We're sorry, the page you asked for does not exist:"
+msgstr "We're sorry, the page you asked for does not exist:"
+
+#: front/src/components/Home.vue:153
+msgid "Welcome"
+msgstr "Welcome"
+
+#: front/src/components/Home.vue:5
+msgid "Welcome on Funkwhale"
+msgstr "Welcome to Funkwhale"
+
+#: front/src/components/Home.vue:24
+msgid "Why funkwhale?"
+msgstr "Why funkwhale?"
+
+#: front/src/components/audio/EmbedWizard.vue:13
+msgid "Widget height"
+msgstr "Widget height"
+
+#: front/src/components/audio/EmbedWizard.vue:6
+msgid "Widget width"
+msgstr "Widget width"
+
+#: front/src/components/Sidebar.vue:118
+#: front/src/components/manage/moderation/AccountsTable.vue:72
+#: front/src/components/manage/moderation/DomainsTable.vue:58
+msgid "Yes"
+msgstr "Yes"
+
+#: front/src/components/auth/Logout.vue:8
+msgid "Yes, log me out!"
+msgstr "Yes, log me out!"
+
+#: front/src/views/content/libraries/Form.vue:19
+msgid "You are able to share your library with other people, regardless of its visibility."
+msgstr ""
+"You are able to share your library with other people, regardless of its "
+"visibility."
+
+#: front/src/components/library/FileUpload.vue:33
+msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
+msgstr ""
+"You are about to upload music to your library. Before proceeding, please "
+"ensure that:"
+
+#: front/src/components/auth/Logout.vue:7
+msgid "You are currently logged in as %{ username }"
+msgstr "You are currently logged in as %{ username }"
+
+#: front/src/views/content/Home.vue:17
+msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
+msgstr ""
+"You can follow libraries from other users to get access to new music. Public "
+"libraries can be followed immediately, while following a private library "
+"requires approval from its owner."
+
+#: front/src/components/Home.vue:133
+msgid "You can invite friends and family to your instance so they can enjoy your music"
+msgstr ""
+"You can invite friends and family to your instance so they can enjoy your "
+"music"
+
+#: front/src/views/auth/EmailConfirm.vue:24
+msgid "You can now use the service without limitations."
+msgstr "You can now use the service without limitations."
+
+#: front/src/components/library/radios/Builder.vue:7
+msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
+msgstr ""
+"You can use this interface to build your own custom radio, which will play "
+"tracks according to your criteria."
+
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
+msgstr ""
+"You can use those to enjoy your playlist and music in offline mode, on your "
+"smartphone or tablet, for instance."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:46
+msgid "You don't have any rule in place for this account."
+msgstr "You don't have any rule in place for this account."
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgid "You don't have any rule in place for this domain."
+msgstr "You don't have any rule in place for this domain."
+
+#: front/src/components/Sidebar.vue:158
+msgid "You have a radio playing"
+msgstr "You have a radio playing"
+
+#: front/src/components/audio/Player.vue:71
+msgid "You may have a connectivity issue."
+msgstr "You may have a connectivity issue."
+
+#: front/src/App.vue:17
+msgid "You need to select an instance in order to continue"
+msgstr "You need to select an instance in order to continue"
+
+#: front/src/components/auth/Settings.vue:99
+msgid "You will be logged out from this session and have to log in with the new one"
+msgstr ""
+"You will be logged out from this session and have to log in with the new one"
+
+#: front/src/components/auth/Settings.vue:70
+msgid "You will have to update your password on your clients that use this password."
+msgstr ""
+"You will have to update your password on your clients that use this password."
+
+#: front/src/components/favorites/List.vue:115
+msgid "Your Favorites"
+msgstr "Your Favourites"
+
+#: front/src/components/Home.vue:114
+msgid "Your music, your way"
+msgstr "Your music, your way"
+
+#: front/src/views/Notifications.vue:7
+msgid "Your notifications"
+msgstr "Your notifications"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:29
+msgid "Your password has been updated successfully."
+msgstr "Your password has been updated successfully."
+
+#: front/src/components/auth/Settings.vue:100
+msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
+msgstr ""
+"Your Subsonic password will be changed to a new, random one, logging you out "
+"from devices that used the old Subsonic password"
diff --git a/front/locales/eo/LC_MESSAGES/app.po b/front/locales/eo/LC_MESSAGES/app.po
index 18fcb5a7e73e47835782c1e17ffb7d9128f4026c..360e6a23796b60c774f3f5baf2c301d696205d6d 100644
--- a/front/locales/eo/LC_MESSAGES/app.po
+++ b/front/locales/eo/LC_MESSAGES/app.po
@@ -7,9 +7,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-20 10:50+0000\n"
-"Last-Translator: Elza Gelez <elza@gelez.xyz>\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-03-19 16:47+0000\n"
+"Last-Translator: Mélanie Chauvel <perso@hack-libre.org>\n"
 "Language-Team: none\n"
 "Language: eo\n"
 "MIME-Version: 1.0\n"
@@ -19,1867 +19,3243 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{title}\" je %{artist}"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{index} da %{length})"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(malplena)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Ensaluti en via Funkwhale konto"
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
-msgstr[0] "Unu el %{total} estas selekta"
-msgstr[1] "%{count} el %{total} estas selektaj"
-
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+msgstr[0] "Unu el %{ total } estas selektita"
+msgstr[1] "%{ count } el %{ total } estas selektitaj"
+
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
-msgstr[0] "%{count} kanto"
-msgstr[1] "%{count} kantoj"
+msgstr[0] "%{ count } kanto"
+msgstr[1] "%{ count } kantoj"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
-msgstr[0] "%{count} kanto en %{albumsCount} albumo"
-msgstr[1] "%{count} kantoj en %{albumsCount} albumoj"
+msgstr[0] "%{ count } kanto en %{ albumsCount } albumo"
+msgstr[1] "%{ count } kantoj en %{ albumsCount } albumoj"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{count} kanto kongruas kun la tutaj filtriloj"
 msgstr[1] "%{count} kantoj kongruas kun la tutaj filtriloj"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "Aldonis unu kanto al atendovico"
-msgstr[1] "Aldonis %{ count }kantoj al atendovico"
-
 #: front/src/components/playlists/Card.vue:18
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
-msgstr[0] "%{count} kanto"
-msgstr[1] "%{count} kantoj"
+msgstr[0] "%{ count } kanto"
+msgstr[1] "%{ count } kantoj"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{current} uzantas el %{max} rajtantas"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{hours} h %{minutes} min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{minutes} min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
 msgstr "%{ username } akceptis vian sekvadon de muzikejo \"%{ library }\""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr "%{ username } sekvis vian muzikejon \"%{ library }\""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } volas sekvi vian muzikejon “%{ library }”"
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Profilo de %{username}"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">Pri "
-"%{instanceName}</translate>"
 
 #: front/src/components/audio/artist/Card.vue:41
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "Unu albumo"
-msgstr[1] "%{count} albumoj"
+msgstr[1] "%{ count } albumoj"
 
 #: front/src/components/favorites/List.vue:10
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "Unu stelumo"
-msgstr[1] "%{count} stelumoj"
+msgstr[1] "%{ count } stelumoj"
+
+#: front/src/components/Home.vue:64
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Orda muzikejo"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
-msgstr "Eraro okazis dum alŝuto de tiu dosiero"
+msgstr "Reta eraro okazis dum alŝuto de tiu dosiero"
+
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Mallonga resumo priskribante viaj ŝanĝoj"
 
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "Pri %{instance}"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "Pri %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "Pri Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Pripaĝo"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
-msgstr "Pri tiu instanco"
+msgstr "Pri ĉi tiu instanco"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Akcepti"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
-msgstr "akceptanta"
+msgstr "Akceptita"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Atingo malaktivigas"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Elekti filtrilon"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Atingo malaktivigas"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Aldoni al stelumoj"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Viaj sciigoj"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Aldoni al ludlisto…"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Atingo malaktivigas"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
 msgstr "Atingas vian muzikon kun pura interfaco ke koncentras ĝin sur gravaĵo"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "Atingdato"
+msgstr "Atingo malaktivigas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Kontoj"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Kontoj"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Kontdatumo"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Preferoj de via konto"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Preferoj de via konto"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
-msgstr "Pozicio de via konto"
+msgstr "Konta statuso"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
-msgstr "Retadreso de via konto"
+msgstr "Konta retadreso"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+#, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Kontoj"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Ago"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
-msgstr[0] "Ago %{action} sukcese komenciĝis por %{count} ero"
-msgstr[1] "Ago %{action} sukcese komenciĝis por %{count} eroj"
+msgstr[0] "Ago %{ action } sukcese komenciĝis por %{ count } ero"
+msgstr[1] "Agoj %{ action } sukcese komenciĝis por %{ count } eroj"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Agoj"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Aktiva"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Aktivo"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
-msgstr "Videblo de Akto"
+msgstr "Videblo de Aktivo"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Aldoni"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Aldoni domajnon"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Aldoni moderecan regulon"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Aldoni novan moderecan regulon"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Aldoni kaj administri datumoj"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
-msgstr "Aldoni muzikon"
+msgstr "Aldoni enhavon"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
-msgstr "Aldoni filtrilo"
+msgstr "Aldoni filtrilon"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
-msgstr "Aldonu filtriloj por agordi vian radion"
+msgstr "Aldonu filtrilojn por tajlori vian radion"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Aldoni al aktuala atendovico"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Aldoni al stelumoj"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Aldoni al ludlisto…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Aldoni al atendovico"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
-msgstr "Aldoni al tiu ludlisto"
+msgstr "Aldoni al ĉi tiu ludlisto"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Aldoni kanton"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Administranto"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administrejo"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Albumo"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Albumo kun %{count} kanto, je %{artist}"
-msgstr[1] "Albumo kun %{count} kantoj, je %{artist}"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Albumo"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
-msgstr "Albumnomo"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Albumoj je ĉi-tiu artisto"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
+msgstr "Nomo de albumo"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Albumpagô"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Nomo de albumo"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Albumoj"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Albumoj je ĉi-tiu artisto"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Ĉia"
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "Ĉiu %{ count } ero estas selekta"
+msgstr[1] "Ĉiuj %{ count } eroj estas selektaj"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
-msgstr "Eraro okazis kiam konservi viajn ŝanĝojn"
+msgstr "Eraro okazis dum konservo de viaj ŝanĝoj"
+
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Eraro okazis dum konservo de viaj ŝanĝoj"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Eraro okazis dum konservo de viaj ŝanĝoj"
 
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Nekonata eraro okazis, povus signifi ke la servilo paneas aÅ­ ne estas atingebla"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Ago"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "Akcepti"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+#, fuzzy
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Akceptita"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr "Akceptita kaj aplikita"
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Ĉu vi vere volas elsaluti?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artisto"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artisto"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Nomo de artisto"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Artistpaĝo"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Nomo de artisto"
 
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artisto, albumo, kanto…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artistoj"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artistoj"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "Foste"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Demandi pasvortrenuligadon"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Muzika datumo"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Fulmoklavoj de muzika ludilo"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Disponeblaj ludlistoj"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avataro"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Reiri al ensalutpaĝo"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Äœisdati agordojn"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Bitrapido"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "Bloki ĉiu"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"Bloki ĉiu el tiu konto aŭ domajno. Preventos interagojn kaj malaperigis ĝian "
-"datumon (dosieroj, muzikejoj, sekvadoj…)"
+msgstr "Bloki ĉiu el tiu konto aŭ domajno. Preventos interagojn kaj malaperigis ĝian datumon (dosieroj, muzikejoj, sekvadoj…)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Folii"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Folii muzikejon"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Folii radiojn"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Folii artistojn"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Folii ludlistojn"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Folii radiojn"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Konstruilo"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "Je %{artist}"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr "Se vi malsekvantus tiun muzikejon, vi perdus ĝian muzikon."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr "Kaŝmemora grando"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Nuligi"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Kandidatoj"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Ne eblas ŝanĝi vian pasvorton"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "Ne povis alŝuti tiun dosieron, certigi ne tro grandas"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Ŝanĝi lingvon"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Ŝanĝi mian pasvorton"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Ŝanĝi pasvorton"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Ŝanĝi vian pasvorton"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Ĉu vi volas ŝanĝi vian pasvorton?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Konservis ŝanĝoj"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Ŝanĝi vian pasvorton ankaŭ ŝanĝos vian Subsonic API pasvorto se vi petis tiun."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "Ŝanĝi vian pasvorton tiel rezultigos"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Babilejo"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Elekti vian instanco"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Purigi muzikejon"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Purigi"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Purigi"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Purigi ludliston"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Purigi vian atendovico"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Alklaki unu foje, aÅ­skulti enkonstruitajn radiojn dum horoj"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Alklaki por selekti elŝutontaj dosieroj, aŭ ŝovi kaj demeti dosierojn aŭ dosierujojn"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
 msgid "Close"
 msgstr "Fermi"
 
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+#, fuzzy
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close"
+msgstr "Fermi"
+
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Kodo"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Malgrandigi"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Preferoj"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Konfirmi"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Konfirmi vian retadreson"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Konfirmada kodo"
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Elekti filtrilon"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Elekti filtrilon"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
 msgstr "Äœisdatigis datumon, alklaku aktualigi por vidi novan datumon"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Kontribui"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Kopii"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
 msgstr "Kopii kantojn el la aktuala atendovico en tiu ludlisto"
 
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
+
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr "Kopi kaj alglui tiun kodon en via retejo"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Kopirajto"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Ne povis konfirmi vian retadreson"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Eraro dum skano de malloka muzikejo"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr "Ne povis traktadi tiun kanton, certiĝi ĝi estas bone etikedata"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Reludversioj, kantparoloj, nian celon estas havi ĉiujn ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Krei"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Krei Funkwhale konton"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Krei novan ludliston"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Krei novan ludliston"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Krei novan muzikejon"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Krei novan ludliston"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Krei konton"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Krei ludliston"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Krei muzikejon"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Kreu mian konton"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Krei ludliston"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Krei vian propran radion"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Kreodato"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Aktuala avataro"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Aktuala muzikejo"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Aktuala kanto"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Aktuala uzo"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Dato"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Kantodatumo"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Malgrandigi volumo"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Forigi"
 
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Forigi ludliston"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Forigi muzikejon"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Forigi moderecan regulon"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Forigi ludliston"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Forigi radion"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Forigi tiun muzikejon?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Forigi tiun muzikejon?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Forigi tiun muzikejon?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Forigi tiun moderecan regulon?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Forigi tiun moderecan regulon?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Forigi tiun muzikejon?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Malfoste"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Resumo"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Detalo"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Resumo"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Detaloj"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
-msgstr ""
-"Kiom da datumo la uzanto povas elŝuti. Lasi malplene por uzi la defaŭlta "
-"valoro de la instanco."
+msgstr "Kiom da datumo la uzanto povas elŝuti. Lasi malplene por uzi la defaŭlta valoro de la instanco."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Kiu estas la videblo de viaj aktoj"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Malatingeblu"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Malatingeblu Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Ĉu vi volas malatingeblu la Subsonic API?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Malaktiva"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Malkovri kiel vi povas uzi Funkwhale el aliaj aplikaĵoj"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Afiŝata nomo"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Publike montri"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Neniam alŝuti aŭdovidaĵojn (muzikoj, albumbildoj, avataroj…) el tiu konto aŭ "
-"domajno. AnkaÅ­ forigos aktualajn datumojn."
+msgstr "Neniam alŝuti aŭdovidaĵojn (muzikoj, albumbildoj, avataroj…) el tiu konto aŭ domajno. Ankaŭ forigos aktualajn datumojn."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Ĉu vi volas purigi la \"%{playlist}\" ludliston?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Ĉu vi volas konfirmi tiun akton?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Ĉu vi volas forigi la \"%{playlist}\" ludliston?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Ĉu vi volas forigi la \"%{radio}\" radion?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Ĉu vi volas forigi la \"%{radio}\" radion?"
+
+#: front/src/components/common/ActionTable.vue:37
+#, fuzzy
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Ĉu vi volas komenci %{action} por %{count} ero?"
 msgstr[1] "Ĉu vi volas komenci %{action} por %{count} eroj?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Ĉu vi volas reŝargi vian antaŭan atendovicon?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Dokumentaro"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Domajno"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Domajnoj"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Elŝuti"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Treni kaj guti horizontaloj por reordigi kantojn en la ludlisto"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "DaÅ­ro"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Konfirmintas retadreson"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Facila uzo"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Redakti"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Redakti"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Eraro kiam ruli akton"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Redakti informoj de instanco"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Redakti…"
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Äœisdati moderecan regulon"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Ludi tiun kanton"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Ludi tiun kanton"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Ludi tiun kanton"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Redakti"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Redakti"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Retmesaĝo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Retadreso"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Enkorpigi"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "Enkorpiga kodo"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr "Enkorpigi tiun albumon en via retejo"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+#, fuzzy
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Enkorpigi tiun kanton en via retejo"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "Enkorpigi tiun kanton en via retejo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr "Sendintaj sekvadoj de muzikejo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr "Sendintaj mesaĝoj"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "Aktiva"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Fini redakto"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Tajpu retadreson de muzikejo"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Tajpu nomon de radio…"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Tajpu nomon de artisto…"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Tajpu nomon de ludlisto…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+#, fuzzy
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Tajpu la retadreson bindanta al via konto"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Tajpu vian retadreson"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Tajpu vian invitkodon (usklecoblindan)"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Tajpu vian serĉon…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Tajpu vian uzantnomon"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Tajpu vian uzantnomon aÅ­ retadreson"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Eraro"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Eraroraportado"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Eraroraportado"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Eraris"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Eraro kiam ruli akton"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Eraro kiam demandi renuligadon de pasvorto"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Eraro kiam ruli akton"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Eraro kiam ŝanĝi vian pasvorton"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Eraro kiam krei domajnon"
 
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Eraro kiam krei regulon"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Eraro kiam krei inviton"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Eraro kiam krei regulon"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Eraro kiam krei inviton"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Eraro dum skano de malloka instanco"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Eraro kiam konservi preferojn"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Eraro kiam konservi preferojn"
+
+#: front/src/components/library/EditForm.vue:46
+#, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Eraro kiam konservi preferojn"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Eraris"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Erarintaj dosieroj"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Ĉiu"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Ĉiu en ĉi-tiu instanco"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+#, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Ĉiu en ĉiuj instancoj"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Ekskluzivi"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Fortempiĝa dato"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Fortempiĝis"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Fortempiĝis aŭ uzantiĝis"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
-"Ekspliku kial vi aplikas tiun regularon. Depende de la preferado de via "
-"instanco, ĝi helpos vin memori kial vi agis sur tiu konto aŭ domajno, kaj "
-"povus esti afiŝa por helpi uzantoj kompreni kiuj moderecaj reguloj ekzistas."
+msgstr "Ekspliku kial vi aplikas tiun regularon. Depende de la preferado de via instanco, ĝi helpos vin memori kial vi agis sur tiu konto aŭ domajno, kaj povus esti afiŝa por helpi uzantoj kompreni kiuj moderecaj reguloj ekzistas."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "Eraris"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Erarintaj kantoj:"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Erarintaj kantoj:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Stelumoj"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Stelumoj"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federo"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Federo"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Dosiernomo"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Dosieroj"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Filtri nomon"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Finanto"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr "Unua vido"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Dato de unua vido"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Sekvi"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Sekvi mallokajn muzikejojn"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Peto da sekvado atendanta konsenton"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
 msgid "Followers"
 msgstr "Sekvantoj"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Followers"
+msgstr "Sekvantoj"
+
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Sekvata"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "El %{album} albumo je %{artist}"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Sekvi"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Malatingeblu"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale funkcias kun aliaj muzikludiloj ke apogas la Subsonic API."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Uzi Funkwhale facilegas."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale estas dizajna tiel ke estas facile aŭskulti muzikon vi ŝatas, aŭ malkovri novajn artistojn."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale estas senpaga kaj lasis vin estri vian muzikon."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale atentas manipuli vian muzikon"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "Generalaj fulmoklavoj"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Akiri novan inviton"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Iru al la muzikejo"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
-msgstr ""
-"Akiri kvalitaj metadatumoj pri vian muzikon kun <a href=\"%{url}\" target=\""
-"_blank\">MusicBrainz</a>"
+msgstr "Akiri kvalitaj metadatumoj pri vian muzikon kun <a href=\"%{url}\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Komencu"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Ricevi helpon"
+
 #: front/src/components/Footer.vue:37
+#, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "Ricevi helpon"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Komenci"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Iru hejme"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Folii artistojn"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr "Kaŝi konton aŭ domajnon, krom sekvantoj."
 
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Aldoni muzikon"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr ""
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Hejmo"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Muzikhoroj"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Tamen, atingi Funkwhale el tiuj aplikaĵo bezonas alian pasvorton ke vi povas difini malsupre."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Se la retadreso provizanta dum la antaŭa etapo korektas kaj bindas al uzantkonto, vi baldaŭ ricevus retmesaĝon kun renuligadaj instrukcioj."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Importdato"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importi muzikon el multe da servicoj, kiel YouTube aÅ­ SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Importstato"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Importfonto"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Importstato"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+#, fuzzy
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "Importstato"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importinta"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Importdato"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
+#, fuzzy
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Novaj aldonoj"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "En stelumoj"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Malaktiva"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "Pliigi volumon"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Tajpu la retadreson bindanta al via konto"
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Internigi el atendovico (unu kanto)"
 msgstr[1] "Internigi el atendovico (%{count} kantoj)"
 
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Instanca datumo"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Instanca datumo"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Instanca informo"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Instancaj radioj"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Instancaj preferoj"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Instanca datumo"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr "Malbona dosiertipo, aserti ĝi estas aŭda dosiero. %{ extensions } funkcias"
+
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
-"Malbona dosiertipo, aserti ĝi estas aŭda dosiero. %{ extensions } funkcias"
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Invita kodo"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Invita kodo (nedeviga)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Invitoj"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Cimspuradilo"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Konservi postsignojn de viaj preferitaj kantoj"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr "Fulmoklavo"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Konataj kontoj"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Konataj muzikejoj"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Lasta akto"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "Lasta kontrolado"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Lasta redakto"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "Lasta vidanto"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Dato de lasta vido"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Lasta ĝisdatigo:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Lanĉi"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Lerni pli pri tiu instanco"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Lasu malplena por hazarda kodo"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Lasu malplena por adaptiĝema fenestraĵo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Muzikejoj"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Muzikejoj"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Äœisdatigas muzikejon"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "Muzikejoj helpas vin organizi kaj diskonigi viajn muzikarojn. Vi povas elŝuti vian propran muzikaron je Funkwhale kaj diskonigi ĝin kun viajn amikojn kaj familio."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Muzikejo"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Kreis muzikejon"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Äœisdatigas muzikejon"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Forigis muzikejon"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "Muzikejaj dosieroj"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Äœisdatigas muzikejon"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "Permesilo"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+#, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Ŝargas sekvantojn…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Ŝargas sekvantojn…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Ŝarĝas muzikejojn…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Ŝargas datumon de muzikejo…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Ŝarĝas sciigojn…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
 msgstr "Ŝargas mallokajn muzikejojn…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Ŝarĝas uzdatumon…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Ŝarĝas viajn stelumojn…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+#, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Loka konto"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Ensaluti"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Ensaluti en via Funkwhale konto"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Elsaluti"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Elsuta je %{username}"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Ensaluti"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Stato de konektado"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Elsaluti"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
 msgstr "Åœajni ke vi ne jam havas muzikejon, kreu unu."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Ripeto malaktivas. Alklaki por aktivi ripetado de la aktuala kanto."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Ripetas unu kanton. Alklaki por aktivi ripetado de la tutan atendovico."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Ripetas la tutan atendovicon. Alklaki por malaktivi ripeto."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Teksto"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "Precipa menuo"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Administri muzikejon"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Manipuli ludlistojn"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Manipuli uzantojn"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Manipuli viajn ludlistojn"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Marki ĉiujn legata"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Marki legata"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Marki mallegata"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "Mb"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr "AÅ­dilo"
 
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Aligis je %{date}"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "Poŝkomputilaj kaj komputilaj aplikaĵoj"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+#, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Modereco"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
-"Moderecaj regularoj helpas vin kontroli kial via instanco interagis kun "
-"domajnon aÅ­ konton."
+msgstr "Moderecaj regularoj helpas vin kontroli kial via instanco interagis kun domajnon aÅ­ konton."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Modifdato"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Modifdato"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Muziko"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Silentigi"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Lasta akto"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Viaj sciigoj"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Mia konto"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Mia mojosa priskribo"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Mia mojosa muzikejo"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "Mia mojosa ludlisto"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Mia mojosa radio"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Miaj muzikejoj"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "ND"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nomo"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nomo"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nomo"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nova pasvorto"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Novaj kantoj estos aldonataj ĉi-tie aŭtomate."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "BaldaÅ­a kanto"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Ne"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Nek aldonaĵoj, nek kromprogramoj: vi nur bezonas retmuzikejo"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Neniom albumo kongruas kun via serĉo"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Neniom artisto kongruas kun via serĉo"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "Nenio teksto disponeblas por tiu kanto."
 
+#: front/src/components/library/TrackDetail.vue:25
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Ni havas nenia licenca informado pri tiu kanto"
+
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Neniu muzikejo korespondas."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
 msgstr "Nenio sciigoj jam."
 
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr ""
+
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Neniu krom mi"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Neniu sekvas tiun muzikejon"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Ne uzantata"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Sciigoj"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Sciigoj"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Oficiala retejo"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Malnova pasvorto"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Malferma"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Äœisdati moderecan regulon"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Malfermi profilon"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Vidi en MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "Malfermi profilon"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Malfermi profilon"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Malfermi retejon"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "AÅ­ agordi vian regulon"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Ordo"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Ordo"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Orda direkto"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Proprietulo"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Maltrovita paĝo"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Maltrovitas paĝon!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr "Paĝeco"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Pasvorto"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Pasvorto aktuliginta"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Pasvorto sukcese aktualiginta"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "PaÅ­zi kanton"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr "PaÅ­zi/ludi la aktualan kanton"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "PaÅ­za"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "Atendas"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Atendas aprobon"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Atendantaj dosieroj"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Atendantaj petoj da sekvado"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Atendantaj dosieroj"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Atendantaj dosieroj"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Rajtoj"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Rajtoj"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Ludi"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Ludi ĉiu"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Ludi ĉiuj albumoj"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Ludi baldaÅ­e"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Ludi sekvan kanton"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Ludi tuj"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Ludi antaÅ­a kanto"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Ludi tiun kanton"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Ludi kanton"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Ludi…"
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Ludlisto"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Ludisto enhavanta unu kanto, je %{username}"
 msgstr[1] "Ludisto enhavanta %{count} kantoj, je %{username}"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Ludlisto kreiintas"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Ludlista redaktilo"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nomo de la ludlisto"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Ludlisto aktualigintas"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Ludlistvideblo"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Ludlistoj"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Ludlistoj"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "Ludlistoj? Jen"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Bonvolu rekontroli ke via pasvorto ĝustas"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Bonvolu rekontroli ke vian uzantnomo kaj pasvorto ĝustas"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF, aŭ JPG. Maksimume 2Mo. La bildo malgrandigos al 400×400 rastrumero."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Paĝeco"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
 msgstr "Preventi konton aÅ­ domajno de sendi sciigoj, krom el sekvantoj."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "AntaÅ­vido"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "AntaÅ­a kanto"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Eraro dum skano"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Konfirmi"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Ensalutu"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Procedas"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Malfermi profilon"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1888,1100 +3264,1973 @@ msgstr "Procedas"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Purigi"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Purigi erarajn dosierojn?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Purigi atendantajn dosierojn?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Purigi ignoratajn dosierojn?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Atendovico"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "Atendovico miksiĝis!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Faranto de radio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Kreis radion"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nomo de la radio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Äœisdatigas radion"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radioj"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radioj"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr "Kialo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr "Ricevintaj sekvadoj de muzikejo"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "Ricevintaj mesaĝoj"
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Novaj aldonoj"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Novaj aldonoj"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Novaj stelumoj"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Lastatempaj aÅ­skultantoj"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Äœisdatigi"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Äœisdatigi"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr "Aktualigi instancinformon"
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Aktualigi instancinformon"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "Aktualiĝi datumon de tabelo"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Aligis je %{date}"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "Registrigadoj fermitas je tiu instanco, vi bezonos invitkodon por registrigi."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "normala uzanto"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Malakcepti"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Malakcepti aŭdovidaĵon"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Malakceptinta"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Rekomenci importadon"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Dato de lasta vido"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Mallokaj muzikejoj"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Mallokaj muzikejoj apartenas al aliaj uzantoj el la reto. Vi povas atingi ilin se ili estas publika aÅ­ vi estas akceptinta."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Forigi"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Forigi profilbildon"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Forigi profilbildon"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Forigi el stelumoj"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
-"Forigas elŝutatajn sed jam procezontajn kantojn, aldonante tiu datumo al via "
-"kvoto."
+msgstr "Forigas elŝutatajn sed jam procezontajn kantojn, aldonante tiu datumo al via kvoto."
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
-"Forigas elŝutatajn preterlasinta kantojn, aldonante tiu datumo al via kvoto."
+msgstr "Forigas elŝutatajn preterlasinta kantojn, aldonante tiu datumo al via kvoto."
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr ""
-"Forigas elŝutatajn kantojn ke la servilo ne povis procezi, aldonante tiu "
-"datumo al via kvoto."
+msgstr "Forigas elŝutatajn kantojn ke la servilo ne povis procezi, aldonante tiu datumo al via kvoto."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Demandi novan pasvorton"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Demandi novan Subsonic API pasvorton?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Demandi pasvorton"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Renuligadi vian pasvorton"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Rekomenci importadon"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Rezultoj per paĝo"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Reiru al ensalutpaĝo"
 
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Vidi dosierojn"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "Regulo"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Konservi"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Skano komencis"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Skani nun"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Foste"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Preterlasis skanon (antaÅ­a skano tro junas)"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "Skano atendas"
-
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Skana"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Malsukcese skanis"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Skanas… (%{progress}%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Serĉi"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Serĉi mallokan muzikejon"
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Serĉu per titolo, artisto, domajno…"
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Serĉu per domajno, uzantnomo, biografio…"
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Serĉu per domajno, uzantnomo, biografio…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Serĉu per domajno, uzantnomo, biografio…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Serĉu per titolo, artisto, albumo…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Serĉu per titolo, artisto, albumo…"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
 msgstr "Serĉu per domajno, uzantnomo, biografio…"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
 msgstr "Serĉu per nomo…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
 msgstr "Serĉu per titolo, artisto, albumo…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "Serĉu per titolo, artisto, domajno…"
-
 #: front/src/components/manage/users/InvitationsTable.vue:153
+#, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Serĉu per uzantnomo, retpoŝtdreso, kodo…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Serĉu per uzantnomo, retpoŝtadreso, nomo…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Serĉu artistoj, albumoj, kantoj…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Serĉi muzikon"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Serĉi je lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Serĉi je Vikipedio"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr "Dua menuo"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Sekcioj"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Elekti filtrilon"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "Elekti unu eron"
 msgstr[1] "Elekti ĉiun la %{total} erojn"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Elekti nur la aktualan uzon"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Agordoj"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Agordoj ĝisdatigas"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Agordoj sukcese ĝisdatigas."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Diskonigi ligilon"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"Diskonigu tiu ligilo kun aliaj uzantoj, do ili povas peti atingon al via "
-"muzikejo."
+msgstr "Diskonigu tiu ligilo kun aliaj uzantoj, do ili povas peti atingon al via muzikejo."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Diskoniga ligilo"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "Afiŝi %{count} kanto"
 msgstr[1] "Afŝi %{count} kantoj"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Afiŝi unu alian albumon"
 msgstr[1] "Afiŝi %{count} aliajn albumojn"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "Afiŝi disponeblajn fulmoklavojn"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Afiŝi mallegintajn sciigojn"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Afiŝi/kaŝi pasvorton"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Afiŝas rezultoj de %{start} al %{end} de %{total}"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Miksi atendocivo"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Miksi vian atendovico"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Registriĝi"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Registriĝi"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Registrada dato"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
-msgstr "Mutigi akto"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "Mutigi sciigojn"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+#, fuzzy
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Grando"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Grando"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Preterlasinta"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Preterlasintaj dosieroj"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "Aplikaĵo"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Pardonon, la paĝo vi petis ne ekzistas:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Fontkodo"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Skipano"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Komenci"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Stopi radion"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Statistikoj"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
-"Statistikoj estas kalkula el konata aktiveco kaj datumoj de via instanco, "
-"kaj ne kongruas la generalan aktivecon de tiu konto"
+msgstr "Statistikoj estas kalkula el konata aktiveco kaj datumoj de via instanco, kaj ne kongruas la generalan aktivecon de tiu konto"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
-"Statistikoj estas kalkula el konata aktiveco kaj datumoj de via instanco, "
-"kaj ne kongruas la generalan aktivecon de tiu domajno"
+msgstr "Statistikoj estas kalkula el konata aktiveco kaj datumoj de via instanco, kaj ne kongruas la generalan aktivecon de tiu domajno"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "Statistikoj estas kalkula el konata aktiveco kaj datumoj de via instanco, kaj ne kongruas la generalan aktivecon de tiu konto"
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Stato"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Stato"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Stato"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Stato"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Stato"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Stopi"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Stato"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Stopi radion"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Submeti"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsono"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Subsona API pasvorto"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Ni ne povis ŝargi tiun kanton"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Ni ne povis ŝargi tiun kanton"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Ni ne povis ŝargi tiun kanton"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Sugestaj elektoj"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Resumo"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "Helpretejo"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr "Funkcianta sufikso: %{extensions}"
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Sinkronigas ŝanĝojn al servilo…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Kopiis teksto al tondujo!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "Simplas: ni amis Grooveshark kaj ni volas konstrui iu plue bona."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "La emblemo de Funkwhale estis dizajni kaj disponigi je Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
 msgstr "La muzikejo kaj ĉiuj ĝiaj kantoj forigos. Ne povos malfari."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr "La muzika dosiero vi elŝutas bone etikedas:"
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
 msgstr "La sekva kanto ludos aŭtomate je kelkajn sekundoj…"
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
+msgstr "La platformo estas libera kaj malfermitkoda, vi povas instali ĝin malzorge"
+
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Ludlisto kreiintas"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Tiu akto ne estas malfaronta."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
 msgstr ""
-"La platformo estas libera kaj malfermitkoda, vi povas instali ĝin malzorge"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "La Subsona API ne disponeblas en tiu Funkwhale instanco."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Ni ne povas aldoni kanton al ludlisto"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Tiu akto ne estas malfaronta."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "La elŝutintaj muzikaj dosieroj estas OGG, Flac aŭ MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
 msgstr "Estas multe vojoj akiri novan datumon kaj aldoni ĉi-tie."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "Tiu akto ne estas malfaronta."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Tiu albumo estas en ĉi-tiuj muzikejoj:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Tiu artisto estas en ĉi-tiuj muzikejoj:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr "Tiu domajno havas specialajn moderecajn regulojn"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr "Tiu instanco oferi ĝis %{quota} de memorado per uzanto."
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "Estas vin!"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Tiu muzikejo enhavas mian personan muzikon, mi esperas vi ŝatas ĝin."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
-"Tiu muzikejo estas privata kaj vi bezonas akceptadon el ĝia proprulo por "
-"vidi ĝia enhavo"
+msgstr "Tiu muzikejo estas privata kaj vi bezonas akceptadon el ĝia proprulo por vidi ĝia enhavo"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
 msgstr "Tiu muzikejo estas publika do vi povas vidi ĝia enhavo libere"
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
+msgstr "Tiu efektus multe da ero aŭ havus malfarontajn konsekvencojn, bonvolu recertiĝi vi vere volas tiun."
+
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
 msgstr ""
-"Tiu efektus multe da ero aÅ­ havus malfarontajn konsekvencojn, bonvolu "
-"recertiĝi vi vere volas tiun."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Tiu referenco estus uzonta por grupigi importadajn dosierojn kune."
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Ne povis traktadi tiun kanton, certiĝi ĝi estas bone etikedata"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "Kanto elŝutanta, sed la servilo ne jam procezis ĝin"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "Kanto jam estas en unu de viaj muzikejoj"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
 msgstr "Tiu kanto ne disponeblas en iu aj muzikejo vi povas atingi"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Tiu kanto ne estas en ĉi-tiu muzikejoj:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Tute forigos tiun ludliston kaj ne povus esti malfaronta."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Tute forigos tiun radion kaj ne povus esti malfaronta."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Tute malaktivas atingo al la subsona API el tiu konto."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr "Forigos vian lokan datumon kaj elsalutos vin, ĉu vi volas kontinui?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Elsalutos vin el ĉiu viaj aparatoj ke uzas la aktualan pasvorton."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Tute forigos tiun ludliston kaj ne povus esti malfaronta."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Forigos ĉiujn kantojn el tiu ludlisto kaj ne povus esti malfaronta."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Titolo"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Title"
 msgstr "Titolo"
 
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr "Titolo"
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr "Baskuli ripetadon de la atendovico"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "Tuta grando"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Tuta grando de tiu muzikejo"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Tutaj uzantoj"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Kanto"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "Kanto jam estas en unu de viaj muzikejoj"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Kanto"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Nomo de kanto"
+
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Kantodatumo"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Kanto kongruanta filtrilo"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Nomo de kanto"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "Kanto elŝutanta, sed la servilo ne jam procezis ĝin"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Kantoj"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "kantoj"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Kantoj"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Kantoj je tiu artisto"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Stelumantaj kantoj"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "aÅ­skultintaj kantoj"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Kanto kongruanta filtrilo"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Tipo"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Tipo"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
 msgstr "Moderece"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Malsekvi"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Malsekvi tiun muzikejon?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "Malfeliĉe, proprulo de tiu instanco ne jam plenigis tiu paĝon."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Infinita muziko"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Malmutigi"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Äœisdati"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Äœisdati ludliston"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Äœisdati avataron"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Äœisdati muzikejon"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "Äœisdati moderecan regulon"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Äœisdati ludliston"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Äœisdati agordojn"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Äœisdati vian pasvorton"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Elŝuti"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Elŝuti novan avataron"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Elŝuti aŭdon"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Elŝutdato"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Elŝutdato"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "Malakcepti elŝuto, certiĝi la dosieron ne tro grandas kaj vi nur havas spaco"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
-"Malakcepti elŝuto, certiĝi la dosieron ne tro grandas kaj vi nur havas spaco"
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr ""
-"Elŝuti muzikajn dosierojn (MP3, OGG, FLAC, ktp.) el via persona muzika "
-"dosierujo direkte en via retumilo por ĝui ilin ĉi-tie."
+msgstr "Elŝuti muzikajn dosierojn (MP3, OGG, FLAC, ktp.) el via persona muzika dosierujo direkte en via retumilo por ĝui ilin ĉi-tie."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Elŝuti novajn kantojn"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Elŝutlimito"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Elŝuto tempolimis, bonvolu reprovi"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Elŝutinta"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Elŝutanta"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Elŝutanta…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Elŝutoj"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Elŝutoj"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "Elŝutoj"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Uzi alian instancon"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
-msgstr ""
-"Uzu tiun formularo por peti pasvortnuligado. Ni sendos retpoŝtmesaĝon kun "
-"instrukcioj por nuligi vian pasvorton."
+msgstr "Uzu tiun formularo por peti pasvortnuligado. Ni sendos retpoŝtmesaĝon kun instrukcioj por nuligi vian pasvorton."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
-"Uzu tiun agordon por tempe aktivigi/malaktivigi la regularon sen tute forigi "
-"ĝin."
+msgstr "Uzu tiun agordon por tempe aktivigi/malaktivigi la regularon sen tute forigi ĝin."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Uzinta"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Uzanto"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Uzanta aktivado"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Uzantaj muzikejoj"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Uzantaj radioj"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Uzantnomo"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Uzantnomo aŭ retpoŝtadreso"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "uzantoj"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Uzantoj"
 
 #: front/src/components/Footer.vue:29
+#, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "Uzi Funkwhale"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Versio %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Vidi dosierojn"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Vidi en MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Videblo"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Videblo: ĉiu en ĉi-tiu instanco"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Videblo: ĉiu, enhave aliaj instancoj"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Videblo: neniu krom mi"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Videblo"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr "Volumo %{number}"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Ni ne povas aldoni kanton al ludlisto"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Ni ne povis krei ludliston"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Ni ne povis krei vian konton"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "Ni ne povis ŝargi tiun kanton"
+#: front/src/components/federation/FetchButton.vue:69
+#, fuzzy
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Ŝarĝas viajn stelumojn…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Ni ne povis ensaluti vin"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Ni ne povis memori vian avataron"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Ni ne povis memori viajn agordojn"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Ni ne povis krei vian konton"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Ni ne spionas vin aŭ ĝenas vin kun reklamoj"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "Ni havas nenia kopirajta informado pri tiu kanto"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "Ni havas nenia licenca informado pri tiu kanto"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "Ni rekomendas Picard pro fari tiun."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Ni pensas ke aÅ­skulti muzikon devus simpli."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Pardonon, la paĝo vi petis ne ekzistas:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Bonvenon"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Bonvenon en Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Kial Funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "Alto de fenestraĵo"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "Larĝo de fenestraĵo"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Jes"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Jes, elsaluti min!"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
-msgstr ""
-"Vi povas diskonigi vian muzikejon kun aliaj uloj, sendepende ĝia videblo."
+msgstr "Vi povas diskonigi vian muzikejon kun aliaj uloj, sendepende ĝia videblo."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
+msgstr "Vi estas elŝutota muziko al via muzikejo. Antaŭ komenci, bonvolu certiĝi ke:"
+
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
 msgstr ""
-"Vi estas elŝutota muziko al via muzikejo. Antaŭ komenci, bonvolu certiĝi ke:"
 
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Vi aktuale estas ensaluta al %{username}"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
-msgstr ""
-"Vi povas sekvi muzikejoj el aliaj uzantoj por atingi novan muzikon. Publikaj "
-"muzikejoj sekvadeblas rekte, sed sekvado de privataj muzikejoj bezonas "
-"akceptado el ĝia proprulo."
+msgstr "Vi povas sekvi muzikejoj el aliaj uzantoj por atingi novan muzikon. Publikaj muzikejoj sekvadeblas rekte, sed sekvado de privataj muzikejoj bezonas akceptado el ĝia proprulo."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
+msgstr "Vi povas inviti amikojn kaj familio en via instanco do ili povas ĝui vian muzikon"
+
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
 msgstr ""
-"Vi povas inviti amikojn kaj familio en via instanco do ili povas ĝui vian "
-"muzikon"
 
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Vi nun povas uzi la servico senlime."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
-msgstr ""
-"Vi povas uzi tiun interfaco por konstrui viajn proprajn radiojn, ke ludos "
-"kantojn laÅ­ viaj reguloj."
+msgstr "Vi povas uzi tiun interfaco por konstrui viajn proprajn radiojn, ke ludos kantojn laÅ­ viaj reguloj."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
-msgstr ""
-"Vi povas uzi tiujn por ĝui vian muzikon kaj ludlistojn nekonektite, kun via "
-"poŝtelefono aŭ tabuleto ekzemple."
+msgstr "Vi povas uzi tiujn por ĝui vian muzikon kaj ludlistojn nekonektite, kun via poŝtelefono aŭ tabuleto ekzemple."
+
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Vi ne havas iu ajn regulon por tiu konto."
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Vi ne havas iu ajn regulon por tiu konto."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr "Vi ne havas iu ajn regulon por tiu konto."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr "Vi ne havas iu ajn regulon por tiu domajno."
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
+msgstr ""
+
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Vi ludas radion"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr "Vi havus konekta problemo."
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Vi devu elekti instanco por kontinui"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Vi estos elŝaluta el tiu seanco kaj devus ensaluti denove"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Vi devos rekte ŝanĝi vian pasvorton en la aplikaĵo ke uzas ĝin."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Ludlisto kreiintas"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Viaj sciigoj"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Viaj stelumoj"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "Via muziko, via vojo"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Viaj sciigoj"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Via pasvorto sukcese ŝanĝis."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Agordoj ĝisdatigas"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
-msgstr ""
-"Via Subsona pasvorto ŝanĝos hazarde, elsalutontas vin el aparetoj ke uzis la "
-"malnovan pasvorton"
+msgstr "Via Subsona pasvorto ŝanĝos hazarde, elsalutontas vin el aparetoj ke uzis la malnovan pasvorton"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Paĝeco"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Kopirajto"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Albumo kun %{count} kanto, je %{artist}"
+msgstr[1] "Albumo kun %{count} kantoj, je %{artist}"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "Aldonis unu kanto al atendovico"
+msgstr[1] "Aldonis %{ count }kantoj al atendovico"
diff --git a/front/locales/es/LC_MESSAGES/app.po b/front/locales/es/LC_MESSAGES/app.po
index 23a8832895e28560600ac3ae2fd8a436d0b95256..3f31090e08c2b0586877b2dc18b46df30493dc5e 100644
--- a/front/locales/es/LC_MESSAGES/app.po
+++ b/front/locales/es/LC_MESSAGES/app.po
@@ -7,9 +7,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-17 05:50+0000\n"
-"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-02-25 08:45+0000\n"
+"Last-Translator: Ale London <alelondon@gmail.com>\n"
 "Language-Team: none\n"
 "Language: es\n"
 "MIME-Version: 1.0\n"
@@ -19,162 +19,300 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\", por %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } de %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(vacío)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Iniciar sesión con tu cuenta de Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } de %{ total } elemento seleccionado"
 msgstr[1] "%{ count } de %{ total } elementos seleccionados"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } canción"
 msgstr[1] "%{ count } canciones"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+#, fuzzy
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } canción en %{ albumsCount } álbumes"
 msgstr[1] "%{ count } canciones en %{ albumsCount } álbumes"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } canción coincidiendo con filtros combinados"
 msgstr[1] "%{ count } canciones coincidiendo con filtros combinados"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "%{ count } canción ha sido añadida a tu cola de reproducción"
-msgstr[1] "%{ count } canciones han sido añadidas a tu cola de reproducción"
-
 #: front/src/components/playlists/Card.vue:18
+#, fuzzy
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} canción"
 msgstr[1] "%{ count } canciones"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ current } usados de %{ max } permitidos"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } h %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
-msgstr ""
+msgstr "%{ username } ha aceptado tu follow en la librería \"%{ library }\""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
-msgstr ""
+msgstr "%{ username } ha seguido tu librería \"%{ library }\""
+
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } quiere seguir tu librería \"%{ library }\""
 
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Perfil de %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
 
 #: front/src/components/audio/artist/Card.vue:41
+#, fuzzy
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 álbum"
 msgstr[1] "%{ count } álbumes"
 
 #: front/src/components/favorites/List.vue:10
+#, fuzzy
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 favorito"
 msgstr[1] "%{ count } favoritos"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+#, fuzzy
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Una biblioteca impecable"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Ha ocurrido un error al subir este archivo"
 
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Ha ocurrido un error al guardar los cambios"
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "Sobre %{ instance }"
 
 #: front/src/components/Footer.vue:6
-#, fuzzy
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "Sobre %{ instance }"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "Acerca de Funkwhale"
 
 #: front/src/components/Footer.vue:10
-#, fuzzy
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
-msgstr "Página del álbum"
+msgstr "Acerca de"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "Acerca de esta instancia"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Aceptar"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Aceptado"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Acceso deshabilitado"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
-msgstr "Accede a tu música con una interfaz limpia y concéntrate en lo que realmente importa"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Seleccionar un filtro"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Acceso deshabilitado"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Añadir a favoritos"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Silenciar notificaciones"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Añadir a lista de reproducción…"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Acceso deshabilitado"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr "Accede a tu música con una interfaz limpia enfocada a lo que realmente importa"
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "Fecha de acceso"
+msgstr "Acceso deshabilitado"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Cuentas"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
 #, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Cuentas"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
-msgstr "Cuenta activa"
+msgstr "Datos de cuenta"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Configuración de cuenta"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Configuración de Cuenta"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Estado de cuenta"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Correo de la cuenta"
 
@@ -182,1754 +320,2951 @@ msgstr "Correo de la cuenta"
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
 #, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
-msgstr "Estado de cuenta"
+msgstr "Cuentas"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Acción"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "Acción %{ action } fue iniciado exitosamente en %{ count } elemento"
 msgstr[1] "Acción %{ action } fue iniciado exitosamente en %{ count } elementos"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Acciones"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Activo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Actividad"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Mostrar mi actividad"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
-msgstr ""
+msgstr "Añadir"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
-msgstr ""
+msgstr "Añadir un dominio"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+#, fuzzy
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Añadir una nueva regla de moderación"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
-msgstr ""
+msgstr "Añadir una nueva regla de moderación"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Agregar y gestionar contenido"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Añadir contenido"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Añadir filtro"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Añade filtros para personalizar tu radio"
 
-#: front/src/components/audio/PlayButton.vue:64
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
-msgstr "Añadir a la cola de reproducción"
+msgstr "Añadir a la cola de reproducción actual"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Añadir a favoritos"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
-#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Añadir a lista de reproducción…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Añadir a la cola de reproducción"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Añadir a esta lista de reproducción"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Añadir canción"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Admin"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administración"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Álbum"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Álbum que contiene %{ count } canción, de %{ artist }"
-msgstr[1] "Álbum que contiene %{ count } canciones, de %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Álbum"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Álbumes de este artista"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "Álbum"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Página del álbum"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Álbum"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Álbumes"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Álbumes de este artista"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Todo"
 
+#: front/src/components/common/ActionTable.vue:59
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "%{ count } de %{ total } elemento seleccionado"
+msgstr[1] "%{ count } de %{ total } elementos seleccionados"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "Ha ocurrido un error al guardar los cambios"
 
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Ha ocurrido un error al guardar los cambios"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Ha ocurrido un error al guardar los cambios"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Ha ocurrido un error desconocido, esto puede significar que el servidor está fuera de servicio o no se puede conectar"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Acción"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
+msgstr "Aprobar"
+
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+#, fuzzy
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Aprobar"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
 msgstr ""
 
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "¿Seguro que quieres cerrar la sesión?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artista"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artista"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Nombre del artista"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Página del artista"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Nombre del artista"
 
 #: front/src/components/audio/Search.vue:65
-#, fuzzy
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artista, álbum, canción…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artistas"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artistas"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "Ascendente"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Restablecer contraseña"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
-#, fuzzy
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
-msgstr "Añadir contenido"
+msgstr "Contenido de Audio"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
+msgstr "Atajos de teclado del reproductor de Audio"
+
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Listas de reproducción disponibles"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Volver a la página de conección"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Actualizar ajustes"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Bitrate"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
-msgstr ""
+msgstr "Bloquear todo"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
+msgstr "Bloquear todo de esta cuenta o dominio. Ésto prevendrá cualquier interacción con la entidad, y eliminará los contenidos relacionados (subidas, librerías, follows, etc.)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Explorar"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Explorar biblioteca"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Explorando radios"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Explorando artistas"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Explorando listas de reproducción"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Explorando radios"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Editor"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "De %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr "Si dejas de seguir esta biblioteca, perderás acceso a su contenido."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
-msgstr ""
+msgstr "Tamaño en caché"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Cancelar"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Candidatos"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "No se puede cambiar la contraseña"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
-msgstr "Imposible subir este archivo, asegúrate que no es demasiado grande"
+msgstr "No es posible subir este archivo, asegúrate que no es demasiado grande"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Cambiar idioma"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Cambiar mi contraseña"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Cambiar contraseña"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Cambiar tu contraseña"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "¿Cambiar tu contraseña?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Cambios sincronizados con el servidor"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Cambiar tu contraseña también cambiará tu contraseña Subsonic API si pediste una."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "Cambiar tu contraseña tendrá las siguientes consecuencias"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
+msgstr "Sala Chat"
+
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
 msgstr ""
 
-#: front/src/App.vue:13
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Escoge tu instancia"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Una biblioteca impecable"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Limpiar"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Limpiar"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Vaciar lista de reproducción"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Vaciar cola de reproducción"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Pulsa una sola vez y escucha durante horas, gracias a las radios integradas"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Haz click para seleccionar archivos o arrastralos aquí para subirlos"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
 msgid "Close"
+msgstr "Cerrar"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+#, fuzzy
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close"
+msgstr "Cerrar"
+
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Código"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Contraer"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Configurar"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Confirmar"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
-#, fuzzy
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Confirma tu correo electrónico"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Código de confirmación"
 
-#: front/src/components/common/ActionTable.vue:7
-msgid "Content have been updated, click refresh to see up-to-date content"
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Seleccionar un filtro"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Seleccionar un filtro"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
 msgstr ""
 
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "El contenido ha sido actualizado, haz click en refrescar para ver el contenido actualizado"
+
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
-msgstr ""
+msgstr "Contribuye"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Copiar"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
-msgstr "Copiar canciones de cola de reproducción actual a lista de reproducción"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
+msgstr "Copiar canciones de cola de reproducción a lista de reproducción"
+
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
-msgstr ""
+msgstr "Copia/Pega este código en el HTML de tu página web"
 
-#: front/src/components/library/Track.vue:91
-#, fuzzy
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
-msgstr "Copiar"
+msgstr "Copyright"
 
 #: front/src/views/auth/EmailConfirm.vue:7
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
-msgstr "Confirma tu correo electrónico"
+msgstr "No hemos podido confirmar tu dirección electrónica"
 
 #: front/src/views/content/remote/ScanForm.vue:3
-#, fuzzy
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
-msgstr "Error al importar la biblioteca externa"
-
-#: front/src/views/content/libraries/FilesTable.vue:213
-#, fuzzy
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr "Ha ocurrido un error al procesar esta pista, asegúrate que esta etiquetada correctamente"
+msgstr "Error al importar la biblioteca remote"
 
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Covers, letras, queremos conseguirlo todo ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
-msgstr "Crear importación"
+msgstr "Crear"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Crear una cuenta de funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Crear una nueva lista de reproducción"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Crear una nueva lista de reproducción"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Crear una nueva biblioteca"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Crear una nueva lista de reproducción"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Crear una cuenta"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Crear una lista de reproducción"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Crear biblioteca"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Crear mi cuenta"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Crear una lista de reproducción"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Crear tu propia radio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Fecha de creación"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Avatar actual"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Biblioteca actual"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Canción actual"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Uso actual"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Fecha"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Información de la canción"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
-msgstr ""
-
-#: front/src/components/manage/library/FilesTable.vue:190
+msgstr "Reducir volumen"
+
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Borrar"
 
-#: front/src/views/content/libraries/Form.vue:39
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Borrar lista de reproducción"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Borrar biblioteca"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
-#, fuzzy
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
-msgstr "Borrar radio"
+msgstr "Borrar regla de moderación"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Borrar lista de reproducción"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Borrar radio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "¿Eliminar la biblioteca?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "¿Eliminar la biblioteca?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "¿Eliminar la biblioteca?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
-#, fuzzy
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
+msgstr "¿Eliminar ésta regla de moderación?"
+
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "¿Eliminar ésta regla de moderación?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
 msgstr "¿Eliminar la biblioteca?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Descendente"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Descripción"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Detalle"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Descripción"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Detalles"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Establecer cuanto contenido puede subir el usuario. Déjalo en blanco para usar el valor por defecto de la instancia."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Determina el nivel de visibilidad de tu actividad"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Desactivar acceso"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Desactivar el acceso Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "¿Desactivar el acceso al API de Subsonic?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
-msgstr "Desactivar acceso"
+msgstr "Desactivado"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Descubre cómo utilizar Funkwhale desde otras aplicaciones"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
-msgstr "Nombre del archivo"
+msgstr "Mostrar nombre"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Mostrar públicamente"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
+msgstr "No descargar ningún archivo media (audio, portada de album, avatar de cuenta...) de ésta cuenta o dominio. Ésto borrará el contenido existente también."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "¿Quieres vaciar la lista de reproducción \"%{ playlist }\"?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "¿Quieres confirmar esta acción?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "¿Quieres borrar la lista de reproducción \"%{ playlist }\"?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "¿Quieres borrar la radio \"%{ radio }\"?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "¿Quieres borrar la radio \"%{ radio }\"?"
+
+#: front/src/components/common/ActionTable.vue:37
+#, fuzzy
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "¿Quieres realizar la acción %{ action } en %{ count } elemento?"
 msgstr[1] "¿Quieres realizar la acción %{ action } en %{ count } elementos?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "¿Quieres restaurar tu cola de reproducción anterior?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Documentación"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
-msgstr ""
+msgstr "Dominio"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
-msgstr ""
+msgstr "Dominios"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Descargar"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Arrastra y suelta las filas para reordenar canciones en la lista de reproducción"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Duración"
 
 #: front/src/views/auth/EmailConfirm.vue:23
-#, fuzzy
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
-msgstr "Correo electrónico confirmado"
+msgstr "Dirección e-mail confirmada"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Fácil de usar"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Editar"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Editar"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Error al aplicar la acción"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Editar la información de esta instancia"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Actualizar regla de moderación"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Reproducir canción"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Reproducir canción"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Reproducir canción"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Editar"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
 #, fuzzy
-msgid "Edit…"
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
 msgstr "Editar"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Correo electrónico"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Dirección de correo electrónico"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
-msgstr ""
+msgstr "Incrustar"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
-msgstr ""
+msgstr "Código empotrado"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
-msgstr ""
+msgstr "Inserta éste álbum en tu página web"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+#, fuzzy
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Inserta esta canción en tu página web"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
-msgstr ""
+msgstr "Inserta esta canción en tu página web"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
-msgstr "Introducir url de biblioteca"
+msgstr "La biblioteca emitida sigue"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
-msgstr ""
+msgstr "Mensajes emitidos"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
-msgstr ""
+msgstr "Habilitado"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Terminar la edición"
 
 #: front/src/views/content/remote/ScanForm.vue:50
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
-msgstr "Introducir url de biblioteca"
+msgstr "Introducir URL de biblioteca"
 
-#: front/src/components/library/Radios.vue:140
-#, fuzzy
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Introducir un nombre de radio…"
 
-#: front/src/components/library/Artists.vue:118
-#, fuzzy
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
-msgstr "Introducir un nombre de artista…"
+msgstr "Introduce un nombre de artista…"
 
 #: front/src/views/playlists/List.vue:107
-#, fuzzy
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
-msgstr "Introducir un nombre de lista de reproducción…"
+msgstr "Introduce un nombre de lista de reproducción…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+#, fuzzy
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Ingresa la dirección de correo electrónico vinculada a tu cuenta"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Introducir tu correo electrónico"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Introducir tu código de invitación (no distingue mayúsculas de minúsculas)"
 
 #: front/src/components/metadata/Search.vue:114
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
-msgstr "Introducir tu búsqueda…"
+msgstr "Introduce tu búsqueda…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Introduce tu nombre de usuario"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Introduce tu nombre de usuario o correo electrónico"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Error"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Informes de error"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Informes de error"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Error"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Error al aplicar la acción"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Error al pedir restablecimiento de contraseña"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Error al aplicar la acción"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Error al cambiar tu contraseña"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
-#, fuzzy
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
-msgstr "Error al crear la invitación"
+msgstr "Error al crear dominio"
+
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Error al crear la regla"
 
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Error al crear la invitación"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
-#, fuzzy
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
-msgstr "Error al crear la invitación"
+msgstr "Error al crear la regla"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
 #, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Error al crear la invitación"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
-msgstr "Error al importar la biblioteca externa"
+msgstr "Error al obtener información del nodo"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Error al guardar los cambios"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Error al guardar los cambios"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+#, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Error al guardar los cambios"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Error"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Archivos con error"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Todo el mundo"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Todo el mundo en esta instancia"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
 #, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
-msgstr "Todo el mundo en esta instancia"
+msgstr "Todo el mundo, en todas las instancias"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Excluir"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Fecha de caducidad"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Caducada"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Caducada/usada"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
+msgstr "Explique por qué está aplicando esta política. Dependiendo de la configuración de su instancia, esto le ayudará a recordar por qué actuó en esta cuenta o dominio, y puede mostrarse públicamente para ayudar a los usuarios a comprender qué reglas de moderación existen."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
-msgstr ""
+msgstr "Ha fallado"
 
-#: front/src/views/content/remote/Card.vue:58
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
-msgstr "Canciones con error:"
+msgstr "Pistas fallidas:"
+
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Pistas fallidas:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Favoritos"
 
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Favoritos"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federación"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
 #, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Federación"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nombre del archivo"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Archivos"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Nombre del filtro"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Terminado"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
-msgstr ""
+msgstr "Primera vista"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
-msgstr "Fecha de caducidad"
+msgstr "Primera fecha de visualización"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Seguir"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Seguir bibliotecas remotas"
 
-#: front/src/views/content/remote/Card.vue:88
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Solicitud de seguimiento pendiente de aprobación"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Seguidores"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Seguidores"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Siguiendo"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Del álbum %{ album } de %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Seguir"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Desactivar acceso"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale es compatible con otros reproductores de música que soportan la API Subsonic."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale es facilísimo de usar."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale está diseñado para que sea fácil escuchar la música que te gusta, o descubrir nuevos artistas."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale es gratis y te da el control de tu música."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale te ayuda a gestionar tu música"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
-msgstr ""
+msgstr "Atajos generales"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Obtener una nueva invitación"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Llévame a la biblioteca"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "Obtén metadatos de calidad para tu música con <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Comenzar"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Obteniendo ayuda"
+
 #: front/src/components/Footer.vue:37
 #, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
-msgstr "Ajustes"
+msgstr "Obteniendo ayuda"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Ir"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Ir a la página principal"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Explorando artistas"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
+msgstr "Ocultar contenido de la cuenta o dominio, excepto de los seguidores."
+
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Añadir contenido"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
 msgstr ""
 
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Inicio"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Horas de música"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Sin embargo, acceder a Funkwhale desde estos clientes requiere una contraseña distinta que podrás configurar a continuación."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Si la dirección de correo electrónico proporcionada en el paso anterior es válida y asociada a una cuenta de usuario, deberías recibir un correo electrónico con las instrucciones de restablecimiento dentro de unos minutos."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Fecha de importación"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importa música desde otras plataformas, como YouTube o SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Estado de la importación"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Fuente de la importación"
 
-#: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Import status"
 msgstr "Estado de la importación"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/manage/library/UploadsTable.vue:20
+#: front/src/views/content/libraries/FilesTable.vue:11
+#: front/src/views/content/libraries/FilesTable.vue:59
 #, fuzzy
+msgctxt "Content/Library/*/Noun"
+msgid "Import status"
+msgstr "Estado de la importación"
+
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
-msgstr "Fecha de importación"
+msgstr "Importado"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Fecha de importación"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
+#, fuzzy
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Añadidos recientemente"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "En favoritos"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Inactivo"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
-msgstr ""
-
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr ""
+msgstr "Aumentar volument"
 
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Agregar de la cola (%{ count } pista)"
 msgstr[1] "Agregar de la cola (%{ count } pistas)"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:71
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
 #, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Datos de Instancia"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
-msgstr "Radios de la instancia"
+msgstr "Datos de Instancia"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Información de esta instancia"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Radios de la instancia"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Ajustes de la instancia"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Datos de Instancia"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr "Tipo de archivo no válido, asegúrese de que está cargando un archivo de audio. Las extensiones de archivo admitidas son %{ extensions }"
+
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Código de invitación"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Código de invitación (opcional)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Invitaciones"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Sistema de seguimiento de incidentes"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Apunta tus canciones favoritas"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
-msgstr ""
+msgstr "Atajos de teclado"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
-msgstr "Mi cuenta"
+msgstr "Cuentas conocidas"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Bibliotecas conocidas"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Última actividad"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
-msgstr ""
+msgstr "Última comprobación"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Última modificación"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
-msgstr ""
+msgstr "Visto por última vez"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
-msgstr "Última actualización:"
+msgstr "Última visualización"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Última actualización:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Iniciar"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Aprender más acerca de esta instancia"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Dejar en blanco para un código aleatorio"
 
 #: front/src/components/audio/EmbedWizard.vue:7
-#, fuzzy
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
-msgstr "Dejar en blanco para un código aleatorio"
+msgstr "Dejar en blanco para widget responsive"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Bibliotecas"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Bibliotecas"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Biblioteca actualizada"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "Las bibliotecas te ayudan a organizar tu colección de música. Puedes subir tu propia colección de musica a Funkwhale y compartirla con tus familiares y amigos."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Biblioteca"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Biblioteca creada"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
 #, fuzzy
-msgid "Library deleted"
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
 msgstr "Biblioteca actualizada"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
+msgid "Library deleted"
+msgstr "Biblioteca eliminada"
+
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "Archivos de biblioteca"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Biblioteca actualizada"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
+msgstr "Licencia"
+
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
 msgstr ""
 
-#: front/src/views/content/libraries/Detail.vue:21
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
 #, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Cargando seguidores…"
+
+#: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Cargando seguidores…"
 
 #: front/src/views/content/libraries/Home.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Cargando bibliotecas…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Cargando datos de la biblioteca…"
 
-#: front/src/views/Notifications.vue:4
-#, fuzzy
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Cargando notificaciones…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
-msgstr "Cargando bibliotecas externas…"
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "Cargando bibliotecas remotas…"
 
 #: front/src/views/content/libraries/Quota.vue:4
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Cargando datos de uso…"
 
 #: front/src/components/favorites/List.vue:5
-#, fuzzy
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Cargando tus favoritos…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
 #, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Mi cuenta"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Iniciar sesión"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Iniciar sesión con tu cuenta de Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Cerrar sesión"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Sesión iniciada como %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Iniciar sesión"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
-msgstr "Estado de cuenta"
+msgstr "Estado de sesión"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Cerrar sesión"
 
 #: front/src/views/content/libraries/Home.vue:9
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
-msgstr "Parece que aún no tienes ninguna biblioteca, ¡Es hora de crear una!"
+msgstr "Parece que aún no tienes ninguna biblioteca, Es hora de crear una!"
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Bucle deshabilitado. Pulsa para cambiar a reproducción en bucle de la canción actual."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Bucle de la canción actual. Pulsa para cambiar a la reproducción en bucle de la cola de reproducción entera."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Bucle de la cola de reproducción entera. Pulsa para desactivar la reproducción en bucle."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Letras"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
-msgstr ""
+msgstr "Menú principal"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Gestionar biblioteca"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Gestionar listas de reproducción"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Gestionar usuarios"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Gestionar tus listas de reproducción"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Marcar todo como leído"
 
-#: front/src/components/notifications/NotificationRow.vue:44
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
-msgstr "Marcar todo como leído"
+msgstr "Marcar como leído"
 
-#: front/src/components/notifications/NotificationRow.vue:45
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
-msgstr "Marcar todo como leído"
+msgstr "Marcar como leído"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
-msgstr ""
+msgstr "Reproductor multimedia"
+
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Miembro desde %{ date }"
 
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
-msgstr ""
+msgstr "Apps móviles y de escritorio"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
 #, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
-msgstr "Federación"
+msgstr "Moderación"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
+msgstr "Las políticas de moderación te ayudan a controlar cómo tu instancia interactúa con un dominio o cuenta concretos."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Fecha de modificación"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Fecha de modificación"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Música"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Silencio"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Silenciar actividad"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Silenciar notificaciones"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Mi cuenta"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Mi descripción molona"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Mi biblioteca molona"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "Mi lista de reproducción molona"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Mi radio molona"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Mis bibliotecas"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "N/A"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nombre"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nombre"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nombre"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nueva contraseña"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Las nuevas canciones se agregarán aquí de forma automática."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Próxima canción"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "No"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Sin complementos, sin extensiones : basta con una biblioteca en la web"
 
 #: front/src/components/audio/Search.vue:25
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Lo sentimos, no hemos encontrado ningún álbum que corresponda con tu búsqueda"
 
 #: front/src/components/audio/Search.vue:16
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Lo sentimos, no hemos encontrado ningún artista que corresponda con tu búsqueda"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "No hay letra disponible para esta canción."
 
+#: front/src/components/library/TrackDetail.vue:25
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "No tenemos ninguna información de licencia para esta pista"
+
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Biblioteca no encontrada."
 
-#: front/src/views/Notifications.vue:26
-#, fuzzy
-msgid "No notifications yet."
-msgstr "Tus notificaciones"
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr "No hay notificaciones para mostrar."
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr ""
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Solo yo"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Nadie está siguiendo esta biblioteca"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "No usado"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Notificaciones"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Notificaciones"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Página oficial"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Antigua contraseña"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Abierta"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Actualizar regla de moderación"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Abrir perfil"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Ver en MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
-msgstr ""
+msgstr "Abrir perfil"
+
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Abrir perfil"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
-#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
-msgstr "Página oficial"
+msgstr "Abrir website"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
-#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
-msgstr "Añade filtros para personalizar tu radio"
+msgstr "Añade filtros para personalizar tus reglas"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
-#, fuzzy
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Orden"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Orden"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Dirección del orden"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Propietario"
 
 #: front/src/components/PageNotFound.vue:33
-#, fuzzy
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
-msgstr "¡Página no encontrada!"
+msgstr "Página no encontrada!"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "¡Página no encontrada!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
-msgstr ""
+msgstr "Paginación"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Contraseña"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Contraseña actualizada"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Contraseña actualizada con éxito"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Pausar la canción"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
-msgstr ""
+msgstr "Pausar / reproducir la pista actual"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
-msgstr ""
+msgstr "En pausa"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "En espera"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Aprobación pendiente"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Archivos pendientes"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Solicitudes de seguimiento pendientes"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Archivos pendientes"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Archivos pendientes"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Permisos"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Permisos"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Reproducir"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Reproducir todo"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Reproducir todos los álbumes"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Reproducir siguiente"
 
 #: front/src/components/ShortcutsModal.vue:67
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
-msgstr "Reproducir canción"
+msgstr "Reproducir siguiente canción"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Reproducir ahora"
 
 #: front/src/components/ShortcutsModal.vue:63
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Canción anterior"
 
-#: front/src/components/Sidebar.vue:211
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Reproducir canción"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Reproducir canción"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Reproducir..."
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Lista de reproducción"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Lista de reproducción con %{ count } canción, de %{ username }"
 msgstr[1] "Lista de reproducción con %{ count } canciones, de %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Lista de reproducción creada"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Editor de listas de reproducción"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nombre de lista de reproducción"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Lista de reproducción actualizada"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Visibilidad de lista de reproducción"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Listas de reproducción"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Listas de reproducción"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "¿Listas de reproducción? Las tenemos"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Por favor, comprueba que tu contraseña es correcta"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Por favor, comprueba que tu nombre de usuario y contraseña son correctos"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF o JPG. Máximo de 2MB. La imagen será reducida a 400x400px."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Paginación"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
+msgstr "Evita que la cuenta o el dominio activen notificaciones, excepto de los seguidores."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
-msgstr ""
+msgstr "Previsualización"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Canción anterior"
 
-#: front/src/views/content/remote/Card.vue:39
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Error durante el análisis"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Continuar"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Proceder a inicio de sesión"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Procesando"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Abrir perfil"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1938,1108 +3273,1973 @@ msgstr "Procesando"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Eliminar"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "¿Eliminar los archivos con errores?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "¿Eliminar los archivos pendientes?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "¿Eliminar los archivos omitidos?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Cola de reproducción"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "¡Cola de reproducción mezclada!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Editor de radio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Radio creada"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nombre de la radio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Radio actualizada"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radios"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radios"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
-msgstr ""
+msgstr "Razón"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
-msgstr ""
+msgstr "Seguidores recibidos en la biblioteca"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
+msgstr "Mensajes recibidos"
+
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Añadidos recientemente"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
 msgstr ""
 
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Añadidos recientemente"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Añadidos a favoritos recientemente"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Escuchados recientemente"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Recargar"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Recargar"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
+msgstr "Actualizar la información del nodo"
+
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Actualizar la información del nodo"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
+msgstr "Actualiza el contenido de la tabla"
+
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
 msgstr ""
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Inscritx desde %{ date }"
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "La inscripción a esta instancia está cerrada, necesitarás un código de invitación para inscribirte."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "Usuario estándar"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Rechazar"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
 #, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
-msgstr "Rechazada"
+msgstr "Rechazar media"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Rechazada"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Reiniciar importación"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Última visualización"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Bibliotecas remotas"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Las bibliotecas remotas pertenecen a otros usuarios de internet. Podrás acceder a ellas cuando sean públicas o cuando te permitan el acceso."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Quitar"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Quitar avatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Quitar avatar"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Quitar de favoritos"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Elimina las pistas cargadas pero aún no procesadas, agregando los datos correspondientes a su cuota."
 
 #: front/src/views/content/libraries/Quota.vue:64
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
 msgstr "Esto borrará las pistas que fueron subidas pero se omitieron por alguna razón. Se borrarán completamente y recuperarás la cuota correspondiente."
 
 #: front/src/views/content/libraries/Quota.vue:90
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
 msgstr "Esto borrará las pistas que fueron subidas pero no se procesaron en el servidor. Se borrarán completamente y recuperarás la cuota correspondiente."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Solicitar una nueva contraseña"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "¿Solicitar una nueva contraseña de la API Subsonic?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Solicitar una contraseña"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Restablecer tu contraseña"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Reiniciar importación"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Resultados por página"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
-#, fuzzy
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
-msgstr "Proceder a inicio de sesión"
+msgstr "Volver a inicio de sesión"
+
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Ver archivos"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
-msgstr ""
+msgstr "Regla"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Guardar"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Análisis iniciado"
 
-#: front/src/views/content/remote/Card.vue:63
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
-msgstr "Reproducir ahora"
+msgstr "Analizar ahora"
+
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Ascendente"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Análisis omitido (el anterior análisis es demasiado reciente)"
 
-#: front/src/views/content/remote/Card.vue:31
-#, fuzzy
-msgid "Scan waiting"
-msgstr "Análisis pendiente"
-
-#: front/src/views/content/remote/Card.vue:43
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
-msgstr "Análisis iniciado"
+msgstr "Análisis finalizado"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Análisis erróneo"
 
-#: front/src/views/content/remote/Card.vue:35
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Analizando…(%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Buscar"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Buscar una biblioteca externa"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:171
+#: front/src/components/manage/library/EditsCardList.vue:211
 #, fuzzy
-msgid "Search by domain, username, bio..."
-msgstr "Buscar por nombre de usuario, correo electrónico, código…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Buscar por título, artista, dominio…"
 
-#: front/src/components/manage/moderation/DomainsTable.vue:151
+#: front/src/components/manage/library/LibrariesTable.vue:191
 #, fuzzy
-msgid "Search by name..."
-msgstr "Buscar por usuario, correo electrónico, nombre…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Buscar por dominio, nombre de usuario, bio…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/components/manage/library/UploadsTable.vue:241
 #, fuzzy
-msgid "Search by title, artist, album…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Buscar por dominio, nombre de usuario, bio…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Buscar por dominio, nombre de usuario, bio…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
 msgstr "Buscar por título, artista, álbum…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
+#: front/src/components/manage/library/AlbumsTable.vue:174
 #, fuzzy
-msgid "Search by title, artist, domain…"
-msgstr "Buscar por título, artista, dominio…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Buscar por título, artista, álbum…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Buscar por dominio, nombre de usuario, bio…"
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Buscar por nombre…"
+
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
+msgid "Search by title, artist, album…"
+msgstr "Buscar por título, artista, álbum…"
 
 #: front/src/components/manage/users/InvitationsTable.vue:153
 #, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Buscar por nombre de usuario, correo electrónico, código…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
-#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Buscar por usuario, correo electrónico, nombre…"
 
 #: front/src/components/audio/SearchBar.vue:20
-#, fuzzy
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Buscar artistas, álbumes, canciones…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Buscar música"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Buscar en lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Buscar en Wikipedia"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
-msgstr ""
+msgstr "Menú secundario"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Secciones"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Seleccionar un filtro"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "Seleccionar %{ total } elemento"
 msgstr[1] "Seleccionar los %{ total } elementos"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Seleccionar solo la página actual"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Ajustes"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Ajustes actualizados"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Ajustes actualizados con éxito."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Compartir enlace"
 
 #: front/src/views/content/libraries/Detail.vue:15
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
 msgstr "Comparte este link con otros usuarios para que puedan pedir acceso a tu biblioteca."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Compartir enlace"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "Mostrar %{ count } canción más"
 msgstr[1] "Mostrar %{ count } canciones más"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Mostrar 1 álbum adicional"
 msgstr[1] "Mostrar %{ count } álbumes adicionales"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
-msgstr ""
+msgstr "Mostrar atajos de teclado disponibles"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Mostrar notificaciones leídas"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Mostrar/ocultar contraseña"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Mostrando resultados %{ start }-%{ end } de %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Mezclar tu cola de reproducción"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Mezclar tu cola de reproducción"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Inscripción"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Inscripción"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Fecha de inscripción"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
 #, fuzzy
-msgid "Silence activity"
-msgstr "Actividad de usuario"
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Tamaño"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
 #, fuzzy
-msgid "Silence notifications"
-msgstr "Mostrar notificaciones leídas"
-
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Tamaño"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Omitido"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Archivos omitidos"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
+msgstr "Software"
+
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
 msgstr ""
 
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Lo sentimos, la página solicitada no existe:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Código fuente"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Miembro del equipo"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Iniciar"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Parar radio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Estadísticas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
+msgstr "Las estadísticas se calculan a partir de la actividad y el contenido conocidos en tu instancia y no reflejan la actividad general de esta cuenta"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
+msgstr "Las estadísticas se calculan a partir de la actividad y el contenido conocidos en tu instancia y no reflejan la actividad general de éste dominio"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "Las estadísticas se calculan a partir de la actividad y el contenido conocidos en tu instancia y no reflejan la actividad general de esta cuenta"
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Estado"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Estado"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Parar"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Estado"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Parar radio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Enviar"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Contraseña de la API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "No podemos añadir la canción a una lista de reproducción"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "No podemos añadir la canción a una lista de reproducción"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "No podemos añadir la canción a una lista de reproducción"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Sugerencias"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Resumen"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
-msgstr ""
+msgstr "Foro de soporte"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
-msgstr ""
+msgstr "Extensiones soportadas: %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
-#, fuzzy
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Sincronizando los cambios con el servidor…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "¡Texto copiado al portapapeles!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "Así de simple: nos encantó Grooveshark y quisimos hacer algo incluso mejor."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
+msgstr "El logotipo de Funkwhale fue generosamente diseñado y suplido por Francis Gading."
+
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
 msgstr ""
-"El logotipo de Funkwhale fue generosamente diseñado y suplido por Francis "
-"Gading."
 
 #: front/src/views/content/libraries/Form.vue:34
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
 msgstr "La biblioteca y todas sus pistas serán borradas. Esta acción es irreversible."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
-msgstr "Las canciones que estás subiendo estén etiquetadas correctamente:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
+msgstr ""
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
 msgstr ""
 
-#: front/src/components/Home.vue:121
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
+msgstr "Las canciones que estás subiendo estén etiquetadas correctamente:"
+
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "La siguiente pista se reproducirá automáticamente en unos segundos…"
+
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "La plataforma es gratuita y de código fuente libre, puedes instalarla y modificarla sin restricciones"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Lista de reproducción creada"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Ésta acción es irreversible."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "La API Subsonic no está disponible en esta instancia de Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "No podemos añadir la canción a una lista de reproducción"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Ésta acción es irreversible."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Las canciones subidas estén en formato OGG, Flac o MP3"
 
 #: front/src/views/content/Home.vue:4
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
 msgstr "Ofrecemos varias formas de obtener nuevo contenido para hacerlo disponible aquí."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
-msgstr ""
+msgstr "Ésta acción es irreversible."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Este album ya está en las siguientes bibliotecas:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Este artista ya está en las siguientes bibliotecas:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
-msgstr ""
+msgstr "Este dominio está sujeto a reglas de moderación específicas"
 
 #: front/src/views/content/Home.vue:9
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr "Esta instancia ofrece %{ quota } de almacenamiento a cada usuario."
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "¡Eres tú!"
 
-#: front/src/views/content/libraries/Form.vue:71
-#, fuzzy
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Esta biblioteca contiene mi música personal, ¡espero que te guste!"
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
+msgstr "Esta biblioteca es privada y se necesita la aprobación de su propietario para acceder a su contenido"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
-msgstr ""
+msgstr "Esta biblioteca es pública y puedes acceder a su contenido libremente"
 
-#: front/src/components/common/ActionTable.vue:45
-#, fuzzy
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
 msgstr "Esto puede afectar a muchos elementos, por favor comprueba si esto es realmente lo que quieres."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Esta referencia será usada para agrupar los archivos subidos."
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Ha ocurrido un error al procesar esta pista, asegúrate que está etiquetada correctamente"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "La pista se ha subido pero aún no la ha procesado el servidor"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "La pista ya está en alguna de tus bibliotecas"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
-msgstr ""
+msgstr "Esta pista no está disponible en ninguna biblioteca a la que tenga acceso"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Esta canción ya está en las siguientes bibliotecas:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Esto borrará por completo esta lista de reproducción y no se podrá deshacer."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Esto borrará por completo esta radio y no se podrá deshacer."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Esto desactivará por completo el acceso a la API Subsonic desde esta cuenta."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-#, fuzzy
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr "Esto borrará tus datos locales y te desconectará, ¿quieres continuar?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Esto cerrará tus sesiones en todos los dispositivos que usan esa contraseña."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Esto borrará por completo esta lista de reproducción y no se podrá deshacer."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Esto borrará todas las canciones de esta lista de reproducción y no se podrá deshacer."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
 msgid "Title"
 msgstr "Título"
 
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
-msgstr ""
+msgstr "Alternar cola en bucle"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
-msgstr ""
+msgstr "Tamaño total"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Tamaño total de la biblioteca"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
-#, fuzzy
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
-msgstr "No usado"
+msgstr "Usuarios totales"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Track"
+msgstr "Canción"
+
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
 msgid "Track"
 msgstr "Canción"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:91
 #, fuzzy
-msgid "Track already present in one of your libraries"
-msgstr "La pista ya está en alguna de tus bibliotecas"
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Nombre"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Información de la canción"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Canción correspondiente al filtro"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Nombre"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-#, fuzzy
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "La pista se ha subido pero aún no la ha procesado el servidor"
-
-#: front/src/components/instance/Stats.vue:54
-msgid "tracks"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
 msgstr "Canciones"
 
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/instance/Stats.vue:54
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Canciones"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Canciones de este artista"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Canciones en favoritos"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "Canciones escuchadas"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Canción correspondiente al filtro"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Tipo"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Tipo"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr ""
+msgstr "Bajo regla de moderación"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Dejar de seguir"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "¿Dejar de seguir esta biblioteca?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "Desafortunadamente, lxs propietarixs de esta instancia aún no han tomado el tiempo para completar esta página."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Música ilimitada"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Activar sonido"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
-msgstr "Fecha de subida"
+msgstr "Actualizar"
+
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Actualizar lista de reproducción"
 
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Actualizar avatar"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Actualizar biblioteca"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr ""
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Actualizar lista de reproducción"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Actualizar ajustes"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Actualizar tu contraseña"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Subir"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Subir un nuevo avatar"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Subir nuevo contenido"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Fecha de subida"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Fecha de subida"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
 msgstr "Subida rechazada, asegúrate que el archivo no es demasiado grande y que no has alcanzado tu cuota"
 
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
+msgstr ""
+
 #: front/src/views/content/Home.vue:7
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
 msgstr "Sube archivos de música (mp3, OGG, Flac, etc…) de tu biblioteca personal a tu navegador y disfrútala aquí."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Subir nuevas pistas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Cuota de subida"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Timeout en la subida, intentalo de nuevo"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Subido"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Subiendo"
 
-#: front/src/components/library/FileUpload.vue:103
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
-msgstr "Subiendo"
+msgstr "Subiendo…"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/manage/library/LibrariesTable.vue:52
 #, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Uploads"
-msgstr "Subir"
+msgstr "Subidas"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Subidas"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:41
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Uploads"
+msgstr "Subidas"
+
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
 
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Usar otra instancia"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Usa este formulario para solicitar un restablecimiento de contraseña. Te mandaremos un correo electrónico a la dirección proporcionada con instrucciones para restablecer tu contraseña."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
+msgstr "Use esta configuración para habilitar / deshabilitar temporalmente la política sin eliminarla por completo."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Usado"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Usuario"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Actividad de usuario"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Bibliotecas de usuarios"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Radios de los usuarios"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nombre de usuario"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nombre de usuario o correo electónico"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "usuario"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Usuario"
 
 #: front/src/components/Footer.vue:29
 #, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
-msgstr "Acerca de Funkwhale"
+msgstr "Usando Funkwhale"
 
 #: front/src/components/Footer.vue:13
-#, fuzzy
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
-msgstr "Código fuente (%{version})"
+msgstr "Versión %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Ver archivos"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Ver en MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Visibilidad"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Visibilidad: Todo el mundo en esta instancia"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Visibilidad: todos, incluyendo otras instancias"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Visibilidad: Solo yo"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Visibilidad"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
-msgstr ""
-
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "No podemos añadir la canción a una lista de reproducción"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "No podemos crear la lista de reproducción"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "No podemos crear tu cuenta"
+msgstr "Volúmen %{ number }"
 
-#: front/src/components/audio/Player.vue:64
+#: front/src/components/federation/FetchButton.vue:69
 #, fuzzy
-msgid "We cannot load this track"
-msgstr "No podemos añadir la canción a una lista de reproducción"
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Cargando tus favoritos…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "No se puede iniciar la sesión"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "No podemos guardar tu avatar"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "No podemos guardar tus ajustes"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "No podemos crear tu cuenta"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "No te rastreamos y no te molestamos con anuncios"
 
-#: front/src/components/library/Track.vue:95
-#, fuzzy
-msgid "We don't have any copyright information for this track"
-msgstr "¡No tienes ninguna notificación!"
-
-#: front/src/components/library/Track.vue:106
-#, fuzzy
-msgid "We don't have any licensing information for this track"
-msgstr "¡No tienes ninguna notificación!"
-
-#: front/src/components/library/FileUpload.vue:40
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
-msgstr "Recomendamos usar Picard"
+msgstr "Recomendamos usar Picard para este propósito."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Pensamos que debe ser simple escuchar música."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Lo sentimos, la página solicitada no existe:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Bienvenido"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Bienvenidx a Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "¿Por qué funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
-msgstr ""
+msgstr "Altura del widget"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
+msgstr "Ancho del widget"
+
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Sí"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Sí, cierra mi sesión!"
 
 #: front/src/views/content/libraries/Form.vue:19
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
 msgstr "Puedes compartir tu biblioteca con otras personas, independientemente de su vilibilidad."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Estás a punto de subir música a tu biblioteca. Antes de continuar asegúrate que:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Tienes iniciada actualmente sesión como %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Puedes seguir bibliotecas de otros usuarios para obtener nueva música. Puedes seguir bibliotecas públicas instantáneamente, mientras que las biliotecas privadas necesitan aprovación por parte de su dueño."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Puedes invitar a tus amigxs y tu familia a tu instancia para que ellxs puedan disfrutar de tu música"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
-msgstr "Tu dirección de correo electrónico ha sido confirmada, ahora puedes usar el servicio sin limitaciones."
+msgstr "Ahora puede utilizar el servicio sin limitaciones."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Puedes usar esta interfaz para hacer tu propia radio personalizada, que reproducirá canciones según tus criterios."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Puedes usarlos para disfrutar de tus listas de reproducción y tu música en modo sin conexión, en tu smartphone o tu tablet, por ejemplo."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "No tienes ninguna regla para esta cuenta."
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "No tienes ninguna regla para esta cuenta."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
-msgstr ""
+msgstr "No tienes ninguna regla para esta cuenta."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
+msgstr "No tienes ninguna regla para este dominio."
+
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
 msgstr ""
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Estás escuchando una radio"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
-msgstr ""
-
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Tienes que seleccionar una instancia para poder continuar"
+msgstr "Puede tener un problema de conectividad."
 
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Se cerrará esta sesión y tendrás que reiniciar sesión con la nueva contraseña"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Tendrás que actualizar tu contraseña en los clientes que usan esta contraseña."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Lista de reproducción creada"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Tus notificaciones"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Tus favoritos"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "Tu música, a tu manera"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Tus notificaciones"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Tu contraseña ha sido cambiada con éxito."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Ajustes actualizados"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "Tu contraseña Subsonic se cambiará a una nueva contraseña aleatoria, cerrando tus sesiones en los dispositivos que usaban la antigua contraseña Subsonic"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Paginación"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Copyright"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Álbum que contiene %{ count } canción, de %{ artist }"
+msgstr[1] "Álbum que contiene %{ count } canciones, de %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } canción ha sido añadida a tu cola de reproducción"
+msgstr[1] "%{ count } canciones han sido añadidas a tu cola de reproducción"
diff --git a/front/locales/fr_FR/LC_MESSAGES/app.po b/front/locales/fr_FR/LC_MESSAGES/app.po
index a8712c60b975e4b36b3512ad342333c8513a6b31..382c7d1077cd768d3e69233c7d1622e8861f897f 100644
--- a/front/locales/fr_FR/LC_MESSAGES/app.po
+++ b/front/locales/fr_FR/LC_MESSAGES/app.po
@@ -1,10 +1,11 @@
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: French (Funkwhale)\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-22 08:45+0000\n"
-"Last-Translator: jovuit <jo.vuitton@gmail.com>\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-05-03 07:47+0000\n"
+"Last-Translator: Pierrick <contact@pierrick.io>\n"
 "Language-Team: French <https://translate.funkwhale.audio/projects/funkwhale/"
 "front/fr/>\n"
 "Language: fr_FR\n"
@@ -15,1879 +16,3187 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
-msgstr "\"%{ title }\", de %{ artist }"
+msgstr "« %{ title } », de %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } sur %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(vide)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "%{ app } Veut accéder à votre compte funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } sur %{ total } élément sélectionné"
 msgstr[1] "%{ count } sur %{ total } éléments sélectionnés"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } piste"
 msgstr[1] "%{ count } pistes"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } piste dans %{ albumsCount } albums"
 msgstr[1] "%{ count } pistes dans %{ albumsCount } albums"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } piste correspondant aux filtres sélectionnés"
 msgstr[1] "%{ count } pistes correspondant aux filtres sélectionnés"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "%{ count } piste a été ajouté à votre queue"
-msgstr[1] "%{ count } pistes ont été ajoutées à votre queue"
-
 #: front/src/components/playlists/Card.vue:18
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} piste"
 msgstr[1] "%{ count } pistes"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
-msgstr "%{ current } utilisé(s) sur %{ max } autorisé(s)"
+msgstr "%{ current } utilisé·s sur %{ max } autorisé·s"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
-msgstr "%{hours} h %{minutes} min"
+msgstr "%{ hours } h %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
-msgstr "%{minutes} min"
+msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
-msgstr "%{ username } a accepté votre suivi sur la librairie \"%{ library }\""
+msgstr "%{ username } a accepté votre suivi de la bibliothèque « %{ library } »"
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
-msgstr "%{ username } a suivi votre librairie \"%{ library }\""
+msgstr "%{ username } suit votre bibliothèque « %{ library } »"
+
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } veut suivre votre bibliothèque « %{ library } »"
 
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Profil de %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">À propos "
-"de %{instanceName}</translate>"
+"<strong>%{ track }</strong> est déjà dans <strong>%{ playlist }</strong>."
 
 #: front/src/components/audio/artist/Card.vue:41
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 album"
 msgstr[1] "%{ count } albums"
 
 #: front/src/components/favorites/List.vue:10
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 favori"
 msgstr[1] "%{ count } favoris"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Une bibliothèque propre"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Une erreur réseau s'est produite lors du téléversement de ce fichier"
 
+#: front/src/components/library/EditForm.vue:145
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Une courte description décrivant vos changements."
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
-msgstr "À propos de %{instance}"
+msgstr "À propos de %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "À propos de %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "À propos de Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "À propos"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "À propos de cette instance"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Accepter"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Accepté"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Accès désactivé"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
-msgstr "\"Accédez à votre musique depuis une interface épurée"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr "Accès aux fichiers audio, librairies, artistes, albums et pistes"
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Accès aux filtres de contenu"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Accès désactivé"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr "Accès au courriel, nom d'utilisateur et informations du profil"
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Accès aux favoris"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr "Accès aux suivis"
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr "Accès à l'historique d'écoute"
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Accès aux notifications"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Accès aux listes de lecture"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Accès aux radios"
+
+#: front/src/components/Home.vue:101
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr ""
+"Accédez à votre musique depuis une interface épurée qui se concentre sur ce "
+"qui compte vraiment"
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
 msgstr "Date d'accès"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Compte"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Compte"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
-msgstr "Informations de compte"
+msgstr "Données du compte"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Paramètres du compte"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Paramètres du compte"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Statut du compte"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Courriel du compte"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Comptes"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Action"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "L'action %{ action } a été lancée avec succès sur %{ count } élément"
 msgstr[1] "L'action %{ action } a été lancée avec succès sur %{ count } éléments"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Actions"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Actif"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Activité"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Visibilité de l'activité"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Ajouter"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Ajouter un domaine"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Ajouter une politique de modération"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Ajouter une nouvelle règle de modération"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Ajouter et gérer du contenu"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr "Ajouter quand même"
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Ajouter du contenu"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
-msgstr "Ajouter des filtres"
+msgstr "Ajouter le filtre"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Ajouter des filtres pour personnaliser votre radio"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Ajouter à la file d'attente actuelle"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Ajouter aux favoris"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Ajouter à la liste de lecture…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
-msgstr "Ajouter à la file d’attente"
+msgstr "Ajouter à la liste d'attente"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
-msgstr "Ajouter à cette playlist"
+msgstr "Ajouter à cette liste de lecture"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
-msgstr "Ajouter une piste"
+msgstr "Ajouter la piste"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Admin"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administration"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Album"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Album contenant %{ count } piste, par %{ artist }"
-msgstr[1] "Album contenant %{ count } pistes, par %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Album"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
+#: front/src/views/admin/library/TrackDetail.vue:128
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Artiste de cet album"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
+msgstr "Données de l'album"
+
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Album name"
 msgstr "Nom de l'album"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Page de l'album"
-
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Albums"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Albums de cet·te artiste"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Tout"
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "Unique élément sélectionné"
+msgstr[1] "Tous les %{ count } éléments sélectionnés"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr "Autoriser l'application"
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+"Une erreur a eu lieu durant le processus de téléversement. Vous trouverez "
+"plus d'information ci-dessous."
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "Une erreur s'est produite pendant l'enregistrement de vos modifications"
 
+#: front/src/components/federation/FetchButton.vue:21
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Une erreur s'est produite pendant la mise à jour des données:"
+
+#: front/src/components/federation/FetchButton.vue:41
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Une erreur HTTP s'est produite en contactant le serveur distant"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
+msgstr "Une erreur inconnue s'est produite, le serveur est peut-être en panne ou injoignable"
+
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr "Une erreur inconnue a eu lieu"
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Application"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr "Détails de l'application"
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr "ID de l'application"
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
 msgstr ""
-"Une erreur inconnue s'est produite, le serveur est peut-être défaillant ou "
-"indisponible"
+"L'ID et le \"secret\" de l'application sont des données vraiment sensibles "
+"et doivent être traitées comme des mots de passe. Ne les partagez avec "
+"personne."
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/auth/ApplicationEdit.vue:25
+#, fuzzy
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr "Secret de l'application"
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "Approuver"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Approuvée"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr "Approuvée et appliquée"
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
-msgstr "Êtes-vous sur de vouloir vous déconnecter ?"
+msgstr "Êtes-vous sûr·e de vouloir vous déconnecter ?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artiste"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artiste"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
+msgstr "Données de l'artiste"
+
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Artist name"
 msgstr "Nom de l'artiste"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Page de l'artiste"
-
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artiste, album, piste…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artistes"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artistes"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
-msgstr "Ascendant"
+msgstr "Croissant"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
-msgstr "Demander à réinitialiser votre mot de passe"
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+msgstr "Demander la réinitialisation du mot de passe"
+
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Contenu audio"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Raccourcis du lecteur audio"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr "Autoriser %{ app }"
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr "Autoriser une application tierce"
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr "Applications autorisées"
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
-msgstr "Playlists disponibles"
+msgstr "Listes de lecture disponibles"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Retour à la page de connexion"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Retour aux paramètres"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
-msgstr "Bitrate"
+msgstr "Débit binaire"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "Bloquer tout"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"Bloquer tout depuis ce compte ou domaine. Cela empêche toute interaction "
-"avec l'entité, et purge le contenu lié (pistes, librairies, suivis, etc.)"
+msgstr "Bloquer tout de ce compte ou domaine. Cela empêche toute interaction avec l'entité, et purge le contenu lié (pistes, librairies, suivis, etc.)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Parcourir"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Parcourir la bibliothèque"
 
+#: front/src/components/library/Albums.vue:4
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Parcourir les albums"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Parcourir les artistes"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
-msgstr "Parcourir les playlists"
+msgstr "Parcourir les listes de lecture"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Parcourir les radios"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Éditeur"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "De %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
-msgstr ""
-"En cessant de suivre cette bibliothèque, vous perdez l’accès à son contenu."
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+msgstr "En cessant de suivre cette bibliothèque, vous perdez l’accès à son contenu."
+
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
-msgstr "Taille en cache"
+msgstr "Taille du cache"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Annuler"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Pistes candidates"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Mot de passe ne peut pas être changé"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
-msgstr ""
-"Impossible de transférer ce fichier, assurez-vous qu'il n'est pas trop gros"
+msgstr "Impossible de transférer ce fichier, assurez-vous qu'il n'est pas trop gros"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Changer la langue"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Changer mon mot de passe"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Changer le mot de passe"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Changer votre mot de passe"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
-msgstr "Changer le mot de passe ?"
+msgstr "Changer le mot de passe ?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Changements synchronisés avec le serveur"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
-msgstr "La mise à jour de votre mot de passe impactera également le mot de passe de l'API Subsonic si vous en avez demandé un."
+msgstr "La mise à jour de votre mot de passe changera également le mot de passe de l'API Subsonic si vous en avez demandé un."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
-msgstr "Modifier votre mot de passe aura les conséquences suivantes"
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
+msgstr "Modifier votre mot de passe aura les conséquences suivantes :"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Salle de discussion"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+"Cocher le périmètre \"Lecture\" ou \"Écriture\" sur le parent implique "
+"l'accès à tous les périmètres enfants correspondants."
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Choisissez votre instance"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Une bibliothèque musicale de qualité"
+#: front/src/components/library/EditForm.vue:75
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Effacer"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Effacer"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
-msgstr "Vider la playlist"
+msgstr "Vider la liste de lecture"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
-msgstr "Vider votre file d’attente"
+msgstr "Vider la liste d'attente"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
-msgstr "Écoutez de la musique pendant des heures, en un clic, grâce aux radios intégrées."
+msgstr "En un clic, écoutez de la musique pendant des heures grâce aux radios intégrées"
+
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+"Cliquer pour afficher plus d'information à propos du processus d'import pour "
+"cet envoi"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
-msgstr "Cliquer pour sélectionner les fichiers a téléverser ou glisser-déposer les fichiers ou répertoires"
+msgstr "Cliquez pour sélectionner les fichiers a téléverser ou glisser-déposer les fichiers ou répertoires"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "Fermer"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "Fermer"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr "Fermer et recharger la page"
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Code"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Réduire"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Configuration"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Confirmer"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Confirmer votre courriel"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Code de confirmation"
 
-#: front/src/components/common/ActionTable.vue:7
-msgid "Content have been updated, click refresh to see up-to-date content"
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr "Filtre de contenu ajouté avec succès"
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Filtres de contenu"
+
+#: front/src/components/auth/Settings.vue:116
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Filtres de contenu"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
 msgstr ""
-"Le contenu a été modifié, cliquez sur rafraîchir pour voir le contenu à jour"
+"Les filtres de contenu vous aident à cacher les contenus que vous ne voulez "
+"pas voir sur ce service."
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "Le contenu a été modifié, cliquez sur rafraichir pour voir le contenu à jour"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Contribuer"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Copier"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
-msgstr "Copier les pistes de la file d’attente dans la playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
+msgstr "Copier les pistes de la file d’attente dans la liste de lecture"
+
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr "Copiez-coller le code suivant dans votre application:"
 
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
-msgstr "Copiez/collez ce code dans votre site web HTML"
+msgstr "Copiez-collez ce code dans le HTML de votre site web"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Copyright"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Nous n'avons pas pu confirmer votre adresse de courriel"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Impossible de récupérer la bibliothèque distante"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-"Une erreur s'est produite lors du traitement de cette piste, assurez-vous "
-"que la piste est correctement étiquetée"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
-msgstr "Pochettes d'albums, paroles, notre but est de tout implémenter ;)"
+msgstr "Pochettes, paroles, notre but est de tout gérer ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Créer"
 
 #: front/src/components/auth/Signup.vue:4
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Créer un compte Funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Créer une nouvelle application"
+
+#: front/src/components/auth/Settings.vue:220
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Créer une nouvelle application"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Créer une nouvelle bibliothèque"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
-msgstr "Créer une nouvelle playlist"
+msgstr "Créer une nouvelle liste de lecture"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Créer un compte"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Créer une application"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
-msgstr "Créer une bibliothèque"
+msgstr "Créer la bibliothèque"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Créer mon compte"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr "Créez-en une pour intégrer Funkwhale avec des applications tierces."
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
-msgstr "Créer une playlist"
+msgstr "Créer la liste de lecture"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Créer votre propre radio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Date de création"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Avatar actuel"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Bibliothèque actuelle"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Piste actuelle"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Utilisation actuelle"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+"Les données renvoyées par le serveur distant ont des attributs manquants ou "
+"invalides"
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr "Les données ont été rafraîchies avec succès depuis le serveur distant."
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Date"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Informations de débogage"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Diminuer le volume"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Supprimer"
 
+#: front/src/components/auth/Settings.vue:254
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Supprimer l'application"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr "Supprimer l'application \"%{ application }\"?"
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Supprimer la bibliothèque"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Supprimer la règle de modération"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
-msgstr "Supprimer la playlist"
+msgstr "Supprimer la liste de lecture"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Supprimer la radio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Supprimer cet album ?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Supprimer cet artiste ?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
-msgstr "Supprimer cette bibliothèque ?"
+msgstr "Supprimer cette bibliothèque ?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
-msgstr "Supprimer cette règle de modération ?"
-
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+msgstr "Supprimer cette règle de modération ?"
+
+#: front/src/components/library/EditCard.vue:94
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Supprimer cette suggestion ?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Supprimer cet envoi ?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
-msgstr "Descendant"
+msgstr "Décroissant"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Description"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Détail"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Description"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Détails"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Déterminez la quantité de contenu que l'utilisateur peut importer. Laissez vide pour utiliser la valeur par défaut de l'instance."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
-msgstr "Déterminer le niveau de visibilité de votre activité"
+msgstr "Détermine le niveau de visibilité de votre activité"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Désactiver l'accès"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Désactiver l'accès via Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Désactiver l'accès à l'API Subsonic ?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Désactivé"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
-msgstr "Découvrez comment utiliser Funkwhale sur d'autres applications"
+msgstr "Découvrez comment utiliser Funkwhale depuis d'autres applications"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Nom d'affichage"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Afficher publiquement"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Ne télécharger aucun média (audio, album, couverture, avatar de compte...) "
-"de ce compte ou domaine. Cela purgera aussi le contenu existant."
+msgstr "Ne jamais télécharger de médias (audio, album, couverture, avatar de compte...) de ce compte ou domaine. Cela purgera aussi le contenu existant."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
-msgstr "Voulez-vous vider la playlist \"%{ playlist }\" ?"
+msgstr "Voulez-vous vider la liste de lecture « %{ playlist } » ?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Souhaitez-vous confirmer cette action ?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
-msgstr "Voulez-vous supprimer la playlist \"%{ playlist }\" ?"
+msgstr "Voulez-vous supprimer la liste de lecture « %{ playlist } » ?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Voulez-vous supprimer la radio « %{ radio } » ?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Voulez-vous cacher le contenu de l’artiste « %{ name } » ?"
+
+#: front/src/components/common/ActionTable.vue:37
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
-msgstr[0] "Voulez-vous effectuer l'action \"%{ action } sur %{ count } élément ?"
-msgstr[1] "Voulez-vous effectuer l'action \"%{ action } sur %{ count } éléments ?"
+msgstr[0] "Voulez-vous effectuer l'action « %{ action } » sur %{ count } élément ?"
+msgstr[1] "Voulez-vous effectuer l'action « \"%{ action } » sur %{ count } éléments ?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
-msgstr "Souhaitez-vous restaurer votre file d’attente précédente ?"
+msgstr "Souhaitez-vous restaurer la dernière liste d'attente ?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Documentation"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Domaine"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Domaines"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Télécharger"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
-msgstr "Glissez et déposer les lignes pour réordonner les pistes dans la playlist"
+msgstr "Glissez et déposer les lignes pour réordonner les pistes dans la liste de lecture"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Durée"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Courriel confirmé"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Simple à utiliser"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Éditer"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Éditer"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Erreur lors du traitement de l'action"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
-msgstr "Éditer les informations de cette instance"
+msgstr "Éditer les informations concernant cette instance"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Mettre à jour les règles de modération"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Modifier cette piste"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Éditer…"
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Modifier cette piste"
+
+#: front/src/components/library/TrackEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Modifier cette piste"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Éditer"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Éditer"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Courriel"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Adresse de courriel"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Insérer"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "Code inséré"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr "Insérez cet album dans votre site web"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Insérez cet·te artiste dans votre site web"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "Insérez cette piste dans votre site web"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
-msgstr "Suivis de librairies émis"
+msgstr "Suivi de la bibliothèque émise"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr "Messages émis"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "Activé"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Terminer l'édition"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Saisissez une URL de bibliothèque"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Saisissez un nom de radio…"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr "Entrer le titre de l’album…"
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Saisissez un nom d'artiste…"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Saisissez un nom de playlist…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Saisissez l'adresse de courriel associée à votre compte"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Saisissez votre courriel"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Saisissez votre code d'invitation (insensible à la casse)"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Saisissez votre recherche…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Saisissez votre nom d'utilisateur·rice"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Saisissez votre nom d'utilisateur·rice ou courriel"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Erreur"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Rapports d'erreur"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Rapports d'erreur"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "En erreur"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Erreur lors du traitement de l'action"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
-msgstr "Erreur pendant la demande de réinitialisation de mot de passe"
+msgstr "Erreur lors de la demande de réinitialisation de mot de passe"
+
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Erreur lors du traitement de l'action"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Erreur pendant le changement de mot de passe"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Erreur lors de la création du domaine"
 
+#: front/src/components/moderation/FilterModal.vue:13
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Erreur lors de la création de la règle"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Erreur lors de la création de l'invitation"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Erreur lors de la création de la règle"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Erreur lors de la création de l'invitation"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Erreur lors de la récupération des informations du nœud"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Erreur pendant l'enregistrement des paramètres"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Erreur pendant l'enregistrement des paramètres"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Erreur durant l'envoi des modifications"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "En erreur"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Fichiers erronés"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Tout le monde"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Tout le monde sur cette instance"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+#, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Tout le monde, sur toutes les instances"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Exclure"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Date d'expiration"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Expirée"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Expirée/utilisée"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
-"Expliquez pourquoi vous appliquez cette règle. En fonction de votre "
-"configuration d'instance, cela vous aidera à vous rappeler pourquoi vous "
-"avez agis sur ce compte ou domaine, et peut être affiché publiquement pour "
-"aider les utilisateurs à comprendre quelles règles de modération sont en "
-"place."
+msgstr "Expliquez pourquoi vous appliquez cette règle. En fonction de votre configuration d'instance, cela vous aidera à vous rappeler pourquoi vous avez agis sur ce compte ou domaine, et peut être affiché publiquement pour aider les utilisateurs à comprendre quelles règles de modération sont en place."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "Échoué"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Pistes échouées :"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Pistes échouées :"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Favoris"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Favoris"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Fédération"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Fédération"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr "Champ"
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nom du fichier"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Fichiers"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Nom du filtre"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Terminé"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr "Découverte"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Date de découverte"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Suivre"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Suivre des bibliothèques distantes"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Demande de suivi en attente de validation"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Abonnés"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Abonnés"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Abonné"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "De l'album %{ album } par %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Suivre"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr "De l’album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> par <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Désactiver l'accès"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale est compatible avec d'autres lecteurs de musique qui supportent l'API Subsonic."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale est très simple à utiliser."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale est conçu pour faciliter l'écoute des musiques que vous aimez et découvrir de nouveaux artistes."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale est gratuit et vous donne le contrôle sur votre musique."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale prend soin de votre musique"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "Raccourcis généraux"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Obtenir une nouvelle invitation"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
-msgstr "Amenez moi à la bibliothèque"
+msgstr "Amenez-moi à la bibliothèque"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "Obtenez des métadonnées de qualité pour votre musique grâce à <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Commencer"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Obtenir de l'aide"
+
 #: front/src/components/Footer.vue:37
+#, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "Obtenir de l'aide"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Aller"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Retourner à la page d'accueil"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Artistes caché·e·s"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr "Cacher le contenu du compte ou du domaine, sauf aux abonnés."
 
+#: front/src/components/moderation/FilterModal.vue:40
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Cacher le contenu"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr "Cacher le contenu de cet·te artiste"
+
+#: front/src/components/audio/Player.vue:615
+#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr "Cacher le contenu de cet·te artiste"
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Accueil"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Heures de musique"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Cependant, accéder à Funkwhale depuis ces clients requiert un mot de passe distinct que vous pouvez configurer ci-dessous."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Si l'adresse email que vous avez fournie est valide et associée à un compte utilisateur, vous allez recevoir un email contenant les instructions de réinitialisation au cours des prochaines minutes."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Date d'import"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importez de la musique de différentes plate-formes, comme YouTube ou Soundcloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Statut de l'importation"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Référence de l'importation"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Statut de l'importation"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+#, fuzzy
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
-msgstr "Status de l'import"
+msgstr "Statut de l'importation"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importé"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Date d'import"
+#: front/src/components/federation/FetchButton.vue:47
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr "Impossible de se connecter à l'URL renseignée"
+
+#: front/src/components/moderation/FilterModal.vue:26
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Dans le widget \"Ajoutés récemment\""
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr "Dans les listes d'artistes et d'albums"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "Dans les favoris"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr "Dans les favoris des autres utilisateurs et dans l'historique d'écoute"
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr "Dans les suggestions radio"
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Inactif"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "Augmenter le volume"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Saisissez l'adresse de courriel liée à votre compte"
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Insérer depuis la queue (%{ count } piste)"
 msgstr[1] "Insérer depuis la queue (%{ count } pistes)"
 
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Adresse de l'instance"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Informations de l'instance"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Informations relatives à cette instance"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Radios de l'instance"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Paramètres de l'instance"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Adresse de l'instance"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr "Mauvais type de fichier, assurez-vous de charger un fichier audio. Les formats de fichiers supportés sont %{ extensions }"
+
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
-"Mauvais type de fichier, assurez-vous de charger un fichier audio. Les "
-"formats de fichiers supportés sont %{ extensions }"
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Code d'invitation"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Code d'invitation (optionnel)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Invitations"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
-msgstr "Issue tracker"
+msgstr "Suivi des problèmes"
+
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr "Impossible de se connecter à l'URL renseignée"
 
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
-msgstr "Gardez une trace de vos chansons favorites"
+msgstr "Sauvegardez vos chansons favorites"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
-msgstr "Raccouris clavier"
+msgstr "Raccourcis clavier"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Comptes connus"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Bibliothèques connues"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Dernière activité"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "Dernière vérification"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Dernière modification"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "Vu pour la dernière fois"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Date de dernier aperçu"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
-msgstr "Dernière mise a jour :"
+msgstr "Dernière mise à jour :"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Démarrer"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
-msgstr "En apprendre plus à propos de cette instance"
+msgstr "En savoir plus à propos de cette instance"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Laisser vide pour obtenir un code aléatoire"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Laisser vide pour un widget adaptatif"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Bibliothèques"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Bibliothèques"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Bibliothèque mise à jour"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "Les bibliothèques vous aident à organiser et à partager votre collection de musique. Vous pouvez téléverser votre bibliothèque musicale sur Funkwhale et la partager avec vos amis et votre famille."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Bibliothèque"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Bibliothèque créée"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Bibliothèque mise à jour"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Bibliothèque supprimée"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
-msgstr "Fichiers de la bibliothèque"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
+msgstr "Modifications de la bibliothèque"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Bibliothèque mise à jour"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "Licence"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+#, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Chargement des abonnés…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Chargement des abonnés…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Chargement des bibliothèques…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Chargement des données de la bibliothèque…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Chargement des notifications…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
-msgstr "Chargement de bibliothèques distantes…"
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "Chargement des bibliothèques distantes…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Chargement des données d'utilisation…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Chargement de vos favoris…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+#, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Compte local"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Connexion"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
-msgstr "Connectez vous à votre compte Funkwhale"
+msgstr "Connectez-vous à votre compte Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Déconnexion"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Connecté·e en tant que %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Connexion"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Statut de connexion"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Déconnexion"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
-msgstr ""
-"On dirait que vous n'avez pas encore de bibliothèque, il est temps d'en "
-"créer une."
+msgstr "On dirait que vous n'avez pas encore de bibliothèque, il est temps d'en créer une."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
-msgstr "Répétition désactivée. Cliquez pour activer la répétition sur la piste actuelle."
+msgstr "Répétition désactivée. Cliquez ici pour activer la répétition sur la piste actuelle."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
-msgstr ""
-"Répétition sur la piste en cours. Cliquer pour répéter sur l'intégralité de "
-"la file d’attente."
+msgstr "Répétition sur la piste en cours. Cliquez pour répéter l'intégralité de la liste d'attente."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
-msgstr "\"Répétition sur l'intégralité"
-
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Paroles"
+msgstr "Répétition de l'intégralité de la liste d'attente, cliquez pour désactiver la répétition."
 
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "Menu principal"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Gérer la bibliothèque"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
-msgstr "Gérer les playlists"
+msgstr "Gérer les listes de lecture"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Gérer les utilisateur·rices"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
-msgstr "Gérer vos playlists"
+msgstr "Gérer vos listes de lecture"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Tout marquer comme lu"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Marquer comme lu"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Marquer comme non lu"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "Mo"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr "Lecteur média"
 
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Membre depuis le %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "Applications mobiles et de bureau"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+#, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Modération"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
-"Les règles de modération vous aident à contrôler comment votre instance "
-"interagi avec un domaine ou compte donné."
+msgstr "Les règles de modération vous aident à contrôler comment votre instance interagit avec un domaine ou compte donné."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Modification %{ id }"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Date de modification"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Musique"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Couper le son"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Masquer l’activité"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Masquer les notifications"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Mon compte"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Ma description géniale"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Ma bibliothèque d'enfer"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
-msgstr "Ma playlist d'enfer"
+msgstr "Ma liste de lecture d'enfer"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Ma radio d'enfer"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Mes bibliothèques"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "ND"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nom"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nom"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nom"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nouveau mot de passe"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Les nouvelles pistes seront ajoutées ici automatiquement."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr "Nouvelle valeur"
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Piste suivante"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Non"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Pas d'addons ou d'extension à installer, il vous suffit d'une bibliothèque sur le web"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Aucun album ne correspond à votre recherche"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Aucun·e artiste ne correspond à votre recherche"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
-msgstr "Pas de paroles disponibles pour cette piste."
+#: front/src/components/library/TrackDetail.vue:14
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
+msgstr "Aucune information sur les droits d'auteur n'est disponible pour cette piste"
+
+#: front/src/components/library/TrackDetail.vue:25
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Aucune information de licence pour cette piste"
 
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Aucune bibliothèque correspondante."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
 msgstr "Pas encore de notifications."
 
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr "Aucun résultat n'a été trouvé."
+
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Personne à part moi"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Personne ne suit cette bibliothèque"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
-msgstr "Pas utilisé"
+msgstr "Non utilisé"
+
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Notifications"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Notifications"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Site officiel"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Ancien mot de passe"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr "Ancienne valeur"
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Accès libre"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Mettre à jour les règles de modération"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Ouvrir le profil"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Voir sur MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "Ouvrir le profil"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Ouvrir le profil"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Ouvrir le site web"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "Ou personnalisez votre règle"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Ordre"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
-msgstr "Ordre"
-
-#: front/src/components/library/Artists.vue:23
+msgstr "Trier par"
+
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
-msgstr "Direction"
+msgstr "Sens"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Propriétaire"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Page non trouvée"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
-msgstr "Page non trouvée !"
+msgstr "Page introuvable !"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr "Pagination"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Mot de passe"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Mot de passe mis à jour"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Mot de passe modifié avec succès"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Mettre en pause"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr "Mettre en pause/jouer la piste en cours"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "En pause"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "En attente"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "En attente de validation"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Fichiers en attente"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Demandes d'abonnement en attente"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Vérification en attente"
+
+#: front/src/components/Sidebar.vue:226
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Vérification des modifications en attente"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Permissions"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Permissions"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Jouer"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Tout lire"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Lire tous les albums"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Lire ensuite"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Jouer la piste suivante"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Lire maintenant"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Jouer la piste précédente"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr "Jouer des chansons similaires"
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Jouer cette piste"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Jouer"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Jouer…"
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
-msgstr "Playlist"
+msgstr "Liste de lecture"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Playlist contenant %{ count } piste, par %{ username }"
 msgstr[1] "Playlist contenant %{ count } pistes, par %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Playlist créée"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Éditeur de playlist"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nom de la playlist"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Playlist mise à jour"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Visibilité de la playlist"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Listes de lecture"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
-msgstr "Playlists"
+msgstr "Listes de lecture"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "Les playlists ? Elles sont là !"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Merci de vérifier que votre mot de passe est correct"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Merci de vérifier que votre nom d'utilisateur et mot de passe sont corrects"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF ou JPG. 2Mo maximum. L'image sera réduite à 400×400 pixels."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Pagination"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
-"Empêche le compte ou domaine de déclencher des notifications, sauf pour les "
-"abonnés."
+msgstr "Empêche le compte ou domaine de déclencher des notifications, sauf pour les abonné·e·s."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "Aperçu"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Piste précédente"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Problème lors de l'analyse"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Continuer"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Poursuivre vers la page de connexion"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "En cours de traitement"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Ouvrir le profil"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1896,1108 +3205,1973 @@ msgstr "En cours de traitement"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Supprimer"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Supprimer les fichiers erronés ?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Supprimer les fichiers en attente ?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Supprimer les fichiers oubliés ?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "File d’attente"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "La file d’attente a été mélangée !"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Éditeur de radio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Radio créée"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nom de la radio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Radio mise à jour"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radios"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radios"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr "Raison"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr "Suivis de bibliothèque reçus"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "Messages reçus"
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Ajoutés récemment"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Ajoutés récemment"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Récemment ajouté aux favoris"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Écouté récemment"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Rafraîchir"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Rafraîchir"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr "Rafraîchir les informations du nœud"
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Rafraîchir les informations du nœud"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "Rafraîchir le contenu de la table"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Inscrit·e depuis le %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "Les inscriptions sont fermées sur cette instance, vous aurez besoin d'un code d'invitation pour vous inscrire."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "utilisateur·rice standard·e"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Rejeter"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Rejeter le média"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Rejeté"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Relancer l'importation"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Date de dernier aperçu"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Bibliothèques distantes"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Les bibliothèques distantes appartiennent à d'autres utilisateurs du réseau. Vous pouvez y accéder tant qu'elles sont publiques ou qu'on vous en donne l'accès."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Retirer"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Supprimer mon avatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Supprimer mon avatar"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Retirer des favoris"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
-"Les pistes importées qui n'ont pas encore été complètement traitées par le "
-"serveur seront supprimées complètement. Le quota correspondant vous sera "
-"restitué."
+msgstr "Les pistes importées qui n'ont pas encore été complètement traitées par le serveur seront supprimées complètement. Le quota correspondant vous sera restitué."
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
-"Les pistes téléversées mais ignorées pendant l'importation pour diverses "
-"raisons seront supprimées complètement. L'espace de stockage correspondant "
-"vous sera restitué."
+msgstr "Les pistes téléversées mais ignorées pendant l'importation pour diverses raisons seront supprimées complètement. L'espace de stockage correspondant vous sera restitué."
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr ""
-"Les pistes téléversées mais pas encore complètement traitées pas le serveur "
-"seront supprimées. L'espace de stockage correspondant vous sera restitué."
+msgstr "Les pistes téléversées mais pas encore complètement traitées pas le serveur seront supprimées. L'espace de stockage correspondant vous sera restitué."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Demander un nouveau mot de passe"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Demander un nouveau mot de passe pour l'API Subsonic ?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Demander un mot de passe"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Réinitialiser votre mot de passe"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Relancer l'importation"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Résultats par page"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Retourner à la page de connexion"
 
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Afficher les fichiers"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "Règle"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Enregistrer"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Scan démarré"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Analyser maintenant"
 
-#: front/src/views/content/remote/Card.vue:166
-msgid "Scan skipped (previous scan is too recent)"
-msgstr "Scan sauté (le scan précédent est trop récent)"
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Croissant"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "Analyse en attente"
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
+msgid "Scan skipped (previous scan is too recent)"
+msgstr "Scan non lancé (le scan précédent est trop récent)"
 
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Analyse démarrée"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Scanné avec des erreurs"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Analyse en cours… (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Rechercher"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Rechercher une bibliothèque distante"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
-msgstr "Rechercher par domaine, nom d'utilisateur·trice, bio…"
+#: front/src/components/manage/library/EditsCardList.vue:211
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Rechercher par titre, artiste, domaine…"
 
-#: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
-msgstr "Rechercher par nom…"
+#: front/src/components/manage/library/LibrariesTable.vue:191
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Rechercher par domaine, nom d'utilisateur·rice, bio…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
-msgid "Search by title, artist, album…"
-msgstr "Rechercher par titre, artiste, album…"
+#: front/src/components/manage/library/UploadsTable.vue:241
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Rechercher par domaine, nom d'utilisateur·rice, bio…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "Rechercher par titre, artiste, domaine…"
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Rechercher par domaine, nom d'utilisateur·rice, bio…"
 
-#: front/src/components/manage/users/InvitationsTable.vue:153
-msgid "Search by username, e-mail address, code…"
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Rechercher par titre, artiste, album…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Rechercher par titre, artiste, album…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Rechercher par domaine, nom d'utilisateur·rice, bio…"
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Rechercher par nom…"
+
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
+msgid "Search by title, artist, album…"
+msgstr "Rechercher par titre, artiste, album…"
+
+#: front/src/components/manage/users/InvitationsTable.vue:153
+#, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
+msgid "Search by username, e-mail address, code…"
 msgstr "Rechercher par nom d'utilisateur·rice, courriel, code…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Rechercher par nom d'utilisateur·rice, courriel, nom…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Rechercher des artistes, albums, pistes…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Rechercher de la musique"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Rechercher sur lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Rechercher sur Wikipédia"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr "Menu secondaire"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Sections"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Sélectionner un filtre"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
 #, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
-msgstr[0] "Selectionner l'ensemble des %{ total } élément"
-msgstr[1] "Selectionner l'ensemble des %{ total } éléments"
+msgstr[0] "Sélectionner l'ensemble de %{ total } élément"
+msgstr[1] "Sélectionner l'ensemble des %{ total } éléments"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Sélectionner seulement la page actuelle"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Paramètres"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Paramètres mis à jour"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Paramètres modifiés avec succès."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Lien de partage"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"Partagez ce lien avec d'autres utilisateurs afin qu'ils puissent demander "
-"l'accès à votre bibliothèque."
+msgstr "Partagez ce lien avec d'autres utilisateurs afin qu'ils puissent demander l'accès à votre bibliothèque."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Lien de partage"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "Afficher %{ count } autre piste"
 msgstr[1] "Afficher %{ count } autres pistes"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Montrer 1 album supplémentaire"
 msgstr[1] "Montrer %{ count } albums supplémentaires"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "Montrer les raccourcis clavier disponibles"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Afficher les notifications lues"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Afficher/masquer le mot de passe"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Affichage des résultats %{ start }-%{ end } sur %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Mélanger la file d'attente"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Mélanger votre file d’attente"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Inscription"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Inscription"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Date d'inscription"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
-msgstr "Rendre l'activité silencieuse"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "Rendre les notifications silencieuses"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+#, fuzzy
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Taille"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Taille"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Ignoré"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Fichiers ignorés"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "Logiciel"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Désolé, la page demandée n’existe pas :"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Code source"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Membre de l'équipe"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Démarrer"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Arrêter la radio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Statistiques"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
-"Les statistiques sont calculées depuis les activités connues et le contenu "
-"sur votre instance, et ne reflètent pas l'activité générale de ce compte"
+msgstr "Les statistiques sont calculées depuis les activités connues et le contenu sur votre instance, et ne reflètent pas l'activité générale de ce compte"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
-"Les statistiques sont calculées depuis les activités connues et le contenu "
-"sur votre instance, et ne reflètent pas l'activité générale de ce domaine"
+msgstr "Les statistiques sont calculées depuis les activités connues et le contenu sur votre instance, et ne reflètent pas l'activité générale de ce domaine"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "Les statistiques sont calculées depuis les activités connues et le contenu sur votre instance, et ne reflètent pas l'activité générale de ce compte"
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Statut"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Statut"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Statut"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Statut"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Statut"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Arrêter"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Statut"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Arrêter la radio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Valider"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Mot de passe de l'API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Nous ne pouvons pas charger cette piste"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Nous ne pouvons pas charger cette piste"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Nous ne pouvons pas charger cette piste"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Suggestions"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Résumé"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "Forum d'aide"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr "Extensions supportées: %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Synchronisation des changements avec le serveur…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "La texte a été copié dans le presse-papier !"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "C'est simple : nous adorions Grooveshark et nous voulions construire quelque chose d'encore mieux."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "Le logo de Funkwhale a été généreusement dessiné et fourni par Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr "La bibliothèque et toutes ses pistes seront supprimées. Cette action est irréversible."
+
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
 msgstr ""
-"La bibliothèque et toutes ses pistes seront supprimées. Cette action est "
-"irréversible."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr "Les fichiers musicaux que vous téléversez sont correctement tagués :"
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
-msgstr "La piste suivante va se jouer automatiquement dans quelques secondes..."
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "La piste suivante va se jouer automatiquement dans quelques secondes…"
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "La plateforme est gratuite et open-source, vous pouvez l'installer et la modifier sans restrictions"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Playlist créée"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Cette action est irréversible."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "L'API Subsonic n'est pas disponible sur cette instance Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Nous ne pouvons pas ajouter cette piste à une playlist"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Cette action est irréversible."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Les fichiers musicaux uploadés sont au format OGG, Flac ou MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
-msgstr ""
-"Il y a différentes manières de récupérer du nouveau contenu et de le rendre "
-"disponible ici."
+msgstr "Il y a différentes manières de récupérer du nouveau contenu et de le rendre disponible ici."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "Cette action est irréversible."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Cet album est présent dans les bibliothèques suivantes :"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Cet⋅te artiste est présent⋅e dans les bibliothèques suivantes :"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr "Ce domaine est sujet à des règles de modération spécifiques"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr "Cette instance offre jusque %{quota} d'espace disque à chaque utilisateur."
+
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
 msgstr ""
-"Cette instance offre jusque %{quota} d'espace disque à chaque utilisateur."
 
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "C'est vous !"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
-msgstr ""
-"Cette bibliothèque contient ma musique personnelle, j'espère que vous "
-"l'aimerez."
+msgstr "Cette bibliothèque contient ma musique personnelle, j'espère que vous l'aimerez."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
-"Cette bibliothèque est privée et son propriétaire doit vous approuver pour "
-"accéder à son contenu"
+msgstr "Cette bibliothèque est privée et son propriétaire doit vous approuver pour accéder à son contenu"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
-msgstr ""
-"Cette bibliothèque est publique et vous pouvez accéder à son contenu "
-"librement"
+msgstr "Cette bibliothèque est publique et vous pouvez accéder à son contenu librement"
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
+msgstr "Cela peut affecter de nombreux éléments ou avoir des conséquences irréversibles, merci de vérifier que c'est bien ce que vous souhaitez."
+
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
 msgstr ""
-"Cela peut affecter de nombreux éléments ou avoir des conséquences "
-"irréversibles, merci de vérifier que c'est bien ce que vous souhaitez."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Cette référence sera utilisée pour regrouper les fichiers importés."
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Le traitement de cette piste a échoué, assurez-vous qu’elle est correctement étiquetée"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "La piste est importée mais n'a pas encore été traitée par le serveur"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "La piste est déjà présente dans l'une de vos bibliothèques"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
-msgstr ""
-"Cette piste n'est pas accessible dans les bibliothèques auxquelles vous avez "
-"accès"
+msgstr "Cette piste n'est pas accessible dans les bibliothèques auxquelles vous avez accès"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Cette piste est présente dans les bibliothèques suivantes :"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Cela supprimera définitivement cette playlist et ne pourra pas être annulé."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Cela supprimera définitivement cette radio et ne pourra pas être annulé."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Cela désactivera complétement l'accès à l'API Subsonic depuis votre compte."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr ""
-"Cela effacera vos données locales et vous déconnectera, voulez-vous "
-"continuer ?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Cela vous déconnectera sur l'ensemble de vos appareils utilisant ce mot de passe."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Cela supprimera définitivement cette playlist et ne pourra pas être annulé."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Cela supprimera toutes les pistes de la playlist et ne pourra pas être annulé."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Titre"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Titre"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
 msgid "Title"
 msgstr "Titre"
 
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr "Basculer la boucle de file d'attente"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "Taille totale"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Taille totale des fichiers de cette bibliothèque"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Nombre total d'utilisateurs"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Piste"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "La piste est déjà présente dans l'une de vos bibliothèques"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Piste"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Nom de la piste"
+
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Information de la piste"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Piste correspondant au filtre"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Nom de la piste"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "La piste est importée mais n'a pas encore été traitée par le serveur"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Pistes"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "pistes"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Pistes"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Pistes par cetâ‹…te artiste"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Pistes en favoris"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "pistes écoutées"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Piste correspondant au filtre"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Type"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Type"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
 msgstr "Sous règle de modération"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Se désabonner"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Se désabonner de cette bibliothèque ?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "Malheureusement, les gestionnaires de cette instance n'ont pas encore pris le temps de compléter cette page."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Musique illimitée"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Réactiver le son"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Mettre à jour"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Mettre à jour la playlist"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Mettre à jour l'avatar"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Mettre à jour la bibliothèque"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "Mettre à jour les règles de modération"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Mettre à jour la playlist"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Mettre à jour les paramètres"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Mettre à jour votre mot de passe"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Envoi"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Téléverser un nouvel avatar"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Téléverser du contenu audio"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Date d'envoi"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Date d'envoi"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "Import refusée, assurez-vous que le fichier n'est pas trop gros et que vous n'avez pas atteint votre quota"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
-"Import refusée, assurez-vous que le fichier n'est pas trop gros et que vous "
-"n'avez pas atteint votre quota"
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr ""
-"Importez des fichiers musicaux (MP3, OGG, Flac, etc.) depuis votre "
-"bibliothèque personnelle directement depuis votre navigateur pour en "
-"profiter ici."
+msgstr "Importez des fichiers musicaux (MP3, OGG, Flac, etc.) depuis votre bibliothèque personnelle directement depuis votre navigateur pour en profiter ici."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Téléverser de nouveaux morceaux"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Quota d’envoi"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Dépassement du délai d'envoi, veuillez réessayer"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Téléversé"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Envoi en cours"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Envoi en cours…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Téléversements"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Téléversements"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "Téléversements"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Utiliser une autre instance"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
-msgstr ""
-"Utilisez ce formulaire pour demander à réinitialiser votre mot de passe. "
-"Vous recevrez un courriel à l'adresse indiquée contenant les instructions de "
-"réinitialisation."
+msgstr "Utilisez ce formulaire pour demander à réinitialiser votre mot de passe. Vous recevrez un courriel à l'adresse indiquée contenant les instructions de réinitialisation."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
-"Utilisez ce paramètre pour activer/désactiver temporairement la règle sans "
-"complètement la supprimer."
+msgstr "Utilisez ce paramètre pour activer/désactiver temporairement la règle sans la supprimer complètement."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Utilisé"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Utilisateur·rice"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Activité des utilisateur·ice·s"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Bibliothèques utilisateur"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Radios des utilisateur·ice·s"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nom d'utilisateur"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nom d'utilisateur ou email"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "utilisateur·rice·s"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Utilisateur·ice·s"
 
 #: front/src/components/Footer.vue:29
+#, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "Utiliser Funkwhale"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Version %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Afficher les fichiers"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Voir sur MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Visibilité"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Visibilité : tout le monde sur cette instance"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Visibilité : tout le monde, y compris les autres instances"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Visibilité : personne sauf moi"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Visibilité"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr "Volume %{ number }"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Nous ne pouvons pas ajouter cette piste à une playlist"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Nous ne pouvons pas créer cette playlist"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Nous ne pouvons pas créer votre compte"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "Nous ne pouvons pas charger cette piste"
+#: front/src/components/federation/FetchButton.vue:69
+#, fuzzy
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Chargement de vos favoris…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Erreur lors de la connexion"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Nous ne pouvons pas enregistrer votre avatar"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Nous ne pouvons pas enregistrer vos paramètres"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Création de votre compte impossible."
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Nous ne vous pistons pas et ne vous exposons pas à des publicités"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "Nous n'avons aucune information de copyright pour cette piste"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "Nous n'avons aucune information de licence pour cette piste"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "nous vous recommandons d'utiliser le logiciel Picard pour cela."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Nous pensons que l'accès à la musique devrait être simple."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Désolé, la page demandée n’existe pas :"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Bienvenue"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Bienvenue sur Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Pourquoi Funkwhale ?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "Hauteur du widget"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "Largeur du widget"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Oui"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Oui, déconnectez-moi !"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
-msgstr ""
-"Vous pouvez partager votre bibliothèque avec d'autres personnes, quelle que "
-"soit sa visibilité."
+msgstr "Vous pouvez partager votre bibliothèque avec d'autres personnes, quelle que soit sa visibilité."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Vous êtes sur le point de transférer de la musique dans votre bibliothèque. Avant de procéder, veuillez vous assurer que :"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Vous êtes actuellement connecté·e en tant que %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Vous pouvez suivre les bibliothèques d'autres utilisateurs pour avoir accès à de la nouvelle musique. Les bibliothèques publiques peuvent être suivies immédiatement, tandis que le suivi d'une bibliothèque privée nécessite l'approbation de son propriétaire."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Vous pouvez inviter vos ami·es et votre famille sur votre instance pour qu'ils·elles puissent profiter de votre musique"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Vous pouvez maintenant utiliser le service sans limitations."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Vous pouvez utiliser cette interface pour réaliser votre propre radio personnalisée, qui jouera les pistes correspondant aux critères indiqués."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Vous pouvez les utiliser pour profiter de vos playlists et de votre musique en mode hors-ligne sur votre smatphone ou tablette, par exemple."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Vous n'avez aucune règle en place pour ce compte."
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Vous n'avez aucune règle en place pour ce compte."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr "Vous n'avez aucune règle en place pour ce compte."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr "Vous n'avez aucune règle en place pour ce domaine."
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
+msgstr ""
+
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Vous écoutez une radio"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
-msgstr "Il se peut que vous ailliez des problèmes de connexion."
-
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Vous devez choisir une instance pour continuer"
+msgstr "Il se peut que vous ayez des problèmes de connexion."
 
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Vous allez être déconnecté⋅e de cette session et vous devrez vous connecter avec votre nouveau mot de passe"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Vous devrez mettre à jour votre mot de passe sur l'ensemble des clients utilisant ce mot de passe."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Playlist créée"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Vos notifications"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Vos favoris"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "Votre musique, à votre façon"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Vos notifications"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Votre mot de passe a été mis à jour avec succès."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Paramètres mis à jour"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "Votre mot de passe Subsonic sera remplacé par un nouveau mot de passe aléatoire, ce qui vous déconnectera de tous les appareils utilisant l'ancien mot de passe"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Pagination"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Copyright"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Album contenant %{ count } piste, par %{ artist }"
+msgstr[1] "Album contenant %{ count } pistes, par %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } piste a été ajoutée à votre liste d'attente"
+msgstr[1] "%{ count } pistes ont été ajoutées à votre liste d'attente"
diff --git a/front/locales/gl/LC_MESSAGES/app.po b/front/locales/gl/LC_MESSAGES/app.po
index 06cd843c1593e1967abe91cbfa1130f31eb19cab..265433abf0bfda2cee9946f93652edff3f29ee68 100644
--- a/front/locales/gl/LC_MESSAGES/app.po
+++ b/front/locales/gl/LC_MESSAGES/app.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 16:04+0100\n"
-"PO-Revision-Date: 2019-01-17 08:33+0000\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-03-05 05:58+0000\n"
 "Last-Translator: Xosé M <xosem@disroot.org>\n"
 "Language-Team: none\n"
 "Language: gl\n"
@@ -19,1924 +19,3251 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\", de %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } de %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(baldeiro)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Conecte coa súa conta Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } de %{ total } seleccionado"
 msgstr[1] "%{ count } de %{ total } seleccionados"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } canción"
 msgstr[1] "%{ count } cancións"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+#, fuzzy
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } canción en %{ albumsCount } álbumes"
 msgstr[1] "%{ count } cancións en %{ albumsCount } álbumes"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } canción coicidente cos filtros combinados"
 msgstr[1] "%{ count } cancións coincidentes cos filtros combinados"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "Engadiuse %{ count } canción a cola"
-msgstr[1] "Engadíronse %{ count } cancións a cola"
-
 #: front/src/components/playlists/Card.vue:18
+#, fuzzy
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} canción"
 msgstr[1] "%{ count } cancións"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ current } utilizado de %{ max } permitido"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } h %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
 msgstr "%{ username } aceptou o seu seguimento na biblioteca \"%{ library }\""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr "%{ username } segue a súa biblioteca \"%{ library }\""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } quere seguir a súa biblioteca \"%{ library }\""
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Perfil de %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">Acerca de "
-"%{instanceName}</translate>"
 
 #: front/src/components/audio/artist/Card.vue:41
+#, fuzzy
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 álbume"
 msgstr[1] "%{ count } álbumes"
 
 #: front/src/components/favorites/List.vue:10
+#, fuzzy
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 favorita"
 msgstr[1] "%{ count } favoritas"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+#, fuzzy
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Limpar biblioteca"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Fallou a rede mentras se subía o ficheiro"
 
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Algo fallou ao gardar os cambios"
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "Acerca de %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "Acerca de %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "Acerca de Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Páxina Acerca de"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "Acerca de esta instancia"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Aceptar"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Aceptado"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Acceso desactivado"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Escolla un filtro"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Acceso desactivado"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Engadir a favoritas"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Acalar notificacións"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Engadir a lista de reprodución…"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Acceso desactivado"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
 msgstr "Acceda a súa música desde unha interface clara que se centra no realmente importante"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "Data de acceso"
+msgstr "Acceso desactivado"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Contas"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Contas"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Datos da conta"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Axustes da conta"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Axustes da conta"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Estado da conta"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Correo-e da conta"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+#, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Contas"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Acción"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "A acción %{ action } foi lanzada correctamente sobre  %{ count } elemento"
 msgstr[1] "A accións %{ action } foi lanzada correctamente sobre %{ count } elementos"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Accións"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Activo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Actividade"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Visibilidade da actividade"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Engadir"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Engadir un dominio"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+#, fuzzy
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Engadir nova regra de moderación"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Engadir nova regra de moderación"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Engadir e xestionar contido"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Engadir contido"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Engadir filtro"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Engada filtros para personalizar a súa radio"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Engadir a cola actual"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Engadir a favoritas"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Engadir a lista de reprodución…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Engadir a cola"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Engadir a esta lista de reprodución"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Engadir canción"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Admin"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administración"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Álbume"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Álbume que contén %{ count } canción, de %{ artist }"
-msgstr[1] "Álbume que contén %{ count } cancións, de %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Álbume"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Álbumes de este artista"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "Nome do álbume"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Páxina do álbume"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Nome do álbume"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Álbumes"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Álbumes de este artista"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Todos"
 
+#: front/src/components/common/ActionTable.vue:59
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "%{ count } de %{ total } seleccionado"
+msgstr[1] "%{ count } de %{ total } seleccionados"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "Algo fallou ao gardar os cambios"
 
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Algo fallou ao gardar os cambios"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Algo fallou ao gardar os cambios"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Aconteceu un fallo descoñecido, esto pode significar que o servidor está caído ou non pode ser alcanzado"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Acción"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "Aprovar"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+#, fuzzy
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Aprovar"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Está segura de que quere desconectar?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artista"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artista"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Nome do artista"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Páxina do artista"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Nome do artista"
 
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artista, álbume, canción…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artistas"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artistas"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "Ascendente"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Solicitar restablecer o contrasinal"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Contido de audio"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Atallos do reprodutor de audio"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Listas de reprodución dispoñibles"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Voltar a conectar"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Actualizar axustes"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Taxa de bits"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "Bloquear todo"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"Bloquear todo de esta conta ou dominio. Esto evitará calquera interacción "
-"coa entidade, e eliminará o contido relacionado (subidas, bibliotecas, "
-"seguimentos, etc.)"
+msgstr "Bloquear todo de esta conta ou dominio. Esto evitará calquera interacción coa entidade, e eliminará o contido relacionado (subidas, bibliotecas, seguimentos, etc.)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Buscar"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Buscar na biblioteca"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Buscando radios"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Buscando artistas"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Buscando nas listas de reprodución"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Buscando radios"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Construtor"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "De %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr "Ao deixar de seguir esta biblioteca perderá o acceso ao seu contido."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr "Tamaño da caché"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Cancelar"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Candidatas"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Non pode cambiar o contrasinal"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "Fallou a subida, asegúrese de que non é demasiado grande"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Cambiar idioma"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Cambiar o contrasinal"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Cambiar contrasinal"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Cambiar o seu contrasinal"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Cambiar o contrasinal?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Cambios sincronizados co servidor"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Ao cambiar o contrasinal tamén cambia o seu contrasinal no API Subsonic si é que solicitou un."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "Cambiar o contrasinal terá as seguintes consecuencias"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Sala de conversa"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Escolla a súa instancia"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Limpar biblioteca"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Limpar"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Limpar"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Limpar lista reprodución"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Limpar cola de reprodución"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Pulse unha vez, escoite durante horas utilizando as radios incrustadas"
 
-#: front/src/components/library/FileUpload.vue:75
-msgid "Click to select files to upload or drag and drop files or directories"
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
 msgstr ""
-"Pulse para escoller os ficheiros a subir ou arrastre e solte ficheiros ou "
-"directorios"
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
+msgid "Click to select files to upload or drag and drop files or directories"
+msgstr "Pulse para escoller os ficheiros a subir ou arrastre e solte ficheiros ou directorios"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "Pechar"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+#, fuzzy
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "Pechar"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Código"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Pechar"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Configurar"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Confirmar"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Confirme o seu correo-e"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Código de confirmación"
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Escolla un filtro"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Escolla un filtro"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
 msgstr "Actualizouse o contido, pulse actualizar para ver o contido actualizado"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Contribuír"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Copiar"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
-msgstr "Copiar cancións da cola actual a lista de reprodución"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
+msgstr "Copiar cancións da cola a lista de reprodución"
+
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr "Copiar/pegar este código no HTML da súa web"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Copyright"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Non se confirmou o seu correo-e"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Non se obtivo a biblioteca remota"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-"Non se procesou esta canción, asegúrese que está correctamente etiquetada"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Portadas, letras, o noso obxetivo é telas todas ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Crear"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Crear unha conta funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Crear unha nova lista de reprodución"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Crear unha nova lista de reprodución"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Crear nova biblioteca"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Crear unha nova lista de reprodución"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Crear unha conta"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Crear lista reprodución"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Crear biblioteca"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Crear a miña conta"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Crear lista reprodución"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Cree a súa propia radio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Data de creación"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Avatar actual"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Biblioteca actual"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Canción actual"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Uso actual"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Data"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Información da canción"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Baixar volume"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Borrar"
 
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Borrar lista de reprodución"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Eliminar biblioteca"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Borrar regra de moderación"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Borrar lista de reprodución"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Borrar radio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Eliminar esta biblioteca?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Eliminar esta biblioteca?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Eliminar esta biblioteca?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Eliminar esta regra de moderación?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
-#: front/src/components/manage/moderation/AccountsTable.vue:22
-#: front/src/components/manage/moderation/DomainsTable.vue:20
-#: front/src/components/manage/users/UsersTable.vue:20
-#: front/src/views/content/libraries/FilesTable.vue:32
-#: front/src/views/playlists/List.vue:28
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Eliminar esta regra de moderación?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Eliminar esta biblioteca?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
+#: front/src/components/manage/moderation/AccountsTable.vue:22
+#: front/src/components/manage/moderation/DomainsTable.vue:20
+#: front/src/components/manage/users/UsersTable.vue:20
+#: front/src/views/content/libraries/FilesTable.vue:32
+#: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Descendente"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Descrición"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Detalle"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Descrición"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Detalles"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
-msgstr ""
-"Indique canto contido pode subir a usuaria. Deixe baldeiro para utilizar o "
-"valor por omisión da instancia."
+msgstr "Indique canto contido pode subir a usuaria. Deixe baldeiro para utilizar o valor por omisión da instancia."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Indique o nivel de visibilidade da súa actividade"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Desactivar o acceso"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Desactivar o acceso Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Desactivar o acceso a API Subsonic?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Desactivado"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Descubra cómo utilizar Funkwhale desde outras apps"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Mostrar nome"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Mostrar públicamente"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Non baixar ningún ficheiro de medios (audio, portada, avatar da conta...) de "
-"esta conta ou dominio. Esto eliminará tamén o contido existente."
+msgstr "Non baixar ningún ficheiro de medios (audio, portada, avatar da conta...) de esta conta ou dominio. Esto eliminará tamén o contido existente."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Quere baldeirar a lista  de reprodución \"%{ playlist }\"?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Quere confirmar esta acción?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Quere eliminar esta lista de reprodución \"%{ playlist }\"?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Quere eliminar a radio \"%{ radio }\"?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Quere eliminar a radio \"%{ radio }\"?"
+
+#: front/src/components/common/ActionTable.vue:37
+#, fuzzy
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Quere executar %{ action } sobre %{ count } elemento?"
 msgstr[1] "Quere executar %{ action } sobre %{ count } elementos?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Quere restaurar a súa cola anterior?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Documentación"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Dominio"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Dominios"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Descargar"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Arrastre e solte filas para reordenar as cancións na lista"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Duración"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Enderezo correo-e confirmado"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Fácil de utilizar"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Editar"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Editar"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Fallo mentres se aplicaba a acción"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Editar a info da instancia"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Editar…"
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Actualizar regra de moderación"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Reproducir esta canción"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Reproducir esta canción"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Reproducir esta canción"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Editar"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Editar"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Correo-e"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Enderezo de correo"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Incrustado"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "Código incrustado"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr "Incruste este álbume no seu sitio web"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+#, fuzzy
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Incruste esta canción no seu sitio web"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "Incruste esta canción no seu sitio web"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
-msgstr ""
+msgstr "Seguimentos da biblioteca emitidos"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
-msgstr ""
+msgstr "Mensaxes emitidas"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
-msgstr ""
+msgstr "Activado"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Finalizar edición"
 
 #: front/src/views/content/remote/ScanForm.vue:50
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
-msgstr "Introduza un nome de dominio de biblioteca..."
+msgstr "Introduza un URL de biblioteca"
 
-#: front/src/components/library/Radios.vue:140
-#, fuzzy
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
-msgstr "Introduza un nome de unha radio..."
+msgstr "Introduza un nome de radio…"
 
-#: front/src/components/library/Artists.vue:118
-#, fuzzy
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
-msgstr "Introduza un nome de un artista..."
+msgstr "Introduza nome de artista…"
 
 #: front/src/views/playlists/List.vue:107
-#, fuzzy
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
-msgstr "Introduza un nome de lista de reprodución..."
+msgstr "Nome de lista de reprodución…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+#, fuzzy
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Introducir o enderezo de correo ligado a súa conta"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Introduza o seu correo-e"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Introduza o seu código de convite (dif. maiúsculas)"
 
 #: front/src/components/metadata/Search.vue:114
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
-msgstr "Introduza os termos de busca..."
+msgstr "Introduza a consulta de busca…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Introduza o nome de usuaria"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Introduza o nome de usuaria ou correo-e"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Fallo"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Fallo ao informar"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Fallo ao informar"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Con fallo"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Fallo mentres se aplicaba a acción"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Fallo ao solicitar o restablecemento do contrasinal"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Fallo mentres se aplicaba a acción"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Fallo ao intentar cambiar o contrasinal"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
-#, fuzzy
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
-msgstr "Fallo ao crear o convite"
+msgstr "Fallo ao crear o dominio"
+
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Fallo ao crear a regra"
 
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Fallo ao crear o convite"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
-#, fuzzy
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
-msgstr "Fallo ao crear o convite"
+msgstr "Fallo ao crear a regra"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
 #, fuzzy
-msgid "Error while fetching node info"
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
 msgstr "Fallo ao crear o convite"
 
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
+msgid "Error while fetching node info"
+msgstr "Fallo ao obter info da instancia"
+
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Fallo ao gardar os axustes"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Fallo ao gardar os axustes"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+#, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Fallo ao gardar os axustes"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Con fallo"
 
 #: front/src/views/content/libraries/Quota.vue:75
-#, fuzzy
+msgctxt "Content/Library/Label"
 msgid "Errored files"
-msgstr "Con fallo"
+msgstr "Ficheiros con fallos"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Todas"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Todas en esta instancia"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
 #, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
-msgstr "Todas en esta instancia"
+msgstr "Todos, en todas as instancias"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Excluír"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Data de caducidade"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Caducado"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Caducado/utilizado"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
+msgstr "Explicar por que aplica esta política a todas as instancias. Dependendo da configuración da súa instancia esto axudaralle a lembrar por que actuou sobre esta conta ou dominio, e pode ser mostrado públicamente para que as usuarias entendan cales son as regras de moderación que se aplican."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
-msgstr ""
+msgstr "Fallou"
 
-#: front/src/views/content/remote/Card.vue:58
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
-msgstr "Cancións federadas"
+msgstr "Cancións fallidas:"
+
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Cancións fallidas:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Favoritas"
 
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Favoritas"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federación"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
 #, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Federación"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nome do ficheiro"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Ficheiros"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Nome do filtro"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Rematado"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
-msgstr ""
+msgstr "Visto primeiro"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
-msgstr "Data de caducidade"
+msgstr "Data da primeira visión"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Seguir"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
-msgstr ""
+msgstr "Seguir bibliotecas remotas"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Solicitude de seguimento pendente de aprobación"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Seguidoras"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Seguidoras"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Seguindo"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Do álbume %{ album } de %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Seguir"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Desactivar o acceso"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale é compatible con outros reprodutores de música compatibles coa API Subsonic."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funckwhale élle ben doado de utilizar."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale está deseñado para escoitar facilmente a música que lle gusta ou descubrir novos artistas."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale é gratuíto e dalle o control sobre a súa música."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale ocúpase de xestionar a súa música"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
-msgstr ""
+msgstr "Atallos xerais"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Obter un novo convite"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Lévame a biblioteca"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
 #, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
-msgstr ""
-"Obteña metadatos de calidade sobre a súa música grazas a\n"
-"              <a href=\"https://musicbrainz.org\" target=\"_blank\">\n"
-"                MusicBrainz\n"
-"              </a>"
+msgstr "Obteña metadatos de calidade sobre a súa música grazas a <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
-#, fuzzy
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
-msgstr "Seguinte paso"
+msgstr "Comezando"
+
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Obter axuda"
 
 #: front/src/components/Footer.vue:37
 #, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
-msgstr "Axustes"
+msgstr "Obter axuda"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Ir"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Ir ao inicio"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Buscando artistas"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
+msgstr "Ocultar contido de conta ou dominio, excepto de seguidoras."
+
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Engadir contido"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
 msgstr ""
 
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Inicio"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Horas de música"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Porén, o acceso a Funkwhale desde estos outros clientes precisa un contrasinal separado que pode establecer aquí abaixo."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Si o enderezo de correo proporcionado no paso anterior é válido e ligado a unha conta de usuaria, debería recibir un correo coas instrucións de restablecemento nun par de minutos."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Data de importación"
-
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importar música desde varias plataformas, tales como YouTube ou SoundCloud"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/ImportStatusModal.vue:3
 #, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Estado da importación"
+
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
-msgstr "Fonte de importación"
+msgstr "Importar referencia"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Estado da importación"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+#, fuzzy
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "Estado da importación"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importado"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
 #, fuzzy
-msgid "Imported date"
-msgstr "Data de importación"
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Recentemente engadida"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "Nas favoritas"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Non activo"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
-msgstr ""
-
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Introducir o enderezo de correo ligado a súa conta"
+msgstr "Aumentar volume"
 
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Introducir desde a cola  (%{ count } canción)"
 msgstr[1] "Introducir desde a cola  (%{ count } cancións)"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:71
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
 #, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Datos da instancia"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
-msgstr "Radios da instancia"
+msgstr "Datos da instancia"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Información da instancia"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Radios da instancia"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Axustes da instancia"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Datos da instancia"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr "Tipo de ficheiro non válido, asegúrese de que sube un ficheiro de audio. Extensións de ficheiros soportadas %{ extensions }"
+
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Código do convite"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Código do convite (optativo)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Convites"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Seguimento de problemas"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Faga seguimento das súas cancións favoritas"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
-msgstr ""
+msgstr "Atallos de teclado"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
-msgstr "A miña conta"
+msgstr "Contas coñecidas"
 
 #: front/src/views/content/remote/Home.vue:14
-#, fuzzy
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
-msgstr "Buscando nas bibliotecas"
+msgstr "Bibliotecas coñecidas"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Última actividade"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
-msgstr "Última obtida"
+msgstr "Última comprobación"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Última modificación"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
-msgstr "Última obtida"
+msgstr "Última vista"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
-msgstr "Data de lanzamento"
+msgstr "Data da última vista"
 
-#: front/src/views/content/remote/Card.vue:56
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
-msgstr "Lista de reprodución actualizada"
+msgstr "Última actualización:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Lanzar"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Coñeza máis sobre esta instancia"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Deixar baldeiro para un código aleatorio"
 
 #: front/src/components/audio/EmbedWizard.vue:7
-#, fuzzy
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
-msgstr "Deixar baldeiro para un código aleatorio"
+msgstr "Deixar baldeiro para un trebello interactivo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Bibliotecas"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Bibliotecas"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Biblioteca actualizada"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
-msgstr ""
+msgstr "As bibliotecas axúdanlle a organizar e compartir a súa colección musical. Pode subir a súa propia colección de música a Funkwhale e compartila cos seus amigos e familia."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Biblioteca"
 
-#: front/src/views/content/libraries/Form.vue:109
-#, fuzzy
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
-msgstr "Nome da biblioteca"
+msgstr "Biblioteca creada"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
 #, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Biblioteca actualizada"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
-msgstr "Ficheiros de biblioteca"
+msgstr "Biblioteca eliminada"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "Ficheiros de biblioteca"
 
-#: front/src/views/content/libraries/Form.vue:106
-#, fuzzy
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
-msgstr "Nome da biblioteca"
+msgstr "Biblioteca actualizada"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
+msgstr "Licenza"
+
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
 msgstr ""
 
-#: front/src/views/content/libraries/Detail.vue:21
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
 #, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Cargando seguidoras…"
+
+#: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
-msgstr "Buscando seguidoras"
+msgstr "Cargando seguidoras…"
 
 #: front/src/views/content/libraries/Home.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
-msgstr "Buscando nas bibliotecas"
+msgstr "Cargando Bibliotecas…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
-msgstr ""
+msgstr "Cargando datos da biblioteca…"
 
-#: front/src/views/Notifications.vue:4
-#, fuzzy
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
-msgstr "Última modificación"
+msgstr "Cargando notificacións…"
 
 #: front/src/views/content/remote/Home.vue:3
-#, fuzzy
-msgid "Loading remote libraries..."
-msgstr "Cargando liña temporal..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "Cargando bibliotecas remotas…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
-msgstr ""
+msgstr "Cargando datos de uso…"
 
 #: front/src/components/favorites/List.vue:5
-#, fuzzy
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
-msgstr "Cargando favoritas..."
+msgstr "Cargando as favoritas…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
 
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
 #, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
-msgstr "A miña conta"
+msgstr "Conta local"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Conectar"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Conecte coa súa conta Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Desconectar"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Conectada como %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Conectar"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
-msgstr "Estado da conta"
+msgstr "Estado da conexión"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Desconectar"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
-msgstr ""
+msgstr "Semella que non ten unha biblioteca, é momento de crear unha."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Bucle desactivado. Pulse para cambiar ao bucle de unha soa canción."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Bucle de unha canción. Pulse para cambiar a bucle de toda a cola."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Bucle de toda a cola. Pulse para desactivar o bucle."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Letras"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
-msgstr ""
+msgstr "Menú principal"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Xestionar biblioteca"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Xestionar listas de reprodución"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Xestionar usuarias"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Xestionar as súas listas de reprodución"
 
-#: front/src/views/Notifications.vue:17
-#, fuzzy
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
-msgstr "Marcar como importado"
+msgstr "Marcar todo como lido"
 
-#: front/src/components/notifications/NotificationRow.vue:44
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
-msgstr "Marcar como importado"
+msgstr "Marcar como lido"
 
-#: front/src/components/notifications/NotificationRow.vue:45
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
-msgstr "Marcar como importado"
+msgstr "Marcar como non lido"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
-msgstr ""
+msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
-msgstr ""
+msgstr "Reprodutor"
+
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Rexistrada desde %{ date }"
 
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
-msgstr ""
+msgstr "Apps de escritorio e móbil"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
 #, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
-msgstr "Federación"
+msgstr "Moderación"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
+msgstr "As políticas de moderación axúdanlle a controlar o xeito en que a súa instancia interactúa con determinado dominio ou conta."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
 #, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Data de modificación"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
-msgstr "Data de caducidade"
+msgstr "Data de modificación"
+
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
 
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Música"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Acalar"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Acalar actividade"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Acalar notificacións"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "A miña conta"
 
-#: front/src/components/library/radios/Builder.vue:236
-#, fuzzy
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
-msgstr "A miña increíble radio"
+msgstr "A miña abraiante descrición"
 
-#: front/src/views/content/libraries/Form.vue:70
-#, fuzzy
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
-msgstr "A miña increíble radio"
+msgstr "A miña abraiante biblioteca"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "A miña fantástica lista"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "A miña increíble radio"
 
 #: front/src/views/content/libraries/Home.vue:6
-#, fuzzy
+msgctxt "Content/Library/Title"
 msgid "My libraries"
-msgstr "Bibliotecas"
+msgstr "As miñas Bibliotecas"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "N/A"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nome"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Novo contrasinal"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "As novas cancións engadiranse aquí automáticamente."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Seguinte canción"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Non"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Sin engadidos nin complementos: só precisa unha biblioteca na web"
 
 #: front/src/components/audio/Search.vue:25
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
-msgstr "Lamentámolo, non atopamos ningún álbume que coincida coa consulta"
+msgstr "Ningún álbume coincide coa busca"
 
 #: front/src/components/audio/Search.vue:16
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
-msgstr "Lamentámolo, non atopamos ningún artista que coincida coa súa consulta"
+msgstr "Ningún artista coincide coa busca"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "Non hai letras dispoñibles para esta canción."
 
-#: front/src/components/federation/LibraryWidget.vue:6
+#: front/src/components/library/TrackDetail.vue:25
 #, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Non temos información da licenza para esta canción"
+
+#: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
-msgstr "Xestionar biblioteca"
+msgstr "Sen biblioteca coincidente."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr "Sen notificación para mostrar."
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
 msgstr ""
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Ninguén excepto eu"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
-msgstr ""
+msgstr "Ninguén segue esta biblioteca"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Non utilizado"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
 #, fuzzy
+msgctxt "*/Notifications/*"
 msgid "Notifications"
-msgstr "Última modificación"
+msgstr "Notificacións"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Notifications"
+msgstr "Notificacións"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Sitio web oficial"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Contrasinal antigo"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Abrir"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Actualizar regra de moderación"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Abrir perfil"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Ver en MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
-msgstr ""
+msgstr "Abrir perfil"
+
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Abrir perfil"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
-#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
-msgstr "Sitio web oficial"
+msgstr "Abrir sitio web"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
-#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
-msgstr "Engada filtros para personalizar a súa radio"
+msgstr "Ou personalice a súa regra"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
-#, fuzzy
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
-msgstr "Ordenando"
-
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+msgstr "Ordear"
+
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Ordenando"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Dirección da orde"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Dona"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Páxina non atopada"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Non atopamos a páxina!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
-msgstr ""
+msgstr "Paxinación"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Contrasinal"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Contrasinal actualizado"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Contrasinal actualizado correctamente"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Pausar canción"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
-msgstr ""
+msgstr "Pausar/reproducir pista actual"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
-#, fuzzy
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
-msgstr "Rexeitado"
+msgstr "Pausada"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "Pendente"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Pendente de aceptación"
 
 #: front/src/views/content/libraries/Quota.vue:22
-#, fuzzy
+msgctxt "Content/Library/Label"
 msgid "Pending files"
-msgstr "Pendente"
+msgstr "Ficheiros pendentes"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Peticións de seguimento pendentes"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Ficheiros pendentes"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Ficheiros pendentes"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Permisos"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Permisos"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Reproducir"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Reproducir todo"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Reproducir todos os álbumes"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Reproducir seguinte"
 
 #: front/src/components/ShortcutsModal.vue:67
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
-msgstr "Reproducir canción"
+msgstr "Reproducir canción seguinte"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Reproducir agora"
 
 #: front/src/components/ShortcutsModal.vue:63
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
-msgstr "Canción anterior"
+msgstr "Reproducir canción anterior"
 
-#: front/src/components/Sidebar.vue:211
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
-msgstr "Reproducir canción"
+msgstr "Reproducir esta canción"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Reproducir canción"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Reproducir..."
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Lista de reprodución"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Lista de reprodución que contén %{ count } canción, de %{ username }"
 msgstr[1] "Lista de reprodución que contén %{ count } cancións, de %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Lista creada"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Editora da lista"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nome da lista"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Lista de reprodución actualizada"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Visibilidade da lista de reprodución"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Listas de reprodución"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Listas de reprodución"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "Listas de reprodución? Témolas"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Por favor, comprobe que o seu contrasinal é correcto"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Por favor, comprobe que o par usuaria/contrasinal é correcto"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF ou JPG. 2MB como máximo. Será reducida a 400x400px."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Paxinación"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
+msgstr "Evitar que o dominio ou conta mostre notificacións, excepto das seguidoras."
 
-#: front/src/components/audio/EmbedWizard.vue:29
-#, fuzzy
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
-msgstr "Paso anterior"
+msgstr "Vista previa"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Canción anterior"
 
-#: front/src/views/content/remote/Card.vue:39
-msgid "Problem during scanning"
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:58
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
+msgid "Problem during scanning"
+msgstr "Problema ao escanear"
+
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
-msgstr "Ir a conectar"
+msgstr "Proceder"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Ir a conectar"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
-msgstr ""
+msgstr "Procesando"
+
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Abrir perfil"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
@@ -1946,1113 +3273,1973 @@ msgstr ""
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
-msgstr ""
+msgstr "Limpar"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
-msgstr ""
+msgstr "Eliminar ficheiros con fallos?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
-msgstr ""
+msgstr "Eliminar ficheiros pendentes?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
-msgstr ""
+msgstr "Eliminar ficheiros saltados?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Cola"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "Cola barallada!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Constructor de Radio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Radio creada"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nome da Radio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Radio actualizada"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radios"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radios"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
-msgstr ""
+msgstr "Razón"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
-msgstr ""
+msgstr "Seguimentos de biblioteca recibidos"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
+msgstr "Mensaxes recibidas"
+
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Recentemente engadida"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
 msgstr ""
 
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Recentemente engadida"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Favorecida recentemente"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Escoitada recentemente"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Actualizar"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Actualizar"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
+msgstr "Actualizar info da instancia"
+
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Actualizar info da instancia"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
+msgstr "Actualizar contido da tabla"
+
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
 msgstr ""
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Rexistrada desde %{ date }"
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "O rexistro está pechado en esta instancia, necesita un código de convite para rexistrarse."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "usuaria normal"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
-msgstr ""
+msgstr "Rexeitar"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
-msgstr ""
+msgstr "Rexeitar medios"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
-msgstr ""
+msgstr "Rexeitado"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
 #, fuzzy
-msgid "Relaunch import"
-msgstr "Rematar importación"
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Data da última vista"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
-#, fuzzy
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
-msgstr "Lévame a biblioteca"
+msgstr "Bibliotecas remotas"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
-msgstr ""
+msgstr "As bibliotecas remotas pertences a outras usuarias na rede. Pode acceder a elas se son públicas ou lle outorgan acceso."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Eliminar"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Eliminar avatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Eliminar avatar"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Eliminar das favoritas"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Elimina completamente as cancións subidas pero aínda non procesadas, engadindo o espazo correspondente a súa cuota."
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Elimina as cancións subidas saltadas durante o proceso de importación, engadindo o espazo correspondente a súa cuota."
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Elimina as cancións subidas que non se procesaron completamente no servidor, engadindo o espazo correspondente a súa cuota."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Solicitar un novo contrasinal"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Solicitar un nonvo contrasinal para o API Subsonic?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Solicitar un contrasinal"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Restablecer o seu contrasinal"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Volte a lanzar importación"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Resultados por páxina"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
-#, fuzzy
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
-msgstr "Ir a conectar"
+msgstr "Voltar a conectar"
+
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Ver ficheiros"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
-msgstr ""
+msgstr "Regra"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Gardar"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
-msgstr ""
+msgstr "Escaneado iniciado"
 
-#: front/src/views/content/remote/Card.vue:63
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
-msgstr "Reproducir agora"
+msgstr "Escanear agora"
 
-#: front/src/views/content/remote/Card.vue:166
-msgid "Scan skipped (previous scan is too recent)"
-msgstr ""
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Ascendente"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr ""
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
+msgid "Scan skipped (previous scan is too recent)"
+msgstr "Escaneado saltado (o escaneado anterior é moi recente)"
 
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
-msgstr ""
+msgstr "Escaneado"
 
-#: front/src/views/content/remote/Card.vue:47
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
-msgstr "Cambios sincronizados co servidor"
+msgstr "Escaneado con fallos"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
+msgstr "Escaneando... (%{ progress }%)"
+
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
 msgstr ""
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Buscar"
 
 #: front/src/views/content/remote/ScanForm.vue:9
-#, fuzzy
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
-msgstr "Lévame a biblioteca"
+msgstr "Buscar unha biblioteca remota"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:171
+#: front/src/components/manage/library/EditsCardList.vue:211
 #, fuzzy
-msgid "Search by domain, username, bio..."
-msgstr "Buscar por artista, nome de usuaria, comentario..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Buscar por título, artista, dominio…"
 
-#: front/src/components/manage/moderation/DomainsTable.vue:151
+#: front/src/components/manage/library/LibrariesTable.vue:191
 #, fuzzy
-msgid "Search by name..."
-msgstr "Buscar por fonte..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Buscar por dominio, nome de usuaria, bio…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/components/manage/library/UploadsTable.vue:241
 #, fuzzy
-msgid "Search by title, artist, album…"
-msgstr "Buscar por título, artista, dominio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Buscar por dominio, nome de usuaria, bio…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Buscar por dominio, nome de usuaria, bio…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
+#: front/src/components/manage/library/TracksTable.vue:174
 #, fuzzy
-msgid "Search by title, artist, domain…"
-msgstr "Buscar por título, artista, dominio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Buscar por título, artista, álbume…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Buscar por título, artista, álbume…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Buscar por dominio, nome de usuaria, bio…"
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Buscar por nome…"
+
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
+msgid "Search by title, artist, album…"
+msgstr "Buscar por título, artista, álbume…"
 
 #: front/src/components/manage/users/InvitationsTable.vue:153
 #, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
-msgstr "Buscar por nome de usuaria, correo-e, código..."
+msgstr "Buscar por nome de usuaria, correo-e, código…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
-#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
-msgstr "Buscar por nome de usuaria, correo-e, nome..."
+msgstr "Buscar por nome de usuaria, correo-e, nome…"
 
 #: front/src/components/audio/SearchBar.vue:20
-#, fuzzy
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
-msgstr "Buscar por artistas, álbumes, cancións..."
+msgstr "Buscar por artistas, álbumes, cancións…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Buscar por algo de música"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Buscar en lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Buscar en Wikipedia"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
-msgstr ""
+msgstr "Menú secundario"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Seccións"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Escolla un filtro"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "Escolla %{ total } elemento"
 msgstr[1] "Escolla todos os %{ total } elementos"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Seleccionar só páxina actual"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Axustes"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Axustes actualizados"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Axustes actualizados correctamente."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Compartir ligazón"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
+msgstr "Comparta esta ligazón con outras usuarias así poderán solicitar acceso a súa biblioteca."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Compartir ligazón"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
 #, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
-msgstr[0] "%{ count } canción"
-msgstr[1] "%{ count } cancións"
+msgstr[0] "Mostrar %{ count } canción máis"
+msgstr[1] "Mostrar %{ count } cancións máis"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Mostrar 1 álbume máis"
 msgstr[1] "Mostrar %{ count } álbumes máis"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
-msgstr ""
+msgstr "Mostrar atallos de teclado dispoñibles"
 
-#: front/src/views/Notifications.vue:10
-#, fuzzy
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
-msgstr "Última modificación"
+msgstr "Mostrar notificacións lidas"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Mostrar/ocultar contrasinal"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Mostrando resultados %{ start }-%{ end } de %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Barallar a cola"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Barallar a cola"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Rexistro"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Rexistrarse"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
 #, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
-msgstr "Rexistrarse"
+msgstr "Data de rexistro"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
 #, fuzzy
-msgid "Silence activity"
-msgstr "Actividade da usuaria"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr ""
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Tamaño"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Tamaño"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Saltado"
 
 #: front/src/views/content/libraries/Quota.vue:49
-#, fuzzy
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
-msgstr "Saltado"
+msgstr "Ficheiros saltados"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
+msgstr "Software"
+
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
 msgstr ""
 
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Lamentámolo, a páxina que solicitou non existe:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Código fonte"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Persoal do equipo"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Iniciar"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Deter radio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Estatísticas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
+msgstr "As estatísticas contabilízanse pola actividade coñecida e o contido da súa instancia, e non reflexan a actividade xeral de esta conta"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
+msgstr "As estatísticas contabilízanse pola actividade coñecida e o contido da súa instancia, e non reflexan a actividade xeral de este dominio"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "As estatísticas contabilízanse pola actividade coñecida e o contido da súa instancia, e non reflexan a actividade xeral de esta conta"
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Estado"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Estado"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Deter"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Estado"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Deter radio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Enviar"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Contrasinal API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Non podemos cargar a canción"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Non podemos cargar a canción"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Non podemos cargar a canción"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Opcións suxeridas"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
+msgstr "Resumo"
+
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
 msgstr ""
 
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
-msgstr ""
+msgstr "Foro de axuda"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
-msgstr ""
+msgstr "Extensións soportadas: %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
-#, fuzzy
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
-msgstr "Sincronizando cambios co servidor..."
+msgstr "Sincronizando cambios co servidor…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
-msgstr ""
+msgstr "Texto copiado ao portapapeis!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "É simple: encantábanos Grooveshark e queremos construír algo aínda mellor."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "O logo de funckwhale foi amablemente deseñado e proporcionado por Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
-msgstr "Eliminará completamente a radio e non ten volta atrás."
+msgstr "Eliminará completamente a biblioteca e as cancións. Non poderá voltar atrás."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
 msgstr ""
 
-#: front/src/components/Home.vue:121
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
+msgstr "Os ficheiros de música que está a subir están etiquetados correctamente:"
+
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "A seguinte canción reproducirase automáticamente en poucos segundos…"
+
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "A plataforma é libre de código aberto, pode instalala e modificala sin preocupación"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Lista creada"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Esta acción non é reversible."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "O API Subsonic non está dispoñible en esta instancia Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
-msgid "The uploaded music files are in OGG, Flac or MP3 format"
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Non podemos engadir a canción a lista de reprodución"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
 msgstr ""
 
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Esta acción non é reversible."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
+msgid "The uploaded music files are in OGG, Flac or MP3 format"
+msgstr "Os ficheiros de música subidos están en formato OGG, Flac ou MP3"
+
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
-msgstr ""
+msgstr "Hai varios xeitos de obter contido novo e publicalo aquí."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
-msgstr ""
+msgstr "Esta acción non é reversible."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
-msgstr ""
+msgstr "Este álbume está presente nas seguintes bibliotecas:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
-msgstr ""
+msgstr "Este artista está presente nas seguintes bibliotecas:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
-msgstr ""
+msgstr "Este dominio está suxeito a regras específicas de moderación"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr "Esta instancia ofrece %{quota} de almacenamento a cada usuaria."
+
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
 msgstr ""
 
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "Este é vostede!"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
-msgstr ""
+msgstr "Esta biblioteca contén a miña música persoal, espero que che guste."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
+msgstr "Esta biblioteca é privada e precisa que a usuaria lle conceda permiso para acceder ao contido"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
-msgstr ""
+msgstr "Esta biblioteca é pública e pode acceder ao contido libremente"
 
-#: front/src/components/common/ActionTable.vue:45
-#, fuzzy
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
-msgstr "Esto podería afectar a moitos elementos, por favor comprobe si realmente é o que quere."
+msgstr "Esto podería afectar a moitos elementos ou ter consecuencias irreversibles, por favor comprobe si realmente é o que quere."
 
-#: front/src/components/library/FileUpload.vue:52
-msgid "This reference will be used to group imported files together."
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
+msgid "This reference will be used to group imported files together."
+msgstr "Esta referencia usarase para agrupar os ficheiros importados."
+
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Non se procesou esta canción, asegúrese que está correctamente etiquetada"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "Canción subida, pero aínda non procesada polo servidor"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
 #, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "A canción xa está presente nunha das súas bibliotecas"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
-msgstr "Cancións dispoñibles en esta biblioteca"
+msgstr "Esta canción non está dispoñible en ningunha biblioteca a que teña acceso"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
-msgstr ""
+msgstr "Esta canción está presente nas seguintes bibliotecas:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Eliminará completamente a lista de reprodución e non poderá voltar atrás."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Eliminará completamente a radio e non ten volta atrás."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Desactivará o acceso a API Subsonic desde a conta."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr "Eliminará os datos locais e será desconectada, desexa continuar?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Será desconectada dos dispositivos existentes que utilicen o contrasinal actual."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Eliminará completamente a lista de reprodución e non poderá voltar atrás."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Esto eliminará todas as cancións da lista de reprodución e non hai volta."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Title"
 msgstr "Título"
 
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
-msgstr ""
+msgstr "Activar a repetición da cola"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
-msgstr ""
+msgstr "Tamaño total"
 
-#: front/src/views/content/libraries/Card.vue:61
-#, fuzzy
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
-msgstr "Cancións dispoñibles en esta biblioteca"
+msgstr "Tamaño total dos ficheiros de esta biblioteca"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
-#, fuzzy
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
-msgstr "Non utilizado"
+msgstr "Conta de usuarias"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Canción"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Canción"
+
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
 msgstr ""
 
-#: front/src/components/library/Track.vue:85
+#: front/src/views/admin/library/TrackDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Nome da canción"
+
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Información da canción"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Filtro coincidente da canción"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
-msgstr "Canción"
-
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr ""
+msgstr "Nome da canción"
+
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Cancións"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "cancións"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Cancións"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Cancións de este artista"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Cancións favorecidas"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "cancións escoitadas"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Filtro coincidente da canción"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Tipo"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Tipo"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr ""
+msgstr "Baixo regra de moderación"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
 #, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
-msgstr "Seguir"
+msgstr "Deixar de seguir"
 
-#: front/src/views/content/remote/Card.vue:101
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
-msgstr "Buscar na biblioteca"
+msgstr "Deixar de seguir biblioteca?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "Desgraciadamente os donos de esta instancia non tiveron tempo de completar esta páxina."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Música sen límites"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Dar voz"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
-msgstr "Actualizar avatar"
+msgstr "Actualizar"
+
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Actualizar lista de reprodución"
 
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Actualizar avatar"
 
 #: front/src/views/content/libraries/Form.vue:25
-#, fuzzy
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
-msgstr "Xestionar biblioteca"
-
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr ""
+msgstr "Actualizar biblioteca"
 
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Actualizar lista de reprodución"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Actualizar axustes"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Actualizar contrasinal"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Subir"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Subir un novo avatar"
 
 #: front/src/views/content/Home.vue:6
-#, fuzzy
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
-msgstr "Subir un novo avatar"
+msgstr "Subir contido de audio"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
 #, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Data de subida"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
-msgstr "Subir"
+msgstr "Data de subida"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "Subida denegada, asegúrese de que o ficheiro non é demasiado grande e que non acadou o límite de cuota"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr ""
+msgstr "Subir ficheiros de música (MP3, OGG, FLAC, etc.) desde a súa biblioteca persoal co seu navegador e desfrútea aquí."
 
-#: front/src/components/library/FileUpload.vue:31
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
-msgstr "Subir un novo avatar"
+msgstr "Subir novas cancións"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
-msgstr "Subir"
+msgstr "Cota de subida"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
+msgstr "Caducou a subida, inténteo de novo"
+
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:100
-#, fuzzy
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
-msgstr "Subir"
+msgstr "Subida"
 
 #: front/src/components/library/FileUpload.vue:5
-#, fuzzy
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
-msgstr "Subindo..."
+msgstr "Subindo"
 
-#: front/src/components/library/FileUpload.vue:103
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
-msgstr "Subindo..."
+msgstr "Subindo…"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/manage/library/LibrariesTable.vue:52
 #, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Uploads"
-msgstr "Subir"
+msgstr "Subidas"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Subidas"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:41
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Uploads"
+msgstr "Subidas"
+
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
 
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Utilizar outra instancia"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Utilice este formulario para solicitar o restablecemento do contrasinal. Enviarémoslle un correo-e con instrucións para restablecelo."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
+msgstr "Utilice este axuste para activar/desactivar temporalmente a condición sen elminala completamente."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Utilizado"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Usuaria"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Actividade da usuaria"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
 #, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
-msgstr "Radios da usuaria"
+msgstr "Bibliotecas da usuaria"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Radios da usuaria"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nome de usuaria"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nome de usuaria ou correo-e"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "usuarias"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Usuarias"
 
 #: front/src/components/Footer.vue:29
 #, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
-msgstr "Acerca de Funkwhale"
+msgstr "Utilizando Funkwhale"
 
 #: front/src/components/Footer.vue:13
-#, fuzzy
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
-msgstr "Código fonte (%{version})"
+msgstr "Versión %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
-#, fuzzy
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
-msgstr "Ficheiros de biblioteca"
+msgstr "Ver ficheiros"
+
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Ver en MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
-#, fuzzy
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
-msgstr "Visibilidade da lista de reprodución"
-
-#: front/src/views/content/libraries/Card.vue:59
-#, fuzzy
-msgid "Visibility: everyone on this instance"
-msgstr "Todas en esta instancia"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr ""
-
-#: front/src/views/content/libraries/Card.vue:58
+msgstr "Visibilidade"
+
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
 #, fuzzy
-msgid "Visibility: nobody except me"
-msgstr "Ninguén excepto eu"
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Visibilidade"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
-msgstr ""
-
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Non podemos engadir a canción a lista de reprodución"
+msgstr "Volume %{ number }"
 
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Non podemos crear a lista de reprodución"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Non podemos crear a súa conta"
-
-#: front/src/components/audio/Player.vue:64
+#: front/src/components/federation/FetchButton.vue:69
 #, fuzzy
-msgid "We cannot load this track"
-msgstr "Non podemos engadir a canción a lista de reprodución"
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Cargando as favoritas…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Non podemos conectala"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Non podemos gardar o seu avatar"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Non podemos gardar os axustes"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Non podemos crear a súa conta"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Nin a perseguimos na internet nin molestamos con publicidade"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr ""
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr ""
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "Recomendámoslle utilizar Picard para ese propósito."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Cremos que escoitar música  debería ser simple."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Lamentámolo, a páxina que solicitou non existe:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Benvida"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Benvida a Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Por qué funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
-msgstr ""
+msgstr "Alto do trebello"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
+msgstr "Ancho do trebello"
+
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Si"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Si, desconectádeme!"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
-msgstr ""
+msgstr "Pode compartir a biblioteca con outa xente, independentemente da súa visibilidade."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
+msgstr "Vai subir música a súa biblioteca. Antes de seguir, asegúrese de que:"
+
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
 msgstr ""
 
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Está conectada como %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
-msgstr ""
+msgstr "Pode seguir bibliotecas de outras usuarias para acceder a nova música. As bibliotecas públicas pódense seguir inmediatamente, mentras que as privadas precisan que a usuaria lle conceda acceso."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Pode convidar amigos e familiares a súa instancia para que desfruten da súa música"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
-msgstr "O seu enderezo de correo foi confirmado, xa pode utilizar o servizo sen limitacións."
+msgstr "Xa pode utilizar o servizo sen limitacións."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Pode utilizar esta interface para construír a súa propia radio, que reproducirá cancións segundo o seu criterio."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Pode utilizalos para desfrutar da súa lista de reprodución e música en modo fora de liña, no seu dispositivo móbil ou tableta, por exemplo."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Non ten ningunha regra activada para esta conta."
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Non ten ningunha regra activada para esta conta."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
-msgstr ""
+msgstr "Non ten ningunha regra activada para esta conta."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
+msgstr "Non ten ningunha regra activada para este dominio."
+
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
 msgstr ""
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Ten a radio a funcionar"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
-msgstr ""
-
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Debe seleccionar unha instancia para poder continuar"
+msgstr "Podería ter problemas de conectividade."
 
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Será desconectada de esta sesión e deberá conectar co novo"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Deberá actualizar o contrasinal nos seus clientes que utilicen este contrasinal."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Lista creada"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "As súas notificacións"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "As súas Favoritas"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "A súa música, o seu xeito"
 
-#: front/src/views/Notifications.vue:7
-#, fuzzy
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
-msgstr "Última modificación"
+msgstr "As súas notificacións"
+
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
 
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "O seu contrasinal foi actualizado correctamente."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Axustes actualizados"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "O seu contrasinal Subsonic será cambiado por un novo, aleatorio, desconectándoa de todos os dispositivos que utilicen os contrasinal antigo"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Paxinación"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Copyright"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Álbume que contén %{ count } canción, de %{ artist }"
+msgstr[1] "Álbume que contén %{ count } cancións, de %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "Engadiuse %{ count } canción a cola"
+msgstr[1] "Engadíronse %{ count } cancións a cola"
diff --git a/front/locales/it/LC_MESSAGES/app.po b/front/locales/it/LC_MESSAGES/app.po
index d3251f2b75cf2102f61706f8749b37053c11e098..298b5b20167196eb9a871329858e9b18bbc5f3c5 100644
--- a/front/locales/it/LC_MESSAGES/app.po
+++ b/front/locales/it/LC_MESSAGES/app.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-15 08:57+0000\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-05-03 10:33+0000\n"
 "Last-Translator: Sylke Vicious <silkevicious@tuta.io>\n"
 "Language-Team: none\n"
 "Language: it\n"
@@ -19,1878 +19,3117 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\", di %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } su %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(vuoto)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "%{ app } vuole accedere al tuo account Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } su %{ total } selezionato"
 msgstr[1] "%{ count } su %{ total } selezionati"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } traccia"
 msgstr[1] "%{ count } tracce"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } traccia in %{ albumsCount } album"
 msgstr[1] "%{ count } tracce in %{ albumsCount } album"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
-msgstr[0] "%{ count } traccia corrisponde ai filtri combinati"
-msgstr[1] "%{ count } tracce corrispondono ai filtri combinati"
-
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "%{ count } traccia è stata aggiunta alla tua coda"
-msgstr[1] "%{ count } tracce sono state aggiunte alla tua coda"
+msgstr[0] "%{ count } traccia corrisponde ai filtri selezionati"
+msgstr[1] "%{ count } tracce corrispondono ai filtri selezionati"
 
 #: front/src/components/playlists/Card.vue:18
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} traccia"
 msgstr[1] "%{ count} tracce"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ current } usato su %{ max } consentito"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } o %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
-msgstr ""
-"%{ username } ha accettato la tua richiesta di seguire la libreria \"%{ "
-"library }\""
+msgstr "%{ username } ha accettato la tua richiesta di seguire la libreria \"%{ library }\""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr "%{ username } segue la tua libreria \"%{ library }\""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } vuole seguire la tua libreria \"%{ library }\""
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Profilo di %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
-msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">A "
-"proposito di %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
+msgstr "<strong>%{ track }</strong> è già nella <strong>%{ playlist }</strong>."
 
 #: front/src/components/audio/artist/Card.vue:41
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 album"
 msgstr[1] "%{ count } album"
 
 #: front/src/components/favorites/List.vue:10
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 mi piace"
 msgstr[1] "%{ count } mi piace"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Una libreria pulita"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "C'è stato un errore durante il caricamento di questo file"
 
+#: front/src/components/library/EditForm.vue:145
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Un breve riassunto che descrive le tue modifiche."
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "A proposito di %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "A proposito di %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "A proposito di Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Pagina di informazioni"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "A proposito di questa istanza"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Accetta"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Accettato"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Accesso disabilitato"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
-msgstr "Accedi alla tua musica da un'interfaccia pulita che si focalizza su quello che conta davvero"
-
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr "Accedi ai file audio, librerie, artisti, album e tracce"
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Accesso ai filtri del contenuto"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Accesso alle modifiche"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr "Accedi ad email, nome utente e informazioni del profilo"
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Accesso ai preferiti"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr "Accesso ai seguiti"
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr "Accedi alla cronologia di ascolto"
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Accesso alle notifiche"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Accesso alle playlist"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Accesso alle radio"
+
+#: front/src/components/Home.vue:101
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr ""
+"Accedi alla tua musica da un'interfaccia pulita che si focalizza su quello "
+"che conta davvero"
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
 msgstr "Data di accesso"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Account"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Account"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Dati dell'account"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Impostazioni dell'account"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Impostazioni dell'account"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Stato dell'account"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Email dell'account"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Account"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Azione"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
-msgstr[0] "L'azione %{ action } è stata lanciata con successo su %{ count } elemento"
-msgstr[1] "L'azione %{ action } è stata lanciata con successo su %{ count } elementi"
-
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+msgstr[0] ""
+"L'azione %{ action } è stata lanciata con successo su %{ count } elemento"
+msgstr[1] ""
+"L'azione %{ action } è stata lanciata con successo su %{ count } elementi"
+
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Azioni"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Attivo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Attività"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Visibilità dell'attività"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Aggiungi"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Aggiungi un dominio"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Aggiungi una nuova regola di moderazione"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Aggiungi una nuova regola di moderazione"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Aggiungi e gestisci contenuti"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr "Aggiungi comunque"
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Aggiungi contenuto"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Aggiungi filtro"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Aggiungi filtri per personalizzare la tua radio"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Aggiungi alla coda attuale"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Aggiungi ai preferiti"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Aggiungi alla playlist…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Aggiungi alla coda"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Aggiungi a questa playlist"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Aggiungi traccia"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Amministratore"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Amministrazione"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
+msgid "Album"
+msgstr "Album"
+
+#: front/src/views/admin/library/TrackDetail.vue:107
+msgctxt "*/*/*/Noun"
 msgid "Album"
 msgstr "Album"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Album contenente %{ count } traccia, di %{ artist }"
-msgstr[1] "Album contenente %{ count } tracce, di %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:128
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Artista dell'album"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
+#: front/src/views/admin/library/AlbumDetail.vue:92
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
+msgstr "Dati dell'album"
+
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Album name"
 msgstr "Nome album"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Pagina dell'album"
-
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Albums"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Albums di questo artista"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Tutto"
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "Tutto, %{ count } elemento, selezionato"
+msgstr[1] "Tutti gli %{ count } elementi selezionati"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr "Permetti applicazione"
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+"Si è verificato un errore durante l'elaborazione del caricamento. Troverai "
+"maggiori informazioni qui sotto."
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "C'è stato un errore durante il salvataggio delle tue modifiche"
 
+#: front/src/components/federation/FetchButton.vue:21
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr ""
+"Si è verificato un errore durante il tentativo di aggiornamento dei dati:"
+
+#: front/src/components/federation/FetchButton.vue:41
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Si è verificato un errore HTTP contattando il server remoto"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Si è verificato un errore sconosciuto, questo significa che il server è offline o non può essere raggiunto"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr "Si è verificato un errore sconosciuto"
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Applicazione"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr "Dettagli dell'applicazione"
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr "ID Applicazione"
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+"L'ID dell'applicazione e il suo secret sono valori molto sensibili e devono "
+"essere trattati come password. Non condividerli con nessun altro."
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr "Secret dell'applicazione"
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "Approva"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Approvato"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr "Approvata ed applicata"
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Sei sicuro di volerti disconnettere?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artista"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artista"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
+msgstr "Dati dell'artista"
+
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Artist name"
 msgstr "Nome dell'artista"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Pagina dell'artista"
-
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artista, album, traccia…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artisti"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artisti"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "Crescente"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Chiedi un reset della password"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Contenuto audio"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Scorciatoie del lettore audio"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr "Autorizza %{ app }"
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr "Autorizza app di terze parti"
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr "App autorizzate"
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Playlist disponibili"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Torna alla pagina di accesso"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Torna alle impostazioni"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Bitrate"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "Blocca tutto"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"Blocca tutto da questo account o dominio. Questo prevenirà qualsiasi "
-"interazione con l'entità, ed eliminerà i relativi contenuti (caricamenti, "
-"librerie, richieste di seguire, ecc.)"
+msgstr "Blocca tutto da questo account o dominio. Questo prevenirà qualsiasi interazione con l'entità, ed eliminerà i relativi contenuti (caricamenti, librerie, richieste di seguire, ecc.)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Sfoglia"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Sfoglia libreria"
 
+#: front/src/components/library/Albums.vue:4
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Sfogliando album"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Sfogliando artisti"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Sfogliando playlists"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Sfogliando radio"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Crea"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "Di %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
-msgstr ""
-"Smettendo di seguire questa libreria, perderai l'accesso al suo contenuto."
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+msgstr "Smettendo di seguire questa libreria, perderai l'accesso al suo contenuto."
+
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr "Dimensione in cache"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Annulla"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Candidati"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Non puoi cambiare la tua password"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "Impossibile caricare questo file, controlla che non sia troppo grande"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Cambia lingua"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Cambia la mia password"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Cambia password"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Cambia la tua password"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Cambiare la tua password?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Modifiche sincronizzate con il server"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Cambiando la tua password cambierà anche la password della API Subsonic se ne hai richiesta una."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
-msgstr "Cambiare la tua password avrà queste conseguenze"
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
+msgstr "Cambiare la tua password avrà queste conseguenze:"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Stanza di conversazione"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+"Controllando i permessi \"Lettura\" o \"Scrittura\" del livello superiore "
+"implica l'accesso a tutti i corrispondenti permessi dei livelli inferiori."
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Scegli la tua istanza"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Pulisci libreria"
+#: front/src/components/library/EditForm.vue:75
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Pulisci"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Pulisci"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Pulisci playlist"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Pulisci la tua coda"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Clicca una volta, ascolta per ore utilizzando le radio integrate"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+"Clicca per visualizzare più informazioni sul processo di importazione di "
+"questo caricamento"
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Clicca per selezionare i file da caricare o trascina e rilascia file o cartelle"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "Chiudi"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "Chiudi"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr "Chiudi e ricarica pagina"
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Codice"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Riduci"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Configurazione"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Conferma"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Conferma il tuo indirizzo e-mail"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Codice di conferma"
 
-#: front/src/components/common/ActionTable.vue:7
-msgid "Content have been updated, click refresh to see up-to-date content"
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr "Filtro di contenuto aggiunto con successo"
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Filtri di contenuto"
+
+#: front/src/components/auth/Settings.vue:116
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Filtri di contenuto"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
 msgstr ""
-"Il contenuto è stato aggiornato, clicca aggiorna per visualizzaare il "
-"contenuto aggiornato"
+"I filtri di contenuti ti aiutano a nascondere cose che non vuoi vedere su "
+"questo servizio."
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "Il contenuto è stato aggiornato, clicca aggiorna per visualizzaare il contenuto aggiornato"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Contribuisci"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Copia"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
-msgstr "Copia tracce dalla tua coda corrente alla playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
+msgstr "Copia tracce dalla coda alla playlist"
+
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr "Copia-incolla il codice seguente in questa applicazione:"
 
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr "Copia/incolla questo codice nel tuo sito HTML"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Copyright"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Non è stato possibile confermare il tuo indirizzo e-mail"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Non è stato possibile recuperare la libreria remota"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-"Non è stato possibile processare questa traccia, assicurati che sia "
-"correttamente etichettata"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Copertine, testi, il nostro obbiettivo è averli tutti ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Crea"
 
 #: front/src/components/auth/Signup.vue:4
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Crea un account funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Crea una nuova applicazione"
+
+#: front/src/components/auth/Settings.vue:220
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Crea una nuova applicazione"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Crea una nuova libreria"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Crea una nuova playlist"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Crea un account"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Crea applicazione"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Crea libreria"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Crea il mio account"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr "Crea una per integrare Funkwhale con applicazioni di terze parti."
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Crea playlist"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Crea la tua radio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Data di creazione"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Avatar attuale"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Libreria attuale"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Traccia corrente"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Utilizzo attuale"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr "I dati riportati dal server remoto hanno attributi invalidi o mancanti"
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr "I dati sono stati aggiornati con successo dal server remoto."
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Data"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Informazioni di debug"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Diminuisci volume"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Elimina"
 
+#: front/src/components/auth/Settings.vue:254
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Elimina applicazione"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr "Eliminare l'applicazione \"%{ application }\"?"
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Elimina libreria"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Elimina regola di moderazione"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Elimina playlist"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Elimina radio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Eliminare questo album?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Eliminare questo artista?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Eliminare questa libreria?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Eliminare questa regola di moderazione?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Eliminare questo suggerimento?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Eliminare questo caricamento?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Decrescente"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Descrizione"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Dettaglio"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Descrizione"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Dettagli"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Determina quanto contenuto un utente può caricare. Lascia vuoto per usare il valore predefinito dell'istanza."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Imposta il livello di visibilità delle tue attività"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Disabilita accesso"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Disabilita accesso Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Disabilitare l'accesso alle API Subsonic?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Disabilitato"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr "Numero disco"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Scopri come utilizzare Funkwhale attraverso altre app"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Nome visualizzato"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Mostra pubblicamente"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Non scaricare nessun media (audio, copertina dell'album, avatar "
-"dell'account...) da questo account o dominio. Questo eliminerà anche i "
-"contenuti già esistenti."
+msgstr "Non scaricare nessun media (audio, copertina dell'album, avatar dell'account...) da questo account o dominio. Questo eliminerà anche i contenuti già esistenti."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Vuoi pulire la playlist \"%{ playlist }\"?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Vuoi confermare questa azione?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Vuoi eliminare la playlist \"%{ playlist }\"?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Vuoi eliminare la radio \"%{ radio }\"?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Vuoi nascondere i contenuti dell'artista \"%{ name }\"?"
+
+#: front/src/components/common/ActionTable.vue:37
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Vuoi eseguire %{ action } su %{ count } elemento?"
 msgstr[1] "Vuoi eseguire %{ action } su %{ count } elementi?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Vuoi ripristinare la tua coda precedente?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Documentazione"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Dominio"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Domini"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Scarica"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Trascina e rilascia righe per riordinare le tracce nella playlist"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Durata"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Indirizzo e-mail confermato"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Facile da utilizzare"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Modifica"
+
+#: front/src/components/auth/Settings.vue:246
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Modifica"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Modifica applicazione"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Modifica le info dell'istanza"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Modifica…"
-
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Modifica regola di moderazione"
+
+#: front/src/components/library/AlbumEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Modifica questo album"
+
+#: front/src/components/library/ArtistEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Modifica questo artista"
+
+#: front/src/components/library/TrackEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Modifica questa traccia"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Modifiche"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Modifiche"
+
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Email"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Indirizzo email"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Incorpora"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "Incorpora codice"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr "Incorpora questo album nel tuo sito web"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Incorpora il lavoro di questo artista nel tuo sito web"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "Incorpora questa traccia nel tuo sito web"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr "Emessi i follow della libreria"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr "Messaggi emessi"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "Abilitato"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Fine modifica"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Inserisci l'URL di una libreria"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Inserisci un nome di una radio…"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr "Inserisci il titolo dell'album..."
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Inserisci il nome di un artista…"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Inserisci il nome di una playlist…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Inserisci l'indirizzo email collegato al tuo account"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Inserisci la tua email"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Inserisci il tuo codice di invito (non tiene conto di maiuscole o minuscole)"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Inserisci i tuoi criteri di ricerca…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Inserisci il tuo nome utente"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Inserisci il tuo nome utente o l'email"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Errore"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Dettaglio dell'errore"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Segnalazione errore"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Tipo di errore"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Errore durante l'esecuzione dell'azione"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Errore durante la richiesta di un reset della password"
 
+#: front/src/components/auth/Authorize.vue:6
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Errore durante l'autorizzazione dell'applicazione"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Errore durante la modifica della password"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Errore durante la creazione del dominio"
 
+#: front/src/components/moderation/FilterModal.vue:13
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Errore durante la creazione del filtro"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Errore durante la creazione dell'invito"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Errore durante la creazione della regola"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Errore durante il recupero dei dati dell'applicazione"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Errore durante il recupero delle informazioni del nodo"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Errore durante il salvataggio delle impostazioni"
+
+#: front/src/components/federation/FetchButton.vue:73
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Errore durante il salvataggio delle impostazioni"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Errore durante l'invio della modifica"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Si è verificato un errore"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "File con errore"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Tutti"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Tutti su questa istanza"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Tutti, su tutte le istanze"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Escludi"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Data di scadenza"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Scaduto"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Scaduto/utilizzato"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
-"Spiega perchè stai applicando questa regola. In base alla configurazione "
-"della tua istanza, questo ti aiuterà a ricordare perchè hai eseguito questa "
-"azione su questo account o dominio, e può essere mostrata pubblicamente per "
-"aiutare gli utenti a capire quali regole sono applicate qui."
+msgstr "Spiega perchè stai applicando questa regola. In base alla configurazione della tua istanza, questo ti aiuterà a ricordare perchè hai eseguito questa azione su questo account o dominio, e può essere mostrata pubblicamente per aiutare gli utenti a capire quali regole sono applicate qui."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "Fallito"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Tracce con errore:"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Tracce preferite"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Preferiti"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Preferiti"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federazione"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "ID Federazione"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr "Campo"
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nome file"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Files"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Filtra nome"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Finito"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr "Visto per la prima volta"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Visto per la prima volta in data"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Segui"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Segui librerie remote"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Richiesta di seguire in attesa di approvazione"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Seguito da"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Seguito da"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Seguendo"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Dall'album %{ album } di %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Segue"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+"Dall'album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> di <a "
+"class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+
+#: front/src/components/auth/Authorize.vue:28
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Accesso completo"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale è compatibile con altri lettori musicali che supportano le Subsonic API."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale è semplicissimo da usare."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale è progettato per permetterti di ascoltare facilmente la musica che ti piace, o per farti scoprire nuovi artisti."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale è gratuito e ti da il controllo sulla tua musica."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale si preoccupa di gestire la tua musica"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "Scorciatoie generali"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Ottieni un nuovo invito"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Portami alla libreria"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
-msgstr "Ottieni metadati di qualità sulla tua musica grazie a <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
+msgstr ""
+"Ottieni metadati di qualità sulla tua musica grazie a <a href=\"%{ url }\" "
+"target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
-msgstr "Iniziamo"
+msgstr "Per iniziare"
+
+#: front/src/components/library/ImportStatusModal.vue:45
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Chiedi aiuto"
 
 #: front/src/components/Footer.vue:37
+msgctxt "Footer/*/Link"
 msgid "Getting help"
-msgstr "Ricevendo aiuto"
+msgstr "Chiedi aiuto"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Vai"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Vai alla pagina iniziale"
 
+#: front/src/components/auth/Settings.vue:128
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Artisti nascosti"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
-msgstr ""
-"Nascondi contenuto dell'account o del dominio, ad esclusione dei seguaci."
+msgstr "Nascondi contenuto dell'account o del dominio, ad esclusione dei seguaci."
+
+#: front/src/components/moderation/FilterModal.vue:40
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Nascondi contenuto"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr "Nascondi contenuti di questo artista"
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr "Nascondi contenuti di questo artista…"
 
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Pagina Iniziale"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Ore di musica"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Comunque, accedere a Funkwhale da quei client richiede un'altra password che puoi impostare qui sotto."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Se l'indirizzo email fornito nel passo precedente è valido e legato ad un account utente, dovresti ricevere un'email con le istruzioni per il reset nel prossimo paio di minuti."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Importa data"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
+"Se autorizzi applicazioni di terze parti ad accedere ai tuoi dati, queste "
+"applicazioni verranno elencate qui."
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importa musica da varie piattaforme, come YouTube o SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Dettaglio dell'importazione"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Importa riferimento"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Stato dell'importazione"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "Stato dell'importazione"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importato"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Data di importazione"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr "Impossibile connettersi al server remoto"
+
+#: front/src/components/moderation/FilterModal.vue:26
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Nel widget \"Aggiunti recentemente\""
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr "Negli elenchi di artisti ed album"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "Nei preferiti"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr "Nei preferiti di altri utenti e nella cronologia di ascolto"
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr "Nei suggerimenti radio"
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Inattivo"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "Aumenta volume"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Inserisci l'indirizzo email collegato al tuo account"
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
-msgstr[0] "Inserita dalla coda (%{ count } traccia)"
-msgstr[1] "Inserite dalla coda (%{ count } tracce)"
+msgstr[0] "Inserisci dalla coda (%{ count } traccia)"
+msgstr[1] "Inserisci dalla coda (%{ count } tracce)"
+
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Istanza"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Dati dell'istanza"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Informazioni sull'istanza"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Radio dell'istanza"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Impostazioni dell'istanza"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "URL dell'istanza"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
-msgstr ""
-"Tipo di file non valido, assicurati che stai caricando un file audio. Le "
-"estensioni di file supportate sono %{ extensions }"
+msgstr "Tipo di file non valido, assicurati che stai caricando un file audio. Le estensioni di file supportate sono %{ extensions }"
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
+msgstr "Metadati non validi"
+
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Codice di invito"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Codice d'invito (opzionale)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Inviti"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Elenco problemi"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr "Non è possibile connettersi all'URL dato"
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Tieni d'occhio le tue tracce preferite"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr "Scorciatoie da tastiera"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Account conosciuti"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Librerie conosciute"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
-msgstr "Ultime attività"
+msgstr "Ultima attività"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "Controllato l'ultima volta"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Ultima modifica"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "Visto l'ultima volta"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Visto l'ultima volta in data"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Ultimo aggiornamento:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Inizia"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Scopri di più su questa istanza"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Lascia vuoto per un codice casuale"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Lascia vuoto per un widget adattivo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Librerie"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Librerie"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Librerie e caricamenti"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "Le librerie sono di aiuto per organizzare e condividere la tua collezione musicale. Puoi caricare la tua musica su Funkwhale e condividerla con amici e parenti."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Libreria"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Libreria creata"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Dati della libreria"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Libreria eliminata"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
-msgstr "File della libreria"
+#: front/src/views/admin/library/EditsList.vue:4
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
+msgstr "Modifiche della libreria"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Libreria aggiornata"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "Licenza"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr "Ascolti"
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr "Ascolti"
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Carica di più…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Caricando la lista di chi ti segue…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Caricando le Librerie…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Caricando i dati della libreria…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Caricando le notifiche…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
-msgstr "Caricando le librerie remote..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "Caricando le librerie remote…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Caricando i dati di utilizzo…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Caricando i tuoi preferiti…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr "Locale"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Account locale"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Accedi"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Accedi al tuo account Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Disconnetti"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Accesso effettuato come %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Accedi"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Stato dell'accesso"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Disconnettiti"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
-msgstr ""
-"Sembra che tu non abbia ancora nessuna libreria, è tempo di crearne una."
+msgstr "Sembra che tu non abbia ancora nessuna libreria, è tempo di crearne una."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Ripetizione disattivata. Clicca per attivare la ripetizione della singola traccia."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Ripeti una singola traccia. Clicca per ripetere l'intera coda."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Ripete l'intera coda. Clicca per disattivare la ripetizione."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Testi"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "Menu principale"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Gestisci libreria"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Gestisci playlist"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Gestisci utenti"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Gestisci le tue playlist"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Segna tutte come lette"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Segna come letta"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Segna come non letta"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr "Riproduttore musicale"
 
+#: front/src/components/auth/Profile.vue:12
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Membro da %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "Applicazioni desktop e mobile"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Moderazione"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
-"Le regole di moderazione ti aiutano a controllare come la tua istanza "
-"interagisce con un dato dominio o account."
+msgstr "Le regole di moderazione ti aiutano a controllare come la tua istanza interagisce con un dato dominio o account."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Modifica %{ id }"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Data di modifica"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr "Di più…"
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Musica"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Muto"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Silenzia attività"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Silenzia notifiche"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Mio account"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "La mia stupenda descrizione"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "La mia eccezionale libreria"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "La mia eccezionale playlist"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "La mia eccezionale radio"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Le mie librerie"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "N/D"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:39
-#: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
+#: front/src/components/manage/moderation/AccountsTable.vue:39
+#: front/src/components/manage/moderation/DomainsTable.vue:38
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nome"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nuova password"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Le nuove tracce saranno allegate qui automaticamente."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr "Nuovo valore"
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Prossima traccia"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "No"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Nessun addon, nessun plugin: ti serve solo una libreria in rete"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Nessun album corrisponde alla tua ricerca"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Nessun artista corrisponde alla tua ricerca"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
-msgstr "Nessun testo disponibile per questa traccia."
+#: front/src/components/library/TrackDetail.vue:14
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
+msgstr ""
+"Nessuna informazione sui diritti d'autore disponibile per questa traccia"
+
+#: front/src/components/library/TrackDetail.vue:25
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Nessuna informazione sulla licenza per questa traccia"
 
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Nessuna libreria corrispondente."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
-msgstr "Ancora nessuna notifica."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr "Nessuna notifica da visualizzare."
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr "Nessun risultato trovato."
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Nessuno tranne me"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Nessuno segue questa libreria"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Non utilizzato"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Notifiche"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Notifiche"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Sito ufficiale"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Vecchia password"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr "Vecchio valore"
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Aperto"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+"Apri una conversazione di supporto (includi nel tuo messaggio le "
+"informazioni di debug qui sotto)"
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Apri nell'interfaccia di moderazione"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Apri profilo locale"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Apri su MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "Apri profilo"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Apri profilo remoto"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Apri sito web"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "O personalizza la tua regola"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Ordine"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Ordinamento"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Direzione di ordinamento"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Proprietario"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Pagina non trovata"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Pagina non trovata!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr "Impaginazione"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Password"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Password aggiornata"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Password aggiornata con successo"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Metti in pausa"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr "Pausa/riproduci la traccia corrente"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "In pausa"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "In sospeso"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Approvazione in sospeso"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "File in sospeso"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Richiesta di seguire in sospeso"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Revisione in sospeso"
+
+#: front/src/components/Sidebar.vue:226
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Revisioni delle modifiche in sospeso"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Permessi"
+
+#: front/src/components/auth/Settings.vue:176
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Permessi"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Riproduci"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Riproduci tutto"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Riproduci tutti gli album"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Riproduci la prossima"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Riproduci traccia successiva"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Riproduci ora"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Riproduci traccia precedente"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr "Riproduci canzoni simili"
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Riproduci questa traccia"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Riproduci traccia"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Riproduci..."
+
+#: front/src/views/playlists/Detail.vue:91
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Lista di riproduzione"
 
 #: front/src/views/playlists/Detail.vue:12
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Lista di riproduzione contenente %{ count } traccia, di %{ username }"
 msgstr[1] "Lista di riproduzione contenente %{ count } tracce, di %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Lista di riproduzione creata"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Modifica lista di riproduzione"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nome lista di riproduzione"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Lista di riproduzione aggiornata"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Visibilità lista di riproduzione"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Liste di riproduzione"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Liste di riproduzione"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "Liste di riproduzione? Ce le abbiamo"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Per favore controlla se la tua password è corretta"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Per favore controlla se la combinazione nome utente/password è corretta"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF or JPG. Massimo 2MB. Saranno scalate a 400x400px."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Posizione"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
-"Evita che l'account o il dominio facciano scattare notifiche, ad esclusione "
-"dei seguaci."
+msgstr "Evita che l'account o il dominio facciano scattare notifiche, ad esclusione dei seguaci."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "Anteprima"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Traccia precedente"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr "Privato"
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Errore durante la scansione"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Procedi"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Procedi all'accesso"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Elaborazione"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Profilo"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1899,1097 +3138,1946 @@ msgstr "Elaborazione"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Rimuovi"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Rimuovere file con errori?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Rimuovere file in attesa?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Rimuovere file saltati?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Coda"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "Coda mischiata!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Creatore Radio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Radio creata"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nome radio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Radio aggiornata"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radio"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radio"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr "Lettura"
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr "Leggi la nostra documentazione per questo errore"
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr "Sola lettura"
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr "Accesso in sola lettura ai dati utente"
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
-msgstr "Motivazione"
+msgstr "Motivo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr "Ricevuto un follow della libreria"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "Messaggi ricevuti"
 
+#: front/src/components/library/EditForm.vue:27
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Modifiche recenti"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr "Modifiche recenti in attesa di revisione"
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Aggiunte recentemente"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Preferiti recenti"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Ascoltate recentemente"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr "URI di redirezione"
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Aggiorna"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Errore di aggiornamento"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr "Aggiorna da un server remoto"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr "Aggiorna informazioni del nodo"
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Aggiornamento in sospeso"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+"La richiesta di aggiornamento non è stata processata in tempo dal nostro "
+"server. Sarà processata più tardi."
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr "Aggiornamento riuscito"
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "Aggiorna tabella dei contenuti"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Registrato da %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr "L'aggiornamento è stato rimandato"
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr "Aggiornando oggetto da remoto…"
 
 #: front/src/components/auth/Signup.vue:9
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
-msgstr "Le registrazioni sono chiuse su questa istanza, hai bisogno di un codice d'invito per registrarti."
+msgstr ""
+"Le registrazioni sono chiuse su questa istanza, avrai bisogno di un codice "
+"d'invito per registrarti."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
-msgstr "utente semplice"
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
+msgstr "Utente semplice"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Rifiuta"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Rifiuta media"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Rifiutato"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Riavvia importazione"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Data di rilascio"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr "Spazio di archiviazione rimanente"
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Librerie remote"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Le librerie remote sono di proprietà di altri utenti nella rete. Puoi accedervi se sono pubbliche o se ti è stato dato l'accesso ad esse."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Rimuovi"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Rimuovi avatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Rimuovi filtro"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Rimuovi dai preferiti"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
-"Rimuovi completamente tracce caricate ma non ancora processate, aggiungendo "
-"lo spazio corrispondente alla tua quota."
+msgstr "Rimuovi completamente tracce caricate ma non ancora processate, aggiungendo lo spazio corrispondente alla tua quota."
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
-"Rimuove completamente le tracce caricate ma che sono state saltate durante "
-"la fase di importazione, aggiungendo lo spazio corrispondente alla tua quota."
+msgstr "Rimuove completamente le tracce caricate ma che sono state saltate durante la fase di importazione, aggiungendo lo spazio corrispondente alla tua quota."
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr ""
-"Rimuove completamente le tracce caricate ma che non sono state processate "
-"correttamente, aggiungendo lo spazio corrispondente alla tua quota."
+msgstr "Rimuove completamente le tracce caricate ma che non sono state processate correttamente, aggiungendo lo spazio corrispondente alla tua quota."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Richiedi una nuova password"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Richiedere una nuova password API Subsonic?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Richiedi una password"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr "Richiedendo un recupero…"
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr "Ripristina al valore iniziale: %{ value }"
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Resetta la tua password"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Riavvia importazione"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Risultati per pagina"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr "Restringi alle modifiche non revisionate"
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Torna alla pagina di accesso"
 
+#: front/src/components/library/ArtistDetail.vue:9
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Revisiona i miei filtri"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr "Revoca"
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr "Revoca accesso"
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr "Revoca accesso per l'applicazione \"%{ application }\"?"
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "Regola"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Salva"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Scansione avviata"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Scansiona ora"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Scansione in sospeso"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Scansione saltata (la scansione precedente è troppo recente)"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "Scansione in attesa"
-
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Scansionata"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Scansione eseguita con errori"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Scansionando... (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr "Visibilità"
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr "Visibilità"
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Cerca"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Cerca una libreria remota"
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Cerca per account, informazioni, dominio…"
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Cerca per dominio, attore, nome, descrizione…"
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Cerca per dominio, attore, nome, riferimento, sorgente…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Cerca per dominio, nome, ID MusicBrainz…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Cerca per dominio, titolo, artista, album, ID MusicBrainz…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Cerca per dominio, titolo, artista, ID MusicBrainz…"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
-msgstr "Cerca per dominio, nome utente, descrizione..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Cerca per dominio, nome utente, descrizione…"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
-msgstr "Cerca per nome..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Cerca per nome…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
 msgstr "Cerca per titolo, artista, album…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "Cerca per titolo, artista, dominio…"
-
 #: front/src/components/manage/users/InvitationsTable.vue:153
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
-msgstr "Cerca per nome utente, email, codice…"
+msgstr "Cerca per nome utente, indirizzo e-mail, codice…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Cerca per nome utente, indirizzo e-mail, nome…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Cerca per artisti, album, tracce…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Cerca un po' di musica"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Cerca su lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Cerca su Wikipedia"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr "Menu secondario"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Sezioni"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Seleziona un filtro"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
-msgstr[0] "Seleziona tutti %{ total } elemento"
-msgstr[1] "Seleziona tutti %{ total } elementi"
+msgstr[0] "Seleziona tutto, %{ total } elemento"
+msgstr[1] "Seleziona tutti e %{ total } elementi"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Seleziona solo la pagina attuale"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Impostazioni"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Impostazioni aggiornate"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Impostazioni aggiornate con successo."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Condividi collegamento"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"Condividi questo collegamento con altri utenti in modo che possano "
-"richiedere l'accesso alla tua libreria."
+msgstr "Condividi questo collegamento con altri utenti in modo che possano richiedere l'accesso alla tua libreria."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Condividi collegamento"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "Mostra %{ count } traccia in più"
 msgstr[1] "Mostra %{ count } tracce in più"
 
 #: front/src/components/audio/artist/Card.vue:30
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Mostra 1 altro album"
 msgstr[1] "Mostra %{ count } altri album"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr "Mostra tutte le modifiche"
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "Mostra scorciatoie da tastiera disponibili"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Mostra notifiche lette"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Mostra/nascondi password"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
-msgstr "Mostrando risultati %{ start }-%{ end } su %{ total }"
+msgstr "Mostrando i risultati da %{ start } a %{ end } su %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Mischia la tua coda"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Mischia la tua coda"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Registrati"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Registrati"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Data di registrazione"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
-msgstr "Silenzia l'attività"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "Silenzia le notifiche"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Dimensione"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Dimensione"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Saltato"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "File saltati"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "Software"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+"Alcune tracce nella tua coda sono già presenti in questo elenco di "
+"riproduzione:"
+
+#: front/src/components/PageNotFound.vue:10
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Ci dispiace, la pagina che hai richiesto non esiste:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Codice sorgente"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Membro dello staff"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Inizia"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Riproduci radio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Statistiche"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
-"Le statistiche sono calcolate da attività conosciute e contenuti della tua "
-"istanza, e non riflette l'attività generale per questo account"
+msgstr "Le statistiche sono calcolate da attività conosciute e contenuti della tua istanza, e non riflette l'attività generale per questo account"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
+msgstr "Le statistiche sono calcolate da attività conosciute e contenuti della tua istanza, e non riflette l'attività generale per questo dominio"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
 msgstr ""
 "Le statistiche sono calcolate da attività conosciute e contenuti della tua "
-"istanza, e non riflette l'attività generale per questo dominio"
+"istanza, e non riflette l'attività generale per questo oggetto"
+
+#: front/src/components/library/FileUpload.vue:95
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Stato"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Stato"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Stato"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Stato"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Stato"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Ferma"
+#: front/src/views/content/libraries/Detail.vue:28
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Stato"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Ferma radio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Invia"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr "Invia e applica modifica"
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr "Invia un'altra modifica"
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr "Invia suggerimento"
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Password API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr "Suggerisci una modifica utilizzando il modulo qui sotto."
+
+#: front/src/components/library/AlbumEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Suggerisci una modifica su questo album"
+
+#: front/src/components/library/ArtistEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Suggerisci una modifica su questo artista"
+
+#: front/src/components/library/TrackEdit.vue:5
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Suggerisci una modifica su questa traccia"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Scelte suggerite"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Riepilogo"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr "Riassunto (opzionale)"
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "Forum di supporto"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr "Estensioni supportate: %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Sincronizzando le modifiche con il server…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Testo copiato negli appunti!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "È molto semplice: amavamo Grooveshark e volevamo creare qualcosa ancora più bello."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+"L'album sarà rimosso, ed anche i caricamenti associati, tracce, preferiti e "
+"cronologia di ascolto. Questa azione è irreversibile."
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr "L'applicazione sta anche richiedendo i seguenti permessi sconosciuti:"
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+"L'artista sarà rimosso, ed anche i caricamenti associati, tracce, album, "
+"preferiti e cronologia di ascolto. Questa azione è irreversibile."
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "Il logo di Funkwhale è stato gentilmente disegnato e concesso da Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr "L'indirizzo fornito non è quello di un server Funkwhale"
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
-msgstr ""
-"La libreria e tutte le sue tracce saranno eliminate. Questa azione è "
-"irreversibile."
+msgstr "La libreria e tutte le sue tracce saranno eliminate. Questa azione è irreversibile."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
-msgstr "I file musicali che stai caricando sono correttamente etichettati:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
+msgstr ""
+"La libreria sarà rimossa, ed anche i caricamenti associati e gli iscritti. "
+"Questa azione è irreversibile."
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
 msgstr ""
-"La traccia seguente verrà riprodotta automaticamente tra pochi secondi..."
+"I metadati inclusi nel file non sono validi o alcuni campi obbligatori sono "
+"mancanti."
 
-#: front/src/components/Home.vue:121
+#: front/src/components/library/FileUpload.vue:38
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
+msgstr "I file musicali che stai caricando sono correttamente etichettati."
+
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "La traccia seguente verrà riprodotta automaticamente tra pochi secondi…"
+
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "La piattaforma è libera e open source, puoi installarla e modificarla senza problemi"
 
+#: front/src/components/playlists/Form.vue:14
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "La lista di riproduzione non può essere creata"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr "Il server remoto ha risposto con il codice HTTP %{ status }"
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+"Il server remoto ha risposto, ma i dati ricevuti non sono supportati da "
+"Funkwhale."
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr "Il server remoto non ha risposto abbastanza velocemente"
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr "Il server remoto ha risposto con dati JSON o JSON-LD non validi"
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+"Gli album selezionati saranno rimossi, ed anche i caricamenti associati, "
+"tracce, preferiti e cronologia di ascolto. Questa azione è irreversibile."
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+"Gli artisti selezionati saranno rimossi, ed anche i caricamenti associati, "
+"tracce, album, preferiti e cronologia di ascolto. Questa azione è "
+"irreversibile."
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+"Le librerie selezionate saranno rimosse, ed anche i caricamenti associati, "
+"ed iscritti. Questa azione è irreversibile."
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+"Le tracce selezionate saranno rimosse, ed anche i caricamenti associati, "
+"preferiti e cronologia di ascolto. Questa azione è irreversibile."
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Il caricamento selezionato sarà rimosso. Questa azione è irreversibile."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr "Il server potrebbe essere caduto"
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "L'API Subsonic non è disponibile su questa istanza Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+"Il suggerimento sarà completamente rimosso, questa azione è irreversibile."
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "La traccia non può essere aggiunta alla lista di riproduzione"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr "La traccia non può essere caricata"
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+"La traccia sarà rimossa, ed anche i caricamenti associati, preferiti e "
+"cronologia di ascolto. Questa azione è irreversibile."
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Il caricamento sarà rimosso. Questa azione è irreversibile."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "I file musicali caricati sono in formato OGG, Flac o MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
-msgstr ""
-"Offriamo vari modi per recuperare nuovi contenuti e renderli disponibili qui."
+msgstr "Offriamo vari modi per recuperare nuovi contenuti e renderli disponibili qui."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "Questa azione è irreversibile."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Questo album è presente nelle seguenti librerie:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Questo artista è presente nelle seguenti librerie:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr "Questo dominio è soggetto a regole specifiche di moderazione"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr "Questa istanza offre fino a %{quota} di spazio di archiviazione per ogni utente."
+
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
 msgstr ""
-"Questa istanza offre fino a %{quota} di spazio di archiviazione per ogni "
-"utente."
+"Questa è la lista di applicazioni che hanno accesso ai dati del tuo account."
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr "Questa è la lista di applicazioni che hai creato."
 
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "Questo sei tu!"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Questa libreria contiene la mia musica personale, spero vi piaccia."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
-"Questa libreria è privata e la tua approvazione dal suo proprietario è "
-"necessaria per accedere al suo contenuto"
+msgstr "Questa libreria è privata e la tua approvazione dal suo proprietario è necessaria per accedere al suo contenuto"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
-msgstr ""
-"Questa libreria è pubblica e tu puoi accedere al suo contenuto liberamente"
+msgstr "Questa libreria è pubblica e tu puoi accedere al suo contenuto liberamente"
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
-msgstr ""
-"Questo può coinvolgere molti elementi o avere conseguenze irreversibili, per "
-"favore ricontrolla se è proprio quello che vuoi."
+msgstr "Questo può coinvolgere molti elementi o avere conseguenze irreversibili, per favore ricontrolla se è proprio quello che vuoi."
+
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr "Questo oggetto è gestito da un altro server, non puoi modificarlo."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Questo riferimento sarà utilizzato per raggruppare file importati."
 
-#: front/src/components/audio/PlayButton.vue:73
-msgid "This track is not available in any library you have access to"
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr ""
+"Non è stato possibile processare questa traccia, assicurati che sia "
+"correttamente etichettata"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
 msgstr ""
-"Questa traccia non è disponibile in nessuna libreria alla quale hai accesso"
+"Questa traccia è stata caricata, ma non è ancora stata processata dal server"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "Questa traccia è già presente in una delle tue librerie"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
+msgid "This track is not available in any library you have access to"
+msgstr "Questa traccia non è disponibile in nessuna libreria alla quale hai accesso"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Questa traccia è presente nelle seguenti librerie:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Questo cancellerà questa lista di riproduzione e non può essere annullato."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Questo cancellerà questa radio e non può essere annullato."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Questo disabiliterà completamente l'accesso alla API Subsonic dagli account."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr ""
-"Questo cancellerà i tuoi dati locali e ti disconnetterà, vuoi continuare?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Questo ti disconnetterà dai dispositivi esistenti che utilizzano la password attuale."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr ""
+"Questo cancellerà permanentemente l'applicazione e tutti i token associati."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+"Questo eviterà a questa applicazione di accedere al servizio a tuo nome."
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Questo cancellerà tutte le tracce da questa lista di riproduzione e non può essere annullato."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Titolo"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Titolo"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
 msgid "Title"
 msgstr "Titolo"
 
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+"Per continuare, per favore seleziona l'istanza Funkwhale alla quale vuoi "
+"connetterti. Inserisci l'indirizzo direttamente, o selezionane uno dalla "
+"lista di suggerimenti."
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr "Cambia tipo di riproduzione della coda"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "Dimensione totale"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Dimensione totale dei files in questa libreria"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Utenti totali"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+msgctxt "*/*/*/Noun"
+msgid "Track"
+msgstr "Traccia"
+
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
 msgid "Track"
 msgstr "Traccia"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "La traccia era già presente in una delle tue librerie"
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr "Traccia #%{ id } - %{ name }"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/views/admin/library/TrackDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Dati della traccia"
+
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Informazioni traccia"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Filtro corrispondenze traccia"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Nome traccia"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "La traccia è stata caricata ma non ancora processata dal server"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Tracce"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "tracce"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Tracce"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Tracce di questo artista"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Tracce preferite"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "tracce ascoltate"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Tracce che corrispondono al filtro"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Tipo"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Tipo"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
 msgstr "Sotto regole di moderazione"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Smetti di seguire"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Smettere di seguire questa libreria?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
-msgstr "Sfortunatamente i proprietari di questa istanza non hanno ancora avuto tempo di completare questa pagina."
+#: front/src/components/About.vue:17
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
+msgstr ""
+"Sfortunatamente i proprietari di questa istanza non hanno ancora avuto tempo "
+"di completare questa pagina."
+
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr "Errore sconosciuto"
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr "Errore sconosciuto"
 
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Musica illimitata"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Non silenziare"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Aggiorna"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Aggiorna applicazione"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Aggiorna avatar"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Aggiorna libreria"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "Aggiorna regole di moderazione"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Aggiorna lista di riproduzione"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Aggiorna impostazioni"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Aggiorna la tua password"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Carica"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Carica un nuovo avatar"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Carica contenuto audio"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Dati di caricamento"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Data di caricamento"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
-msgstr ""
-"Caricamento non riuscito, assicurati che il file non sia troppo grande e di "
-"non aver esaurito la tua quota"
+msgstr "Caricamento non riuscito, assicurati che il file non sia troppo grande e di non aver esaurito la tua quota"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
+msgstr "Il caricamento è ancora in corso e presto sarà processato dal server."
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr ""
-"Carica file musicali (mp3, ogg, flac, ecc.) dalla tua libreria personale "
-"direttamente dal tuo browser per goderne qui."
+msgstr "Carica file musicali (mp3, ogg, flac, ecc.) dalla tua libreria personale direttamente dal tuo browser per goderne qui."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Carica nuove tracce"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Quota di caricamento"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Caricamento scaduto, per favore riprova"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+"Il caricamento è stato saltato perchè uno simile è già disponibile in una "
+"delle tue librerie."
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr "Il caricamento è stato processato con successo dal server."
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Caricato"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Caricamento"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Caricamento…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Caricamenti"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Caricamenti"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
-msgstr "Caricati"
+msgstr "Caricamenti"
+
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+"Usa \"urn:ietf:wg:oauth:2.0:oob\" come URI di reindirizzamento se la tua "
+"applicazione non è servita sul web."
 
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Usa un'altra istanza"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Usa questo modulo per richiedere un reset della password. Ti invieremo una email all'indirizzo fornito con le istruzioni per resettare la tua password."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
-"Usa questa impostazione per abilitare/disabilitare temporaneamente la regola "
-"senza rimuoverla completamente."
+msgstr "Usa questa impostazione per abilitare/disabilitare temporaneamente la regola senza rimuoverla completamente."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Usati"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Utente"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Attività utente"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
-msgstr "Librerie utente"
+msgstr "Librerie dell'utente"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Radio dell'utente"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nome utente"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nome utente o email"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "utenti"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Utenti"
 
 #: front/src/components/Footer.vue:29
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "Utilizzando Funkwhale"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Versione (%{version})"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Vedi files"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr "Vedi nell'amministrazione di Django"
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Vedi su MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Visibilità"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Visibilità: tutti su questa istanza"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Visibilità: tutti, incluse altre istanze"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Visibilità: nessuno tranne me"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Visibilità"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr "Volume %{ number }"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Non possiamo aggiungere la traccia alla lista di riproduzione"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Non possiamo creare la lista di riproduzione"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Non possiamo creare il tuo account"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "Non possiamo caricare questa traccia"
+#: front/src/components/federation/FetchButton.vue:69
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Aspettando i risultati…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Non riusciamo a farti accedere"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Non possiamo salvare il tuo avatar"
+#: front/src/components/auth/ApplicationForm.vue:3
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Non è stato possibile salvare le tue modifiche"
 
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Non possiamo salvare le tue impostazioni"
-
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Noi non ti tracciamo o infastidiamo con pubblicità"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "Non abbiamo nessuna informazione sul copyright per questa traccia"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "Non abbiamo nessuna informazione sulla licenza di questa traccia"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "Ti consigliamo di utilizzare Picard per quello scopo."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Noi pensiamo che ascoltare musica debba essere semplice."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Ci dispiace, la pagina che hai richiesto non esiste:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Benvenuto"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Benvenuto su Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Perchè Funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "Altezza del widget"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "Larghezza del widget"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr "Scrivi"
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr "Sola-scrittura"
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr "Accesso in sola-scrittura ai dati utente"
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Si"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Si, disconnettimi!"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
-msgstr ""
-"Sarai in grado di condividere la tua libreria con altre persone, "
-"indipendentemente dalla sua visibilità."
+msgstr "Sarai in grado di condividere la tua libreria con altre persone, indipendentemente dalla sua visibilità."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Stai per caricare della musica nella tua libreria. Prima di procedere, per favore assicurati che:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+"Attualmente sei connesso a <a href=\"%{ url }\" target=\"_blank\">%{ "
+"hostname }&nbsp;<i class=\"external icon\"/></a>. Se continui, sarai "
+"disconnesso dalla tua istanza attuale ed i tuoi dati locali saranno "
+"eliminati."
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr "Stai attualmente nascondendo i contenuti di questo artista."
+
 #: front/src/components/auth/Logout.vue:7
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Sei attualmente connesso come %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+"Non stai caricando contenuti protetti da diritti d'autore in una libreria "
+"pubblica, altrimenti potresti infrangere la legge"
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr "Ora stai utilizzando l'istanza Funkwhale su %{ url }"
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Puoi seguire librerie di altri utenti per avere accesso a nuova musica. Le librerie pubbliche possono essere seguite immediatamente, mentre seguire le librerie private richiede l'approvazione del suo proprietario."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Puoi invitare amici e familiari sulla tua istanza così possono fruire della tua musica"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+"Puoi gestire ed aggiornare i tuoi filtri in qualsiasi momento dalle "
+"impostazioni del tuo account."
+
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Ora puoi usare il servizio senza limitazioni."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Puoi usare questa interfaccia per creare la tua radio personalizzata, che riprodurrà tracce in accordo con i tuoi criteri."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Puoi usarli per godere delle tue liste di riproduzione e musica anche quando non collegato, dal tuo cellulare o tablet, per esempio."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Non hai nessuna applicazione connessa al tuo account."
+
+#: front/src/components/auth/Settings.vue:261
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Non hai ancora nessuna applicazione configurata."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr "Non hai nessuna regola attiva per questo account."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr "Non hai nessuna regola attiva per questo dominio."
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
+msgstr ""
+"Non hai i permessi per modificare questo oggetto, ma puoi suggerire "
+"modifiche. Una volta inviati, i suggerimenti saranno revisionati prima "
+"dell'approvazione."
+
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Hai una radio in riproduzione"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr "Potresti avere un problema di connettività."
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Devi selezionare un'istanza per continuare"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Sarai disconnesso da questa sessione e dovrai accedere con una nuova"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr "Sarai reindirizzato su <strong>%{ url }</strong>"
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr "Ti sarà mostrato un codice da copiare-incollare nell'applicazione."
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Dovrai aggiornare la tua password sui tuoi dispositivi che utilizzano questa password."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+"Non vedrai tracce, album e attività utente collegate a questo artista in "
+"futuro:"
+
+#: front/src/components/auth/Signup.vue:13
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Il tuo account non può essere creato."
+
+#: front/src/components/auth/Settings.vue:215
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Le tue applicazioni"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr "La tua immagine di profilo non può essere salvata"
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr "La tua modifica è stata inviata correttamente."
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "I Tuoi Preferiti"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "La tua musica, il tuo modo di essere"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Le tue notifiche"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr "La tua password non può essere cambiata"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "La tua password è stata aggiornata con successo."
 
+#: front/src/components/auth/Settings.vue:14
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Le tue impostazioni non possono essere aggiornate"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "La tua password Subsonic sarà cambiata con una nuova e casuale, e sarai disconnesso dai dispositivi che utilizzano ancora la vecchia password Subsonic"
+
+#: front/src/edits.js:47
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Posizione"
+
+#: front/src/edits.js:54
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Diritti d'autore"
+
+#: front/src/components/library/AlbumBase.vue:183
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] ""
+"Album contenente %{ count } traccia, di <a class=\"internal\" href=\"%{ "
+"artistUrl }\">%{ artist }</a>"
+msgstr[1] ""
+"Album contenente %{ count } tracce, di <a class=\"internal\" href=\"%{ "
+"artistUrl }\">%{ artist }</a>"
+
+#: front/src/components/audio/PlayButton.vue:220
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } traccia è stata aggiunta alla tua coda"
+msgstr[1] "%{ count } tracce sono state aggiunte alla tua coda"
diff --git a/front/locales/nl/LC_MESSAGES/app.po b/front/locales/nl/LC_MESSAGES/app.po
index 76df472324b24f952da00248660ffcf2654ef307..4ea82bf516104808c853db63ebbf93ceba9d516c 100644
--- a/front/locales/nl/LC_MESSAGES/app.po
+++ b/front/locales/nl/LC_MESSAGES/app.po
@@ -8,8 +8,8 @@ msgstr ""
 "Project-Id-Version: front 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-10-05 20:10+0200\n"
-"PO-Revision-Date: 2019-01-18 11:50+0000\n"
-"Last-Translator: Vierkantor <vierkantor@vierkantor.com>\n"
+"PO-Revision-Date: 2019-04-08 08:01+0000\n"
+"Last-Translator: Koen <koen.glotzbach@gmail.com>\n"
 "Language-Team: none\n"
 "Language: nl\n"
 "MIME-Version: 1.0\n"
@@ -64,7 +64,7 @@ msgstr[1] "%{ count } nummers"
 
 #: front/src/views/content/libraries/Quota.vue:11
 msgid "%{ current } used on %{ max } allowed"
-msgstr "%{ current } in gebruik van %{ max } toegestaan"
+msgstr "%{ current } in gebruik; maximaal %{ max } toegestaan"
 
 #: front/src/components/common/Duration.vue:2
 msgid "%{ hours } h %{ minutes } min"
@@ -80,12 +80,12 @@ msgstr "%{ user } heeft een nummer als favoriet gemarkeerd"
 
 #: front/src/components/activity/Listen.vue:7
 msgid "%{ user } listened to a track"
-msgstr "%{ user } heeft een nummer geluisterd"
+msgstr "%{ user } heeft een nummer beluisterd"
 
 #: front/src/components/audio/artist/Card.vue:41
 msgid "1 album"
 msgid_plural "%{ count } albums"
-msgstr[0] "%{ count } album"
+msgstr[0] "1 album"
 msgstr[1] "%{ count } albums"
 
 #: front/src/components/favorites/List.vue:10
@@ -104,7 +104,7 @@ msgstr "Over Funkwhale"
 
 #: front/src/App.vue:34 src/components/About.vue:8 src/components/About.vue:55
 msgid "About this instance"
-msgstr "Over deze instantiëring"
+msgstr "Over deze instantie"
 
 #: front/src/views/content/libraries/Detail.vue:48
 msgid "Accept"
@@ -117,8 +117,8 @@ msgstr "Geaccepteerd"
 #: front/src/components/Home.vue:106
 msgid "Access your music from a clean interface that focus on what really matters"
 msgstr ""
-"Toegang tot je muziek met een nette interface die de nadruk legt op wat echt "
-"belangrijk is"
+"Toegang tot je muziek, met een nette gebruikersomgeving die de nadruk legt "
+"op wat écht belangrijk is"
 
 #: front/src/views/admin/users/UsersDetail.vue:54
 msgid "Account active"
@@ -130,11 +130,11 @@ msgstr "Accountinstellingen"
 
 #: front/src/components/manage/users/UsersTable.vue:39
 msgid "Account status"
-msgstr "Accounttoestand"
+msgstr "Accountstatus"
 
 #: front/src/views/auth/PasswordReset.vue:14
 msgid "Account's email"
-msgstr "E-mail van account"
+msgstr "E-mailadres van account"
 
 #: front/src/views/content/libraries/Detail.vue:29
 msgid "Action"
@@ -143,8 +143,8 @@ msgstr "Actie"
 #: front/src/components/common/ActionTable.vue:86
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
-msgstr[0] "Actie %{ action } was succesvol begonnen voor %{ count } element"
-msgstr[1] "Actie %{ action } was succesvol begonnen voor %{ count } elementen"
+msgstr[0] "Actie %{ action } is begonnen voor %{ count } element"
+msgstr[1] "Actie %{ action } is begonnen voor %{ count } elementen"
 
 #: front/src/components/common/ActionTable.vue:8
 #: front/src/components/library/radios/Builder.vue:64
@@ -169,7 +169,7 @@ msgstr "Filter toevoegen"
 
 #: front/src/components/library/radios/Builder.vue:40
 msgid "Add filters to customize your radio"
-msgstr "Voeg filters toe om jouw radio te personaliseren"
+msgstr "Voeg filters toe om je radio te personaliseren"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:21
@@ -191,7 +191,7 @@ msgstr "Nummer toevoegen"
 
 #: front/src/components/manage/users/UsersTable.vue:69
 msgid "Admin"
-msgstr "Administrator"
+msgstr "Beheerder"
 
 #: front/src/components/Sidebar.vue:82
 msgid "Administration"
@@ -213,7 +213,7 @@ msgstr[1] "Album met %{ count } nummers, van %{ artist }"
 
 #: front/src/components/library/Track.vue:20
 msgid "Album page"
-msgstr "Pagina van album"
+msgstr "Albumpagina"
 
 #: front/src/components/audio/Search.vue:19 src/components/instance/Stats.vue:48
 #: front/src/components/requests/Form.vue:9
@@ -231,12 +231,12 @@ msgstr "Alles"
 
 #: front/src/components/playlists/Editor.vue:13
 msgid "An error occured while saving your changes"
-msgstr "Een fout is opgetreden bij het opslaan van de veranderingen"
+msgstr "Er is een fout opgetreden tijdens het opslaan van de wijzigingen"
 
 #: front/src/components/auth/Login.vue:10
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr ""
-"Een onbekende fout is opgetreden. Mogelijk staat de server uit of is "
+"Er is een onbekende fout opgetreden: mogelijk staat de server uit of is "
 "onbereikbaar"
 
 #: front/src/components/auth/Logout.vue:5
@@ -253,11 +253,11 @@ msgstr "Artiest"
 
 #: front/src/components/requests/Form.vue:5 src/components/mixins/Translations.vue:24
 msgid "Artist name"
-msgstr "Naam artiest"
+msgstr "Artiestnaam"
 
 #: front/src/components/library/Album.vue:22 src/components/library/Track.vue:23
 msgid "Artist page"
-msgstr "Pagina van artiest"
+msgstr "Artiestpagina"
 
 #: front/src/components/audio/Search.vue:10 src/components/instance/Stats.vue:42
 #: front/src/components/library/Library.vue:7 src/components/library/Artists.vue:120
@@ -275,46 +275,46 @@ msgstr "Oplopend"
 
 #: front/src/views/auth/PasswordReset.vue:27
 msgid "Ask for a password reset"
-msgstr "Wachtwoordreset aanvragen"
+msgstr "Wachtwoordherstel aanvragen"
 
 #: front/src/components/playlists/PlaylistModal.vue:26
 msgid "Available playlists"
-msgstr "Beschikbare playlists"
+msgstr "Beschikbare afspeellijsten"
 
 #: front/src/components/auth/Settings.vue:34
 msgid "Avatar"
-msgstr "Avatar"
+msgstr "Gebruikersafbeelding"
 
 #: front/src/views/auth/EmailConfirm.vue:17 src/views/auth/PasswordReset.vue:24
 #: front/src/views/auth/PasswordResetConfirm.vue:18
 msgid "Back to login"
-msgstr "Terug naar inloggen"
+msgstr "Terug naar inlogpagina"
 
 #: front/src/components/library/Track.vue:80
 #: front/src/components/manage/library/FilesTable.vue:42
 #: front/src/components/mixins/Translations.vue:28
 msgid "Bitrate"
-msgstr "Bitrate"
+msgstr "Bitsnelheid"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
 msgid "Browse"
-msgstr "Doorzoeken"
+msgstr "Bladeren"
 
 #: front/src/components/Sidebar.vue:65
 msgid "Browse library"
-msgstr "Bibliotheek doorzoeken"
+msgstr "Verzameling doorbladeren"
 
 #: front/src/components/library/Artists.vue:4
 msgid "Browsing artists"
-msgstr "Artiesten doorzoeken"
+msgstr "Artiesten doorbladeren"
 
 #: front/src/views/playlists/List.vue:3
 msgid "Browsing playlists"
-msgstr "Afspeellijsten doorzoeken"
+msgstr "Afspeellijsten doorbladeren"
 
 #: front/src/components/library/Radios.vue:4
 msgid "Browsing radios"
-msgstr "Radio's doorzoeken"
+msgstr "Radio's doorbladeren"
 
 #: front/src/components/library/radios/Builder.vue:5
 msgid "Builder"
@@ -327,7 +327,7 @@ msgstr "Van %{ artist }"
 #: front/src/views/content/remote/Card.vue:103
 msgid "By unfollowing this library, you will loose access to its content."
 msgstr ""
-"Als je de bibliotheek niet meer volgt, verlies je toegang tot alle inhoud."
+"Als je deze verzameling ontvolgt, dan verlies je toegang tot alle inhoud."
 
 #: front/src/components/common/DangerousButton.vue:17
 #: front/src/components/library/radios/Filter.vue:53
@@ -341,7 +341,7 @@ msgstr "Mogelijkheden"
 
 #: front/src/components/auth/Settings.vue:76
 msgid "Cannot change your password"
-msgstr "Je wachtwoord kon niet aangepast worden"
+msgstr "Kan wachtwoord niet wijzigen"
 
 #: front/src/App.vue:65
 msgid "Change language"
@@ -349,42 +349,42 @@ msgstr "Taal kiezen"
 
 #: front/src/components/auth/Settings.vue:67
 msgid "Change my password"
-msgstr "Wachtwoord aanpassen"
+msgstr "Wachtwoord wijzigen"
 
 #: front/src/components/auth/Settings.vue:95
 msgid "Change password"
-msgstr "Wachtwoord aanpassen"
+msgstr "Wachtwoord wijzigen"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
 msgid "Change your password"
-msgstr "Wachtwoord aanpassen"
+msgstr "Wachtwoord wijzigen"
 
 #: front/src/components/auth/Settings.vue:96
 msgid "Change your password?"
-msgstr "Jouw wachtwoord aanpassen?"
+msgstr "Wil je je wachtwoord wijzigen?"
 
 #: front/src/components/playlists/Editor.vue:21
 msgid "Changes synced with server"
-msgstr "Wijzigingen opgeslagen op de server"
+msgstr "Wijzigingen opgeslagen op server"
 
 #: front/src/components/auth/Settings.vue:70
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr ""
-"Als je je wachtwoord aanpast, wordt ook het wachtwoord voor de Subsonic-API "
-"aangepast als je er een ingesteld had."
+"Als je je wachtwoord wijzigt, dan wordt ook het wachtwoord voor de Subsonic-"
+"API gewijzigd als je deze had ingesteld."
 
 #: front/src/components/auth/Settings.vue:98
 msgid "Changing your password will have the following consequences"
-msgstr "Het aanpassen van je wachtwoord heeft deze gevolgen"
+msgstr "Het aanpassen van je wachtwoord heeft gevolgen"
 
 #: front/src/App.vue:6
 msgid "Choose your instance"
-msgstr "Kies je instantiëring"
+msgstr "Kies je instantie"
 
 #: front/src/components/Home.vue:64
 msgid "Clean library"
-msgstr "Een nette bibliotheek"
+msgstr "Een nette verzameling"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
 msgid "Clear"
@@ -397,7 +397,7 @@ msgstr "Afspeellijst wissen"
 
 #: front/src/components/Home.vue:44
 msgid "Click once, listen for hours using built-in radios"
-msgstr "Met een druk op de knop urenlang muziek uit ingebouwde radio's"
+msgstr "Met één druk op de knop urenlang muziek uit ingebouwde radiostations"
 
 #: front/src/components/library/FileUpload.vue:76
 msgid "Click to select files to upload or drag and drop files or directories"
@@ -441,56 +441,56 @@ msgstr "Kopiëren"
 
 #: front/src/components/Home.vue:85
 msgid "Covers, lyrics, our goal is to have them all ;)"
-msgstr "Covers, songteksten, ons doel is om ze allemaal te hebben ;)"
+msgstr "Hoezen, songteksten - ons doel is om ze allemaal te hebben ;)"
 
 #: front/src/components/auth/Signup.vue:4
 msgid "Create a funkwhale account"
-msgstr "Maak een account voor funkwhale"
+msgstr "Creëer een Funkwhale-account"
 
 #: front/src/views/content/libraries/Home.vue:14
 msgid "Create a new library"
-msgstr "Nieuwe bibliotheek maken"
+msgstr "Creëer een nieuwe verzameling"
 
 #: front/src/components/playlists/Form.vue:2
 msgid "Create a new playlist"
-msgstr "Nieuwe afspeellijst maken"
+msgstr "Creëer een nieuwe afspeellijst"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
 msgid "Create an account"
-msgstr "Account aanmaken"
+msgstr "Creëer een account"
 
 #: front/src/components/requests/Card.vue:25
 msgid "Create import"
-msgstr "Importering aanmaken"
+msgstr "Importeren"
 
 #: front/src/views/content/libraries/Form.vue:26
 msgid "Create library"
-msgstr "Bibliotheek aanmaken"
+msgstr "Verzameling creëren"
 
 #: front/src/components/auth/Signup.vue:51
 msgid "Create my account"
-msgstr "Account aanmaken"
+msgstr "Account creëren"
 
 #: front/src/components/playlists/Form.vue:34
 msgid "Create playlist"
-msgstr "Afspeellijst aanmaken"
+msgstr "Afspeellijst creëren"
 
 #: front/src/components/library/Radios.vue:23
 msgid "Create your own radio"
-msgstr "Je eigen radio aanmaken"
+msgstr "Creëer je eigen radiostation"
 
 #: front/src/components/manage/users/InvitationsTable.vue:40
 #: front/src/components/mixins/Translations.vue:17
 msgid "Creation date"
-msgstr "Aanmaakdatum"
+msgstr "Gecreëerd op"
 
 #: front/src/components/auth/Settings.vue:54
 msgid "Current avatar"
-msgstr "Huidige avatar"
+msgstr "Huidige gebruikersafbeelding"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
 msgid "Current library"
-msgstr "Huidige bibliotheek"
+msgstr "Huidige verzameling"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
 msgid "Current track"
@@ -498,7 +498,7 @@ msgstr "Huidig nummer"
 
 #: front/src/views/content/libraries/Quota.vue:2
 msgid "Current usage"
-msgstr "Huidig gebruik"
+msgstr "Huidig verbruik"
 
 #: front/src/views/content/libraries/Detail.vue:27
 msgid "Date"
@@ -513,7 +513,7 @@ msgstr "Verwijderen"
 
 #: front/src/views/content/libraries/Form.vue:39
 msgid "Delete library"
-msgstr "Bibliotheek verwijderen"
+msgstr "Verzameling verwijderen"
 
 #: front/src/views/playlists/Detail.vue:38
 msgid "Delete playlist"
@@ -521,11 +521,11 @@ msgstr "Afspeellijst verwijderen"
 
 #: front/src/views/radios/Detail.vue:28
 msgid "Delete radio"
-msgstr "Radio verwijderen"
+msgstr "Radiostation verwijderen"
 
 #: front/src/views/content/libraries/Form.vue:31
 msgid "Delete this library?"
-msgstr "Deze bibliotheek verwijderen?"
+msgstr "Wil je deze verzameling verwijderen?"
 
 #: front/src/components/favorites/List.vue:34 src/components/library/Artists.vue:26
 #: front/src/components/library/Radios.vue:47
@@ -556,11 +556,11 @@ msgstr "Toegang uitschakelen"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:49
 msgid "Disable Subsonic access"
-msgstr "Toegang met Subsonic uitschakelen"
+msgstr "Subsonic-toegang uitschakelen"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:50
 msgid "Disable Subsonic API access?"
-msgstr "Toegang van de Subsonic-API uitzetten?"
+msgstr "Subsonic-API-toegang uitschakelen?"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:14
 msgid "Discover how to use Funkwhale from other apps"
@@ -568,23 +568,24 @@ msgstr "Ontdek hoe je Funkwhale met andere apps kunt gebruiken"
 
 #: front/src/components/library/radios/Builder.vue:30
 msgid "Display publicly"
-msgstr "Openbaar tonen"
+msgstr "Openbaren"
 
 #: front/src/components/playlists/Editor.vue:42
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
-msgstr "Wil je de afspeellijst \"%{ playlist }\" echt wissen?"
+msgstr "Weet je zeker dat je de afspeellijst \"%{ playlist }\" wilt wissen?"
 
 #: front/src/components/common/DangerousButton.vue:7
 msgid "Do you want to confirm this action?"
-msgstr "Actie bevestigen?"
+msgstr "Wil je de actie bevestigen?"
 
 #: front/src/views/playlists/Detail.vue:35
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
-msgstr "Wil je echt de afspeellijst \"%{ playlist }\" verwijderen?"
+msgstr ""
+"Weet je zeker dat je de afspeellijst \"%{ playlist }\" wilt verwijderen?"
 
 #: front/src/views/radios/Detail.vue:26
 msgid "Do you want to delete the radio \"%{ radio }\"?"
-msgstr "Wil je echt de radio \"%{ radio }\" verwijderen?"
+msgstr "Weet je zeker dat je het radiostation \"%{ radio }\" wilt verwijderen?"
 
 #: front/src/components/common/ActionTable.vue:29
 msgid "Do you want to launch %{ action } on %{ count } element?"
@@ -594,7 +595,7 @@ msgstr[1] "Wil je %{ action } toepassen op %{ count } elementen?"
 
 #: front/src/components/Sidebar.vue:104
 msgid "Do you want to restore your previous queue?"
-msgstr "Wil je de vorige wachtrij terugzetten?"
+msgstr "Wil je de vorige wachtrij herstellen?"
 
 #: front/src/App.vue:37
 msgid "Documentation"
@@ -606,14 +607,14 @@ msgstr "Downloaden"
 
 #: front/src/components/playlists/Editor.vue:49
 msgid "Drag and drop rows to reorder tracks in the playlist"
-msgstr "Om de afspeellijst te herordenen, kun je de regels verslepen"
+msgstr "Versleep de rijen om nummers op de afspeellijst te herordenen"
 
 #: front/src/components/audio/track/Table.vue:9 src/components/library/Track.vue:58
 #: front/src/components/manage/library/FilesTable.vue:43
 #: front/src/views/content/libraries/FilesTable.vue:56
 #: front/src/components/mixins/Translations.vue:29
 msgid "Duration"
-msgstr "Speelduur"
+msgstr "Duur"
 
 #: front/src/components/Home.vue:93
 msgid "Easy to use"
@@ -621,15 +622,15 @@ msgstr "Makkelijk te gebruiken"
 
 #: front/src/views/content/libraries/Detail.vue:9
 msgid "Edit"
-msgstr "Wijzigen"
+msgstr "Bewerken"
 
 #: front/src/components/About.vue:21
 msgid "Edit instance info"
-msgstr "Info van instantiëring wijzigen"
+msgstr "Instantie-informatie bewerken"
 
 #: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
 msgid "Edit..."
-msgstr "Wijzigen…"
+msgstr "Bewerken…"
 
 #: front/src/components/auth/Signup.vue:29
 #: front/src/components/manage/users/UsersTable.vue:38
@@ -646,7 +647,7 @@ msgstr "E-mailadres bevestigd"
 
 #: front/src/views/playlists/Detail.vue:29
 msgid "End edition"
-msgstr "Wijzigingen afronden"
+msgstr "Bewerken afronden"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:20
 #: front/src/views/content/libraries/Form.vue:4
@@ -659,48 +660,48 @@ msgstr "Fout tijdens scannen"
 
 #: front/src/components/common/ActionTable.vue:79
 msgid "Error while applying action"
-msgstr "Fout bij het toepassen van actie"
+msgstr "Fout tijdens toepassen van actie"
 
 #: front/src/views/auth/PasswordReset.vue:7
 msgid "Error while asking for a password reset"
-msgstr "Fout bij het aanvragen van wachtwoordvervanging"
+msgstr "Fout tijdens aanvragen van wachtwoordherstel"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:7
 msgid "Error while changing your password"
-msgstr "Fout bij het aanpassen van je wachtwoord"
+msgstr "Fout tijdens wijzigen van wachtwoord"
 
 #: front/src/views/auth/EmailConfirm.vue:7
 msgid "Error while confirming your email"
-msgstr "Fout bij het bevestigen van je e-mailadres"
+msgstr "Fout tijdens bevestigen van e-mailadres"
 
 #: front/src/components/manage/users/InvitationForm.vue:4
 msgid "Error while creating invitation"
-msgstr "Fout bij het aanmaken van de uitnodiging"
+msgstr "Fout tijdens creëren van uitnodiging"
 
 #: front/src/views/content/remote/ScanForm.vue:3
 msgid "Error while fetching remote library"
-msgstr "Fout bij het ophalen van de verre bibliotheek"
+msgstr "Fout tijdens ophalen van externe verzameling"
 
 #: front/src/components/admin/SettingsGroup.vue:5
 msgid "Error while saving settings"
-msgstr "Fout bij het opslaan van de instellingen"
+msgstr "Fout tijdens opslaan van instellingen"
 
 #: front/src/views/content/libraries/FilesTable.vue:16
 #: front/src/views/content/libraries/FilesTable.vue:237
 msgid "Errored"
-msgstr "Gefaald"
+msgstr "Mislukt"
 
 #: front/src/views/content/libraries/Quota.vue:75
 msgid "Errored files"
-msgstr "Gefaalde bestanden"
+msgstr "Mislukte bestanden"
 
 #: front/src/views/content/remote/Card.vue:58
 msgid "Errored tracks:"
-msgstr "Gefaalde nummers:"
+msgstr "Mislukte nummers:"
 
 #: front/src/components/library/radios/Builder.vue:61
 msgid "Exclude"
-msgstr "Weglaten"
+msgstr "Uitsluiten"
 
 #: front/src/components/discussion/Comment.vue:14
 msgid "Expand"
@@ -738,7 +739,7 @@ msgstr "Filternaam"
 #: front/src/views/content/libraries/FilesTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:241
 msgid "Finished"
-msgstr "Klaar"
+msgstr "Afgerond"
 
 #: front/src/views/content/remote/Card.vue:83
 msgid "Follow"
@@ -746,11 +747,11 @@ msgstr "Volgen"
 
 #: front/src/views/content/remote/Card.vue:88
 msgid "Follow pending approval"
-msgstr "Volgen na toestemming"
+msgstr "Wachten op toestemming"
 
 #: front/src/views/content/Home.vue:16
 msgid "Follow remote libraries"
-msgstr "Verre bibliotheken volgen"
+msgstr "Externe verzamelingen volgen"
 
 #: front/src/views/content/libraries/Detail.vue:7
 msgid "Followers"
@@ -758,22 +759,22 @@ msgstr "Volgers"
 
 #: front/src/views/content/remote/Card.vue:93
 msgid "Following"
-msgstr "Aan het volgen"
+msgstr "Volgend"
 
 #: front/src/components/activity/Like.vue:14 src/components/activity/Listen.vue:14
 msgid "from %{ album } by %{ artist }"
-msgstr "uit %{ album } door %{ artist }"
+msgstr "van %{ album } door %{ artist }"
 
 #: front/src/components/library/Track.vue:13
 msgid "From album %{ album } by %{ artist }"
-msgstr "Uit het album %{ album } van %{ artist }"
+msgstr "Van het album %{ album } van %{ artist }"
 
 #: front/src/App.vue:55
 msgid "Funkwhale is a free and open-source project run by volunteers. You can help us improve the platform by reporting bugs, suggesting features and share the project with your friends!"
 msgstr ""
-"Funkwhale is vrije, open-source software gemaakt door vrijwilligers. Je kan "
-"ons helpen dit platform te verbeteren door bugs te melden, features voor te "
-"stellen en het project met je vrienden te delen!"
+"Funkwhale is vrije, opensourcesoftware, gemaakt door vrijwilligers. Je kunt "
+"ons helpen dit platform te verbeteren door bugs te melden, functies voor te "
+"stellen en het project te delen met je vrienden!"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
@@ -787,16 +788,16 @@ msgstr "Funkwhale is zeer eenvoudig te gebruiken."
 #: front/src/components/Home.vue:39
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr ""
-"Funkwhale is ontworpen om het makkelijk te maken naar jouw favoriete muziek "
-"te luisteren, of nieuwe artiesten te ontdekken."
+"Funkwhale is ontworpen om het je makkelijk te maken je favoriete muziek te "
+"beluisteren of nieuwe artiesten te ontdekken."
 
 #: front/src/components/Home.vue:116
 msgid "Funkwhale is free and gives you control on your music."
-msgstr "Funkwhale is gratis en geeft jou het beheer over jouw muziek."
+msgstr "Funkwhale is gratis en geeft je het beheer over je muziek."
 
 #: front/src/components/Home.vue:66
 msgid "Funkwhale takes care of handling your music"
-msgstr "Funkwhale zorgt voor jouw muziek"
+msgstr "Funkwhale zorgt voor je muziek"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
 msgid "Get a new invitation"
@@ -804,13 +805,13 @@ msgstr "Nieuwe uitnodiging aanvragen"
 
 #: front/src/components/Home.vue:13
 msgid "Get me to the library"
-msgstr "Breng me naar de bibliotheek"
+msgstr "Breng me naar de verzameling"
 
 #: front/src/components/Home.vue:76
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr ""
-"Verkrijg hoogwaardige metadata over je muziek met behulp van <a href=\"%{ "
-"url }\" target=\"_blank\">MusicBrainz</a>"
+"Verkrijg hoogwaardige metagegevens over je muziek met behulp van <a href=\"%{"
+" url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
 msgid "Get started"
@@ -819,7 +820,7 @@ msgstr "Aan de slag"
 #: front/src/components/common/ActionTable.vue:21
 #: front/src/components/common/ActionTable.vue:27
 msgid "Go"
-msgstr "Doen!"
+msgstr "Ga"
 
 #: front/src/components/PageNotFound.vue:14
 msgid "Go to home page"
@@ -836,15 +837,15 @@ msgstr "Uren aan muziek"
 #: front/src/components/auth/SubsonicTokenForm.vue:11
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr ""
-"Om Funkwhale te benaderen van die apps is een los wachtwoord nodig. Dit kan "
-"je hieronder instellen."
+"Om Funkwhale te benaderen via die apps is een apart wachtwoord nodig. Dit "
+"kan je hieronder instellen."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr ""
-"Als het e-mailadres uit de vorige stap geldig is en hoort bij een gebruiker, "
-"dan zou je een e-mail moeten ontvangen met instructies voor het vervangen "
-"van je wachtwoord."
+"Als het e-mailadres uit de vorige stap geldig is en toebehoort aan een "
+"gebruiker, dan zou je een e-mail moeten ontvangen met instructies voor "
+"wachtwoordherstel."
 
 #: front/src/components/manage/library/FilesTable.vue:40
 msgid "Import date"
@@ -852,20 +853,20 @@ msgstr "Importdatum"
 
 #: front/src/components/Home.vue:71
 msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importeer muziek uit meerdere platformen zoals YouTube of SoundCloud"
+msgstr "Importeer muziek uit meerdere platformen, zoals YouTube of SoundCloud"
 
 #: front/src/components/library/FileUpload.vue:51
 msgid "Import reference"
-msgstr "Importeringsnummer"
+msgstr "Importnummer"
 
 #: front/src/views/content/libraries/FilesTable.vue:11
 #: front/src/views/content/libraries/FilesTable.vue:55
 msgid "Import status"
-msgstr "Importeringstoestand"
+msgstr "Importstatus"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
 msgid "In favorites"
-msgstr "Tussen favorieten"
+msgstr "In je favorieten"
 
 #: front/src/components/manage/users/UsersTable.vue:54
 msgid "Inactive"
@@ -879,7 +880,7 @@ msgstr[1] "Aan de wachtrij toevoegen (%{ count } nummers)"
 
 #: front/src/components/library/Radios.vue:9
 msgid "Instance radios"
-msgstr "Radio's van de instantiëring"
+msgstr "Radio's van de instantie"
 
 #: front/src/components/auth/Signup.vue:42
 #: front/src/components/manage/users/InvitationForm.vue:11
@@ -902,8 +903,8 @@ msgstr "Bugtracker"
 #: front/src/views/content/libraries/Home.vue:9
 msgid "It looks like you don't have any library yet, it's time to create one!"
 msgstr ""
-"Het lijkt erop dat je nog geen bibliotheek hebt. Het is tijd om er een aan "
-"te maken!"
+"Het lijkt erop dat je nog geen verzameling hebt; de hoogste tijd om er één "
+"te creëren!"
 
 #: front/src/components/Home.vue:50
 msgid "Keep a track of your favorite songs"
@@ -911,7 +912,7 @@ msgstr "Beheer je lievelingsmuziek"
 
 #: front/src/views/content/remote/Home.vue:14
 msgid "Known libraries"
-msgstr "Bekende bibliotheken"
+msgstr "Bekende verzamelingen"
 
 #: front/src/components/manage/users/UsersTable.vue:41
 #: front/src/views/admin/users/UsersDetail.vue:45
@@ -933,11 +934,11 @@ msgstr "Opstarten"
 
 #: front/src/views/content/remote/Card.vue:63
 msgid "Launch scan"
-msgstr "Begin scan"
+msgstr "Scannen"
 
 #: front/src/components/Home.vue:10
 msgid "Learn more about this instance"
-msgstr "Meer over deze instantiëring ontdekken"
+msgstr "Meer informatie over deze instantie"
 
 #: front/src/components/requests/Form.vue:10
 msgid "Leave this field empty if you're requesting the whole discography."
@@ -945,24 +946,24 @@ msgstr "Laat dit veld leeg als je de hele discografie wilt opvragen."
 
 #: front/src/views/content/Base.vue:5
 msgid "Libraries"
-msgstr "Bibliotheken"
+msgstr "Verzamelingen"
 
 #: front/src/views/content/libraries/Form.vue:2
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr ""
-"Bibliotheken helpen je met het organiseren en delen van je "
-"muziekverzamelingen. Je kan je eigen muziek uploaden naar Funkwhale en delen "
-"met je vrienden en familie."
+"Verzamelingen helpen je bij het organiseren en delen van je "
+"muziekverzamelingen. Je kunt je eigen muziek uploaden naar Funkwhale en "
+"delen met vrienden en familie."
 
 #: front/src/components/instance/Stats.vue:30
 #: front/src/components/manage/users/UsersTable.vue:177
 #: front/src/views/admin/users/UsersDetail.vue:181
 msgid "Library"
-msgstr "Bibliotheek"
+msgstr "Verzameling"
 
 #: front/src/views/admin/library/FilesList.vue:3
 msgid "Library files"
-msgstr "Bibliotheekbestanden"
+msgstr "Verzamelingsbestanden"
 
 #: front/src/App.vue:31
 msgid "Links"
@@ -970,36 +971,36 @@ msgstr "Links"
 
 #: front/src/views/content/libraries/Detail.vue:21
 msgid "Loading followers..."
-msgstr "Volgers aan het laden..."
+msgstr "Bezig met laden van volgers..."
 
 #: front/src/views/content/libraries/Home.vue:3
 msgid "Loading Libraries..."
-msgstr "Bibliotheken aan het laden…"
+msgstr "Bezig met laden van verzamelingen..."
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
 msgid "Loading library data..."
-msgstr "Bibliotheekdata aan het laden…"
+msgstr "Bezig met laden van verzamelingsgegevens..."
 
 #: front/src/views/Notifications.vue:4
 msgid "Loading notifications..."
-msgstr "Meldingen aan het laden…"
+msgstr "Bezig met laden van meldingen..."
 
 #: front/src/views/content/remote/Home.vue:3
 msgid "Loading remote libraries..."
-msgstr "Verre bibliotheken aan het laden…"
+msgstr "Bezig met laden van externe verzamelingen..."
 
 #: front/src/views/instance/Timeline.vue:4
 msgid "Loading timeline..."
-msgstr "Tijdlijn aan het laden…"
+msgstr "Bezig met laden van tijdlijn..."
 
 #: front/src/views/content/libraries/Quota.vue:4
 msgid "Loading usage data..."
-msgstr "Verbruiksdata aan het laden…"
+msgstr "Bezig met laden van verbruiksgegevens..."
 
 #: front/src/components/favorites/List.vue:5
 msgid "Loading your favorites..."
-msgstr "Jouw favorieten aan het laden…"
+msgstr "Bezig met laden van je favorieten..."
 
 #: front/src/components/auth/Login.vue:4
 msgid "Log in to your Funkwhale account"
@@ -1027,11 +1028,11 @@ msgstr "Afspeellijsten beheren"
 
 #: front/src/views/playlists/List.vue:8
 msgid "Manage your playlists"
-msgstr "Jouw afspeellijsten beheren"
+msgstr "Beheer je afspeellijsten"
 
 #: front/src/views/Notifications.vue:17
 msgid "Mark all as read"
-msgstr "Alles als gelezen markeren"
+msgstr "Alles markeren als gelezen"
 
 #: front/src/views/admin/users/UsersDetail.vue:94
 msgid "MB"
@@ -1047,7 +1048,7 @@ msgstr "Mijn account"
 
 #: front/src/views/content/libraries/Home.vue:6
 msgid "My libraries"
-msgstr "Mijn bibliotheken"
+msgstr "Mijn verzamelingen"
 
 #: front/src/components/audio/track/Row.vue:40 src/components/library/Track.vue:64
 #: front/src/components/library/Track.vue:75 src/components/library/Track.vue:86
@@ -1085,7 +1086,8 @@ msgstr "Nee"
 
 #: front/src/components/Home.vue:100
 msgid "No add-ons, no plugins : you only need a web library"
-msgstr "Geen uitbreidingen of plugins: je hebt alleen een webbibliotheek nodig"
+msgstr ""
+"Geen uitbreidingen of plug-ins: je hebt alleen een online verzameling nodig"
 
 #: front/src/components/library/Track.vue:113
 msgid "No lyrics available for this track."
@@ -1093,11 +1095,11 @@ msgstr "Geen songtekst beschikbaar voor dit nummer."
 
 #: front/src/components/federation/LibraryWidget.vue:6
 msgid "No matching library."
-msgstr "Geen passende bibliotheek gevonden."
+msgstr "Geen overeenkomende verzameling gevonden."
 
 #: front/src/views/content/libraries/Detail.vue:57
 msgid "Nobody is following this library"
-msgstr "Niemand volgt deze bibliotheek"
+msgstr "Niemand volgt deze verzameling"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
 msgid "Not used"
@@ -1144,7 +1146,7 @@ msgstr "Sorteervolgorde"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
 msgid "Owner"
-msgstr "Beheerder"
+msgstr "Eigenaar"
 
 #: front/src/components/PageNotFound.vue:7
 msgid "Page not found!"
@@ -1156,30 +1158,30 @@ msgstr "Wachtwoord"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
 msgid "Password updated successfully"
-msgstr "Wachtwoord succesvol aangepast"
+msgstr "Wachtwoord is gewijzigd"
 
 #: front/src/components/library/FileUpload.vue:105
 #: front/src/views/content/libraries/FilesTable.vue:14
 #: front/src/views/content/libraries/FilesTable.vue:233
 msgid "Pending"
-msgstr "Openstaand"
+msgstr "In behandeling"
 
 #: front/src/views/content/libraries/Detail.vue:37
 msgid "Pending approval"
-msgstr "Goedkeuring staat open"
+msgstr "Wachtend op goedkeuring"
 
 #: front/src/views/content/libraries/Quota.vue:22
 msgid "Pending files"
-msgstr "Openstaande bestanden"
+msgstr "In behandeling zijnde bestanden"
 
 #: front/src/components/requests/Form.vue:26
 msgid "Pending requests"
-msgstr "Openstaande verzoeken"
+msgstr "In behandeling zijnde verzoeken"
 
 #: front/src/components/manage/users/UsersTable.vue:42
 #: front/src/views/admin/users/UsersDetail.vue:68
 msgid "Permissions"
-msgstr "Toestemmingen"
+msgstr "Machtigingen"
 
 #: front/src/components/audio/PlayButton.vue:9 src/components/library/Track.vue:30
 msgid "Play"
@@ -1206,63 +1208,63 @@ msgstr "Nu afspelen"
 #: front/src/views/playlists/Detail.vue:12
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Afspeellijst met %{ count } nummer, door %{ username }"
+msgstr[1] "Afspeellijst met %{ count } nummers, door %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
 msgid "Playlist created"
-msgstr ""
+msgstr "Afspeellijst gecreëerd"
 
 #: front/src/components/playlists/Editor.vue:4
 msgid "Playlist editor"
-msgstr ""
+msgstr "Afspeellijst wijzigen"
 
 #: front/src/components/playlists/Form.vue:21
 msgid "Playlist name"
-msgstr ""
+msgstr "Afspeellijstnaam"
 
 #: front/src/components/playlists/Form.vue:6
 msgid "Playlist updated"
-msgstr ""
+msgstr "Afspeellijst gewijzigd"
 
 #: front/src/components/playlists/Form.vue:25
 msgid "Playlist visibility"
-msgstr ""
+msgstr "Zichtbaarheid van afspeellijst"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
 #: front/src/components/library/Library.vue:13 src/views/playlists/List.vue:104
 #: front/src/views/admin/Settings.vue:82
 msgid "Playlists"
-msgstr ""
+msgstr "Afspeellijsten"
 
 #: front/src/components/Home.vue:56
 msgid "Playlists? We got them"
-msgstr ""
+msgstr "Afspeellijsten? Die hebben we"
 
 #: front/src/components/auth/Settings.vue:79
 msgid "Please double-check your password is correct"
-msgstr ""
+msgstr "Controleer of je wachtwoord klopt"
 
 #: front/src/components/auth/Login.vue:9
 msgid "Please double-check your username/password couple is correct"
-msgstr ""
+msgstr "Controleer of je gebruikersnaam en wachtwoord kloppen"
 
 #: front/src/components/auth/Settings.vue:46
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
-msgstr ""
+msgstr "PNG, GIF of JPG. Maximaal 2MB. Wordt verkleind tot 400x400px."
 
 #: front/src/components/library/FileUpload.vue:58
 msgid "Proceed"
-msgstr ""
+msgstr "Doorgaan"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
 msgid "Proceed to login"
-msgstr ""
+msgstr "Doorgaan met inloggen"
 
 #: front/src/components/library/FileUpload.vue:17
 msgid "Processing"
-msgstr ""
+msgstr "Bezig met verwerken..."
 
 #: front/src/views/content/libraries/Quota.vue:36
 #: front/src/views/content/libraries/Quota.vue:39
@@ -1271,143 +1273,147 @@ msgstr ""
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
 msgid "Purge"
-msgstr ""
+msgstr "Leegmaken"
 
 #: front/src/views/content/libraries/Quota.vue:89
 msgid "Purge errored files?"
-msgstr ""
+msgstr "Foutieve bestanden verwijderen?"
 
 #: front/src/views/content/libraries/Quota.vue:37
 msgid "Purge pending files?"
-msgstr ""
+msgstr "In behandeling zijnde bestanden verwijderen?"
 
 #: front/src/views/content/libraries/Quota.vue:63
 msgid "Purge skipped files?"
-msgstr ""
+msgstr "Overgeslagen bestanden verwijderen?"
 
 #: front/src/components/Sidebar.vue:20
 msgid "Queue"
-msgstr ""
+msgstr "Wachtrij"
 
 #: front/src/components/library/radios/Builder.vue:15
 msgid "Radio created"
-msgstr ""
+msgstr "Radio gecreëerd"
 
 #: front/src/components/library/radios/Builder.vue:21
 msgid "Radio name"
-msgstr ""
+msgstr "Radionaam"
 
 #: front/src/components/library/radios/Builder.vue:12
 msgid "Radio updated"
-msgstr ""
+msgstr "Radio bijgewerkt"
 
 #: front/src/components/library/Library.vue:10 src/components/library/Radios.vue:142
 msgid "Radios"
-msgstr ""
+msgstr "Radio's"
 
 #: front/src/views/instance/Timeline.vue:7
 msgid "Recent activity on this instance"
-msgstr ""
+msgstr "Recente activiteit op deze instantie"
 
 #: front/src/components/library/Home.vue:24
 msgid "Recently added"
-msgstr ""
+msgstr "Recent toegevoegd"
 
 #: front/src/components/library/Home.vue:11
 msgid "Recently favorited"
-msgstr ""
+msgstr "Recent toegevoegd aan favorieten"
 
 #: front/src/components/library/Home.vue:6
 msgid "Recently listened"
-msgstr ""
+msgstr "Recent beluisterd"
 
 #: front/src/views/admin/users/UsersDetail.vue:103
 #: front/src/views/content/remote/Home.vue:15
 msgid "Refresh"
-msgstr ""
+msgstr "Verversen"
 
 #: front/src/components/auth/Profile.vue:12
 msgid "Registered since %{ date }"
-msgstr ""
+msgstr "Geregistreerd sinds %{ date }"
 
 #: front/src/components/auth/Signup.vue:9
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr ""
+"Registraties zijn gesloten op deze instantie. Je hebt een uitnodiging nodig "
+"om te registreren."
 
 #: front/src/components/manage/users/UsersTable.vue:71
 msgid "regular user"
-msgstr ""
+msgstr "standaard gebruiker"
 
 #: front/src/views/content/libraries/Detail.vue:51
 msgid "Reject"
-msgstr ""
+msgstr "Afkeuren"
 
 #: front/src/views/content/libraries/Detail.vue:43
 msgid "Rejected"
-msgstr ""
+msgstr "Afgekeurd"
 
 #: front/src/views/content/remote/Home.vue:6
 msgid "Remote libraries"
-msgstr ""
+msgstr "Externe verzamelingen"
 
 #: front/src/views/content/remote/Home.vue:7
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr ""
+"Externe verzamelingen worden beheerd door andere gebruikers op het netwerk. "
+"Je kunt ze gebruiken als ze openbaar zijn of als jou toegang is verleend."
 
 #: front/src/components/library/radios/Filter.vue:59
 msgid "Remove"
-msgstr ""
+msgstr "Verwijderen"
 
 #: front/src/components/auth/Settings.vue:58
 msgid "Remove avatar"
-msgstr ""
+msgstr "Gebruikersafbeelding verwijderen"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:34
 #: front/src/components/auth/SubsonicTokenForm.vue:37
 msgid "Request a new password"
-msgstr ""
+msgstr "Nieuw wachtwoord aanvragen"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:35
 msgid "Request a new Subsonic API password?"
-msgstr ""
+msgstr "Nieuw Subsonic-API-wachtwoord aanvragen?"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:43
 msgid "Request a password"
-msgstr ""
+msgstr "Wachtwoord aanvragen"
 
 #: front/src/components/requests/Form.vue:20
 msgid "Request submitted!"
-msgstr ""
+msgstr "Verzoek ingediend!"
 
 #: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
 msgid "Reset your password"
-msgstr ""
+msgstr "Wachtwoord opnieuw instellen"
 
 #: front/src/components/favorites/List.vue:38 src/components/library/Artists.vue:30
 #: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
 msgid "Results per page"
-msgstr ""
+msgstr "Aantal resultaten per pagina"
 
 #: front/src/components/admin/SettingsGroup.vue:63
 #: front/src/components/library/radios/Builder.vue:33
 msgid "Save"
-msgstr ""
+msgstr "Opslaan"
 
 #: front/src/views/content/remote/Card.vue:31
 msgid "Scan pending"
-msgstr ""
+msgstr "Nog te scannen"
 
 #: front/src/views/content/remote/Card.vue:43
 msgid "Scanned successfully"
-msgstr ""
+msgstr "Scannen afgerond"
 
 #: front/src/views/content/remote/Card.vue:47
 msgid "Scanned with errors"
-msgstr ""
+msgstr "Afgerond, maar met foutmeldingen"
 
 #: front/src/views/content/remote/Card.vue:35
 msgid "Scanning... (%{ progress }%)"
-msgstr ""
+msgstr "Bezig met scannen... (% {progress }%)"
 
 #: front/src/components/library/Artists.vue:10 src/components/library/Radios.vue:29
 #: front/src/components/manage/library/FilesTable.vue:5
@@ -1415,142 +1421,146 @@ msgstr ""
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5 src/views/playlists/List.vue:13
 msgid "Search"
-msgstr ""
+msgstr "Zoeken"
 
 #: front/src/views/content/remote/ScanForm.vue:9
 msgid "Search a remote library"
-msgstr ""
+msgstr "Zoeken naar externe verzameling"
 
 #: front/src/components/audio/Search.vue:2
 msgid "Search for some music"
-msgstr ""
+msgstr "Zoeken naar muziek"
 
 #: front/src/components/library/Track.vue:116
 msgid "Search on lyrics.wikia.com"
-msgstr ""
+msgstr "Zoeken op lyrics.wikia.com"
 
 #: front/src/components/library/Album.vue:33 src/components/library/Artist.vue:31
 #: front/src/components/library/Track.vue:40
 msgid "Search on Wikipedia"
-msgstr ""
+msgstr "Zoeken op Wikipedia"
 
 #: front/src/views/admin/Settings.vue:15
 msgid "Sections"
-msgstr ""
+msgstr "Secties"
 
 #: front/src/components/library/radios/Builder.vue:45
 msgid "Select a filter"
-msgstr ""
+msgstr "Filter kiezen"
 
 #: front/src/components/common/ActionTable.vue:64
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Selecteer %{ total } element"
+msgstr[1] "Selecteer alle %{ total } elementen"
 
 #: front/src/components/common/ActionTable.vue:73
 msgid "Select only current page"
-msgstr ""
+msgstr "Alleen deze pagina kiezen"
 
 #: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:88
 #: front/src/components/manage/users/UsersTable.vue:185
 #: front/src/views/admin/users/UsersDetail.vue:189
 msgid "Settings"
-msgstr ""
+msgstr "Instellingen"
 
 #: front/src/components/auth/Settings.vue:10
 msgid "Settings updated"
-msgstr ""
+msgstr "Instellingen bijgewerkt"
 
 #: front/src/components/admin/SettingsGroup.vue:11
 msgid "Settings updated successfully."
-msgstr ""
+msgstr "De instellingen zijn bijgewerkt."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
 msgid "Share link"
-msgstr ""
+msgstr "Link om te delen"
 
 #: front/src/views/content/libraries/Detail.vue:15
 msgid "Share this link with other users so they can request an access to your library."
 msgstr ""
+"Deel deze link met anderen zodat ze toegang tot je verzamelingen kunnen "
+"aanvragen."
 
 #: front/src/views/content/libraries/Detail.vue:14
 #: front/src/views/content/remote/Card.vue:73
 msgid "Sharing link"
-msgstr ""
+msgstr "Link om te delen"
 
 #: front/src/components/audio/album/Card.vue:40
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Nog %{ count } nummer tonen"
+msgstr[1] "Nog %{ count } nummers tonen"
 
 #: front/src/components/audio/artist/Card.vue:30
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Nog %{ count } album tonen"
+msgstr[1] "Nog %{ count } albums tonen"
 
 #: front/src/views/Notifications.vue:10
 msgid "Show read notifications"
-msgstr ""
+msgstr "Gelezen meldingen tonen"
 
 #: front/src/components/manage/library/FilesTable.vue:97
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
 #: front/src/views/content/libraries/FilesTable.vue:111
 msgid "Showing results %{ start }-%{ end } on %{ total }"
-msgstr ""
+msgstr "Resultaten - %{ start }-%{ end } van de %{ total }"
 
 #: front/src/components/manage/users/UsersTable.vue:40
 #: front/src/views/admin/users/UsersDetail.vue:37
 msgid "Sign-up"
-msgstr ""
+msgstr "Registreren"
 
 #: front/src/components/library/FileUpload.vue:84 src/components/library/Track.vue:69
 #: front/src/components/manage/library/FilesTable.vue:44
 #: front/src/views/content/libraries/FilesTable.vue:57
 #: front/src/components/mixins/Translations.vue:27
 msgid "Size"
-msgstr ""
+msgstr "Grootte"
 
 #: front/src/views/content/libraries/FilesTable.vue:15
 #: front/src/views/content/libraries/FilesTable.vue:229
 msgid "Skipped"
-msgstr ""
+msgstr "Overgeslagen"
 
 #: front/src/views/content/libraries/Quota.vue:49
 msgid "Skipped files"
-msgstr ""
+msgstr "Overgeslagen bestanden"
 
 #: front/src/components/requests/Form.vue:3
 msgid "Something's missing in the library? Let us know what you would like to listen!"
 msgstr ""
+"Ontbreekt er iets in de verzameling? Laat ons weten waar je naar wilt "
+"luisteren!"
 
 #: front/src/components/audio/Search.vue:25
 msgid "Sorry, we did not found any album matching your query"
-msgstr ""
+msgstr "Sorry, er is geen album dat overeenkomt met de zoekopdracht"
 
 #: front/src/components/audio/Search.vue:16
 msgid "Sorry, we did not found any artist matching your query"
-msgstr ""
+msgstr "Sorry, er is geen artiest die overeenkomt met de zoekopdracht"
 
 #: front/src/App.vue:40
 msgid "Source code"
-msgstr ""
+msgstr "Broncode"
 
 #: front/src/App.vue:39
 msgid "Source code (%{version})"
-msgstr ""
+msgstr "Broncode (%{ version })"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
 msgid "Staff member"
-msgstr ""
+msgstr "Staflid"
 
 #: front/src/components/radios/Button.vue:4
 msgid "Start"
-msgstr ""
+msgstr "Starten"
 
 #: front/src/components/library/FileUpload.vue:85
 #: front/src/components/manage/users/InvitationsTable.vue:17
@@ -1558,111 +1568,122 @@ msgstr ""
 #: front/src/components/manage/users/UsersTable.vue:43
 #: front/src/views/content/libraries/Detail.vue:28
 msgid "Status"
-msgstr ""
+msgstr "Status"
 
 #: front/src/components/radios/Button.vue:3
 msgid "Stop"
-msgstr ""
+msgstr "Stoppen"
 
 #: front/src/components/Sidebar.vue:150
 msgid "Stop radio"
-msgstr ""
+msgstr "Radio stoppen"
 
 #: front/src/App.vue:11 src/components/requests/Form.vue:17
 msgid "Submit"
-msgstr ""
+msgstr "Indienen"
 
 #: front/src/components/requests/Form.vue:22
 msgid "Submit another request"
-msgstr ""
+msgstr "Nóg een verzoek indienen"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
 msgid "Subsonic API password"
-msgstr ""
+msgstr "Wachtwoord voor Subsonic-API"
 
 #: front/src/App.vue:13
 msgid "Suggested choices"
-msgstr ""
+msgstr "Aanbevelingen"
 
 #: front/src/components/library/FileUpload.vue:3
 msgid "Summary"
-msgstr ""
+msgstr "Samenvatting"
 
 #: front/src/components/playlists/Editor.vue:9
 msgid "Syncing changes to server..."
-msgstr ""
+msgstr "Bezig met synchroniseren van wijzigingen naar server..."
 
 #: front/src/components/common/CopyInput.vue:3
 msgid "Text copied to clipboard!"
-msgstr ""
+msgstr "Tekst gekopieerd naar het klembord!"
 
 #: front/src/components/Home.vue:26
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr ""
+"Het zit zo: we waren fan van Grooveshark en wilden iets nóg beters bouwen."
 
 #: front/src/App.vue:58
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr ""
+"Het Funkwhale-logo is met liefde ontworpen en gemaakt door Francis Gading."
 
 #: front/src/views/content/libraries/Form.vue:34
 msgid "The library and all its tracks will be deleted. This action is irreversible."
 msgstr ""
+"De verzameling en alle bijbehorende nummers worden verwijderd. Dit kan niet "
+"ongedaan worden gemaakt."
 
 #: front/src/components/library/FileUpload.vue:39
 msgid "The music files you are uploading are tagged properly:"
-msgstr ""
+msgstr "De muziekbestanden die je uploadt hebben de juiste tags:"
 
 #: front/src/components/Home.vue:121
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr ""
+"Het platform is vrij en open source; je kunt het zorgeloos installeren en "
+"aanpassen"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:4
 msgid "The Subsonic API is not available on this Funkwhale instance."
-msgstr ""
+msgstr "De Subsonic-API is niet beschikbaar op deze instantie."
 
 #: front/src/components/library/FileUpload.vue:43
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
-msgstr ""
+msgstr "De geüploade bestanden zijn in de formaten OGG, FLAC of MP3"
 
 #: front/src/components/library/Album.vue:52
 msgid "This album is present in the following libraries:"
-msgstr ""
+msgstr "Dit album is beschikbaar in de volgende verzamelingen:"
 
 #: front/src/components/library/Artist.vue:63
 msgid "This artist is present in the following libraries:"
-msgstr ""
+msgstr "Deze artiest komt voor in de volgende verzamelingen:"
 
 #: front/src/views/content/Home.vue:9
 msgid "This instance offers up to %{quota} of storage space to every user."
-msgstr ""
+msgstr "Deze instantie biedt tot %{ quota } opslagruimte voor elke gebruiker."
 
 #: front/src/components/auth/Profile.vue:16
 msgid "This is you!"
-msgstr ""
+msgstr "Dit ben jij!"
 
 #: front/src/components/common/ActionTable.vue:38
 msgid "This may affect a lot of elements, please double check this is really what you want."
 msgstr ""
+"Dit kan gevolgen hebben voor veel elementen. Controleer of je dit écht wilt "
+"doen."
 
 #: front/src/components/library/FileUpload.vue:52
 msgid "This reference will be used to group imported files together."
-msgstr ""
+msgstr "Deze referentie wordt gebruikt om geïmporteerde bestanden te groeperen."
 
 #: front/src/components/library/Track.vue:125
 msgid "This track is present in the following libraries:"
-msgstr ""
+msgstr "Dit nummer komt voor in de volgende verzamelingen:"
 
 #: front/src/views/playlists/Detail.vue:37
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr ""
+"De afspeellijst wordt volledig verwijderd; dit kan niet ongedaan worden "
+"gemaakt."
 
 #: front/src/views/radios/Detail.vue:27
 msgid "This will completely delete this radio and cannot be undone."
 msgstr ""
+"De radio wordt volledig verwijderd; dit kan niet ongedaan worden gemaakt."
 
 #: front/src/components/auth/SubsonicTokenForm.vue:51
 msgid "This will completely disable access to the Subsonic API using from account."
-msgstr ""
+msgstr "De toegang tot de Subsonic-API vanaf dit account wordt uitgeschakeld."
 
 #: front/src/App.vue:162 src/components/About.vue:55 src/components/Home.vue:154
 #: front/src/components/PageNotFound.vue:33 src/components/Sidebar.vue:203
@@ -1799,160 +1820,176 @@ msgstr ""
 msgid "This will erase your local data and disconnect you, do you want to continue?"
 msgid_plural "%{ count } tracks were added to your queue"
 msgstr[0] ""
-msgstr[1] ""
+"Dit wist al je lokale gegevens en ontkoppelt je. Weet je zeker dat je wilt "
+"doorgaan?"
+msgstr[1] "Er zijn %{ count } nummers toegevoegd aan je wachtrij"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:36
 msgid "This will log you out from existing devices that use the current password."
-msgstr ""
+msgstr "Je wordt uitgelogd op elk apparaat met het huidige wachtwoord."
 
 #: front/src/components/playlists/Editor.vue:44
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr ""
+"Alle nummers worden verwijderd uit de afspeellijst; dit kan niet ongedaan "
+"worden gemaakt."
 
 #: front/src/views/content/libraries/Quota.vue:90
 msgid "This will remove tracks that were uploaded but failed to be process by the server. This will remove those files completely and you will regain the corresponding quota."
 msgstr ""
+"Alle nummers die niet konden worden verwerkt, worden verwijderd. De "
+"bestanden worden volledig verwijderd en je krijgt het bijbehorende quotum "
+"terug."
 
 #: front/src/views/content/libraries/Quota.vue:38
 msgid "This will remove tracks that were uploaded but not processed yet. This will remove those files completely and you will regain the corresponding quota."
 msgstr ""
+"Alle nummers die nog niet verwerkt zijn, worden verwijderd. De bestanden "
+"worden volledig verwijderd en je krijgt het bijbehorende quotum terug."
 
 #: front/src/views/content/libraries/Quota.vue:64
 msgid "This will remove tracks that were uploaded but skipped during import processes for various reasons. This will remove those files completely and you will regain the corresponding quota."
 msgstr ""
+"Alle nummers die bij het importeren zijn overgeslagen (om wat voor reden dan "
+"ook), worden verwijderd. De bestanden worden volledig verwijderd en je "
+"krijgt het bijbehorende quotum terug."
 
 #: front/src/components/audio/track/Table.vue:6
 #: front/src/components/manage/library/FilesTable.vue:37
 #: front/src/views/content/libraries/FilesTable.vue:51
 #: front/src/components/mixins/Translations.vue:26
 msgid "Title"
-msgstr ""
+msgstr "Titel"
 
 #: front/src/components/library/Track.vue:53
 msgid "Track information"
-msgstr ""
+msgstr "Nummerinformatie"
 
 #: front/src/components/library/radios/Filter.vue:44
 msgid "Track matching filter"
-msgstr ""
+msgstr "Kloppend nummer"
 
 #: front/src/components/instance/Stats.vue:54
 msgid "tracks"
-msgstr ""
+msgstr "nummers"
 
 #: front/src/components/library/Album.vue:43
 #: front/src/components/playlists/PlaylistModal.vue:33 src/views/content/Base.vue:8
 #: front/src/views/content/libraries/Detail.vue:8 src/views/playlists/Detail.vue:50
 #: front/src/views/radios/Detail.vue:34
 msgid "Tracks"
-msgstr ""
+msgstr "Nummers"
 
 #: front/src/components/library/Artist.vue:54
 msgid "Tracks by this artist"
-msgstr ""
+msgstr "Nummers van deze artiest"
 
 #: front/src/components/instance/Stats.vue:25
 msgid "Tracks favorited"
-msgstr ""
+msgstr "Nummers in favorieten"
 
 #: front/src/components/instance/Stats.vue:19
 msgid "tracks listened"
-msgstr ""
+msgstr "beluisterde nummers"
 
 #: front/src/components/library/Track.vue:91
 #: front/src/components/manage/library/FilesTable.vue:41
 msgid "Type"
-msgstr ""
+msgstr "Type"
 
 #: front/src/views/content/remote/Card.vue:100 src/views/content/remote/Card.vue:105
 msgid "Unfollow"
-msgstr ""
+msgstr "Ontvolgen"
 
 #: front/src/views/content/remote/Card.vue:101
 msgid "Unfollow this library?"
-msgstr ""
+msgstr "Wil je deze verzameling ontvolgen?"
 
 #: front/src/components/About.vue:15
 msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
 msgstr ""
+"Helaas is deze pagina nog niet ingevuld door de beheerders van deze "
+"instantie."
 
 #: front/src/components/Home.vue:37
 msgid "Unlimited music"
-msgstr ""
+msgstr "Ongelimiteerd luisteren naar muziek"
 
 #: front/src/components/auth/Settings.vue:50
 msgid "Update avatar"
-msgstr ""
+msgstr "Gebruikersafbeelding bijwerken"
 
 #: front/src/views/content/libraries/Form.vue:25
 msgid "Update library"
-msgstr ""
+msgstr "Verzameling bijwerken"
 
 #: front/src/components/playlists/Form.vue:33
 msgid "Update playlist"
-msgstr ""
+msgstr "Afspeellijst bijwerken"
 
 #: front/src/components/auth/Settings.vue:27
 msgid "Update settings"
-msgstr ""
+msgstr "Instellingen bijwerken"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
 msgid "Update your password"
-msgstr ""
+msgstr "Wachtwoord bijwerken"
 
 #: front/src/views/content/libraries/Card.vue:44
 #: front/src/components/manage/users/UsersTable.vue:173
 #: front/src/views/content/libraries/DetailArea.vue:24
 #: front/src/views/admin/users/UsersDetail.vue:177
 msgid "Upload"
-msgstr ""
+msgstr "Uploaden"
 
 #: front/src/components/auth/Settings.vue:45
 msgid "Upload a new avatar"
-msgstr ""
+msgstr "Nieuwe gebruikersafbeelding uploaden"
 
 #: front/src/views/content/Home.vue:6
 msgid "Upload audio content"
-msgstr ""
+msgstr "Audio uploaden"
 
 #: front/src/views/content/libraries/FilesTable.vue:54
 msgid "Upload date"
-msgstr ""
+msgstr "Uploaddatum"
 
 #: front/src/views/content/Home.vue:7
 msgid "Upload music files (mp3, ogg, flac, etc.) from your personal library directly from your browser to enjoy them here."
 msgstr ""
+"Upload je eigen muziekbestanden (MP3, FLAC, OGG) via je browser om er hier "
+"naar te luisteren."
 
 #: front/src/components/library/FileUpload.vue:31
 msgid "Upload new tracks"
-msgstr ""
+msgstr "Nieuwe nummers uploaden"
 
 #: front/src/views/admin/users/UsersDetail.vue:82
 msgid "Upload quota"
-msgstr ""
+msgstr "Uploadquotum"
 
 #: front/src/components/library/FileUpload.vue:99
 msgid "Uploaded"
-msgstr ""
+msgstr "Geüpload"
 
 #: front/src/components/library/FileUpload.vue:5
 msgid "Uploading"
-msgstr "Aan het uploaden"
+msgstr "Bezig met uploaden"
 
 #: front/src/components/library/FileUpload.vue:102
 msgid "Uploading..."
-msgstr "Aan het uploaden..."
+msgstr "Bezig met uploaden..."
 
 #: front/src/App.vue:44
 msgid "Use another instance"
-msgstr "Een andere instantiëring gebruiken"
+msgstr "Andere instantie gebruiken"
 
 #: front/src/views/auth/PasswordReset.vue:12
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr ""
 "Met dit formulier kun je een nieuw wachtwoord aanvragen. Je ontvangt van ons "
-"een e-mail op jouw aangegeven adres met de instructies om je wachtwoord te "
-"vervangen."
+"een e-mail op het door jou ingevoerde aangegeven adres met de instructies om "
+"je wachtwoord te herstellen."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
 msgid "Used"
@@ -1964,16 +2001,16 @@ msgstr "Gebruiker"
 
 #: front/src/components/instance/Stats.vue:5
 msgid "User activity"
-msgstr "Activiteit van gebruikers"
+msgstr "Gebruikersactiviteit"
 
 #: front/src/components/library/Album.vue:49 src/components/library/Artist.vue:60
 #: front/src/components/library/Track.vue:122
 msgid "User libraries"
-msgstr "Gebruikersbibliotheken"
+msgstr "Gebruikersverzamelingen"
 
 #: front/src/components/library/Radios.vue:20
 msgid "User radios"
-msgstr "Gebruikerradio's"
+msgstr "Gebruikersradio's"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
@@ -1999,14 +2036,14 @@ msgstr "Gebruikers"
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
 msgid "View files"
-msgstr "Bekijk bestanden"
+msgstr "Bestanden bekijken"
 
 #: front/src/components/library/Album.vue:37 src/components/library/Artist.vue:35
 #: front/src/components/library/Track.vue:44
 #: front/src/components/metadata/ReleaseCard.vue:53
 #: front/src/components/metadata/ArtistCard.vue:49
 msgid "View on MusicBrainz"
-msgstr "Bekijk in MusicBrainz"
+msgstr "Bekijken op MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
 msgid "Visibility"
@@ -2014,35 +2051,35 @@ msgstr "Zichtbaarheid"
 
 #: front/src/components/playlists/PlaylistModal.vue:20
 msgid "We cannot add the track to a playlist"
-msgstr "Dit nummer kan niet aan een afspeellijst toegevoegd worden"
+msgstr "Dit nummer kan niet aan een afspeellijst worden toegevoegd"
 
 #: front/src/components/playlists/Form.vue:14
 msgid "We cannot create the playlist"
-msgstr "De afspeellijst kan niet aangemaakt worden"
+msgstr "De afspeellijst kan niet worden gecreëerd"
 
 #: front/src/components/auth/Signup.vue:13
 msgid "We cannot create your account"
-msgstr "Jouw account kan niet aangemaakt worden"
+msgstr "Je account kan niet worden gecreëerd"
 
 #: front/src/components/auth/Login.vue:7
 msgid "We cannot log you in"
-msgstr "Fout bij het inloggen"
+msgstr "Er is een fout opgetreden tijdens het inloggen"
 
 #: front/src/components/auth/Settings.vue:38
 msgid "We cannot save your avatar"
-msgstr "Je avatar kan niet opgeslagen worden"
+msgstr "Je gebruikersafbeelding kan niet worden opgeslagen"
 
 #: front/src/components/auth/Settings.vue:14
 msgid "We cannot save your settings"
-msgstr "Je instellingen kunnen niet opgeslagen worden"
+msgstr "Je instellingen kunnen niet worden opgeslagen"
 
 #: front/src/components/Home.vue:127
 msgid "We do not track you or bother you with ads"
-msgstr "We volgen je niet en storen je niet met reclame"
+msgstr "We volgen je niet en vallen je niet lastig met reclame"
 
 #: front/src/views/Notifications.vue:26
 msgid "We don't have any notification to display!"
-msgstr "Geen melding om te tonen!"
+msgstr "Er zijn geen te tonen meldingen!"
 
 #: front/src/views/content/Home.vue:4
 msgid "We offer various way to grab new content and make it available here."
@@ -2058,486 +2095,517 @@ msgstr "Omdat het makkelijk moet zijn naar muziek te luisteren."
 
 #: front/src/components/PageNotFound.vue:10
 msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Helaas bestaat de opgevraagde pagina niet:"
+msgstr "Helaas, de opgevraagde pagina bestaat niet:"
 
 #: front/src/components/requests/Form.vue:21
 msgid "We've received your request, you'll get some groove soon ;)"
-msgstr ""
+msgstr "We hebben je verzoek ontvangen. Binnenkort kun je genieten ;)"
 
 #: front/src/components/Home.vue:5
 msgid "Welcome on Funkwhale"
-msgstr ""
+msgstr "Welkom op Funkwhale"
 
 #: front/src/components/Home.vue:24
 msgid "Why funkwhale?"
-msgstr ""
+msgstr "Waarom Funkwhale?"
 
 #: front/src/components/Sidebar.vue:115
 msgid "Yes"
-msgstr ""
+msgstr "Ja"
 
 #: front/src/components/auth/Logout.vue:8
 msgid "Yes, log me out!"
-msgstr ""
+msgstr "Ja, ik wil uitloggen!"
 
 #: front/src/components/library/FileUpload.vue:33
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr ""
+"Je staat op het punt muziek te uploaden. Controleer voordat je doorgaat:"
 
 #: front/src/components/auth/Logout.vue:7
 msgid "You are currently logged in as %{ username }"
-msgstr ""
+msgstr "Je bent ingelogd als %{ username }"
 
 #: front/src/views/content/Home.vue:17
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr ""
+"Je kunt andere verzamelingen volgen voor toegang tot nieuwe muziek. Openbare "
+"verzamelingen kun je meteen volgen, maar voor privéverzamelingen heb je "
+"toestemming nodig van de beheerder."
 
 #: front/src/components/Home.vue:133
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr ""
+"Je kunt vrienden en familie uitnodigen zodat ze kunnen genieten van je muziek"
 
 #: front/src/components/library/radios/Builder.vue:7
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr ""
+"Met dit hulpmiddel kun je je eigen radiostation opzetten. Dit station speelt "
+"nummers aan de hand van jouw wensen."
 
 #: front/src/components/auth/SubsonicTokenForm.vue:8
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr ""
+"Je kunt ze gebruiken om ook offline te genieten van je afspeellijst en "
+"muziek, bijvoorbeeld op je smartphone of tablet."
 
 #: front/src/components/Sidebar.vue:147
 msgid "You have a radio playing"
-msgstr ""
+msgstr "Er wordt een radiostation afgespeeld"
 
 #: front/src/App.vue:8
 msgid "You need to select an instance in order to continue"
-msgstr ""
+msgstr "Kies een instantie om door te gaan"
 
 #: front/src/views/content/libraries/Form.vue:19
 msgid "You will be able to share your library with other people, regardless of it's visibility."
 msgstr ""
+"Je kunt je verzameling delen met anderen, ongeacht hoe je de zichtbaarheid "
+"hebt ingesteld."
 
 #: front/src/components/auth/Settings.vue:100
 msgid "You will be logged out from this session and have to log in with the new one"
-msgstr ""
+msgstr "Je wordt uitgelogd uit deze sessie moet inloggen op de nieuwe"
 
 #: front/src/components/auth/Settings.vue:71
 msgid "You will have to update your password on your clients that use this password."
 msgstr ""
+"Je moet je wachtwoord bijwerken op je clients die ook dit wachtwoord "
+"gebruiken."
 
 #: front/src/views/auth/EmailConfirm.vue:24
 msgid "Your email address was confirmed, you can now use the service without limitations."
 msgstr ""
+"Je e-mailadres is bevestigd. Je kunt nu onbeperkt gebruikmaken van de dienst."
 
 #: front/src/components/Home.vue:114
 msgid "Your music, your way"
-msgstr ""
+msgstr "Jouw muziek op jouw manier"
 
 #: front/src/views/Notifications.vue:7
 msgid "Your notifications"
-msgstr ""
+msgstr "Je meldingen"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:29
 msgid "Your password has been updated successfully."
-msgstr ""
+msgstr "Je wachtwoord is bijgewerkt."
 
 #: front/src/components/auth/Settings.vue:101
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr ""
+"Je Subsonic-wachtwoord wordt gewijzigd in een nieuw willekeurig wachtwoord. "
+"Hierbij wordt je uitgelogd op apparaten die het oude Subsonic-wachtwoord "
+"gebruiken."
 
 #: front/src/components/mixins/Translations.vue:8
 msgid "Activity visibility"
-msgstr ""
+msgstr "Zichtbaarheid van activiteit"
 
 #: front/src/components/mixins/Translations.vue:9
 msgid "Determine the visibility level of your activity"
-msgstr ""
+msgstr "Bepaal de zichtbaarheid van je activiteit"
 
 #: front/src/components/mixins/Translations.vue:11
 #: front/src/components/playlists/Form.vue:81 src/views/content/libraries/Form.vue:72
 msgid "Nobody except me"
-msgstr ""
+msgstr "Niemand, behalve ik"
 
 #: front/src/components/mixins/Translations.vue:12
 #: front/src/components/playlists/Form.vue:85 src/views/content/libraries/Form.vue:73
 msgid "Everyone on this instance"
-msgstr ""
+msgstr "Iedereen op deze instantie"
 
 #: front/src/components/mixins/Translations.vue:18
 msgid "Accessed date"
-msgstr ""
+msgstr "Benaderd op"
 
 #: front/src/components/mixins/Translations.vue:19
 msgid "Modification date"
-msgstr ""
+msgstr "Bewerkt op"
 
 #: front/src/components/mixins/Translations.vue:20
 msgid "Imported date"
-msgstr ""
+msgstr "Geïmporteerd op"
 
 #: front/src/components/mixins/Translations.vue:22
 msgid "Track name"
-msgstr ""
+msgstr "Naam van nummer"
 
 #: front/src/components/mixins/Translations.vue:23
 msgid "Album name"
-msgstr ""
+msgstr "Albumnaam"
 
 #: front/src/components/mixins/Translations.vue:30
 msgid "Sign-up date"
-msgstr ""
+msgstr "Geregistreerd op"
 
 #: front/src/components/playlists/Editor.vue:163
 msgid "Copy tracks from current queue to playlist"
-msgstr ""
+msgstr "Nummers kopiëren van huidige wachtrij naar afspeellijst"
 
 #: front/src/components/playlists/PlaylistModal.vue:116
 msgid "Add to this playlist"
-msgstr ""
+msgstr "Toevoegen aan deze afspeellijst"
 
 #: front/src/components/playlists/Form.vue:74
 msgid "My awesome playlist"
-msgstr ""
+msgstr "Mijn geweldige afspeellijst"
 
 #: front/src/components/playlists/Form.vue:89
 msgid "Everyone"
-msgstr ""
+msgstr "Iedereen"
 
 #: front/src/components/auth/Signup.vue:95
 msgid "Sign Up"
-msgstr ""
+msgstr "Registreren"
 
 #: front/src/components/auth/Signup.vue:96
 msgid "Enter your invitation code (case insensitive)"
-msgstr ""
+msgstr "Voer je uitnodigingscode in (hoofdletterongevoelig)"
 
 #: front/src/components/auth/Signup.vue:97
 msgid "Enter your username"
-msgstr ""
+msgstr "Voer je gebruikersnaam in"
 
 #: front/src/components/auth/Signup.vue:98
 msgid "Enter your email"
-msgstr ""
+msgstr "Voer je e-mailadres in"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:95
 msgid "Password updated"
-msgstr ""
+msgstr "Wachtwoord bijgewerkt"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:111
 msgid "Access disabled"
-msgstr ""
+msgstr "Toegang uitgeschakeld"
 
 #: front/src/components/auth/Login.vue:77
 msgid "Enter your username or email"
-msgstr ""
+msgstr "Voer je gebruikersnaam of e-mailadres in"
 
 #: front/src/components/auth/Login.vue:78
 msgid "Log In"
-msgstr ""
+msgstr "Inloggen"
 
 #: front/src/components/auth/Profile.vue:47
 msgid "%{ username }'s profile"
-msgstr ""
+msgstr "%{ username }'s profiel"
 
 #: front/src/components/auth/Logout.vue:20
 msgid "Log Out"
-msgstr ""
+msgstr "Uitloggen"
 
 #: front/src/components/auth/Settings.vue:249
 msgid "Account Settings"
-msgstr ""
+msgstr "Accountinstellingen"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:19
 msgid "Remove from favorites"
-msgstr ""
+msgstr "Verwijderen uit favorieten"
 
 #: front/src/components/favorites/List.vue:110
 msgid "Your Favorites"
-msgstr ""
+msgstr "Je favorieten"
 
 #: front/src/components/library/Radios.vue:141
 msgid "Enter a radio name..."
-msgstr ""
+msgstr "Voer een naam in voor de radio..."
 
 #: front/src/components/library/radios/Builder.vue:233
 msgid "Radio Builder"
-msgstr ""
+msgstr "Radio opzetten"
 
 #: front/src/components/library/radios/Builder.vue:235
 msgid "My awesome radio"
-msgstr ""
+msgstr "Mijn geweldige radio"
 
 #: front/src/components/library/radios/Builder.vue:236
 msgid "My awesome description"
-msgstr ""
+msgstr "Mijn geweldige omschrijving"
 
 #: front/src/components/library/FileUpload.vue:238
 msgid "Upload refused, ensure the file is not too big and you have not reached your quota"
 msgstr ""
+"Upload geweigerd. Zorg ervoor dat het bestand niet te groot is en dat je je "
+"quotum nog niet hebt bereikt."
 
 #: front/src/components/library/FileUpload.vue:239
 msgid "Impossible to upload this file, ensure it is not too big"
-msgstr ""
+msgstr "Kan dit bestand niet uploaden; zorg ervoor dat het niet te groot is"
 
 #: front/src/components/library/FileUpload.vue:240
 msgid "A network error occured while uploading this file"
-msgstr ""
+msgstr "Er is een netwerkfout opgetreden tijdens het uploaden van dit bestand"
 
 #: front/src/components/library/FileUpload.vue:241
 msgid "Upload timeout, please try again"
-msgstr ""
+msgstr "Upload verlopen; probeer het opnieuw"
 
 #: front/src/components/library/Artists.vue:119
 msgid "Enter an artist name..."
-msgstr ""
+msgstr "Voer een artiestnaam in..."
 
 #: front/src/components/library/Track.vue:195 src/components/audio/SearchBar.vue:27
 #: front/src/components/metadata/Search.vue:138
 msgid "Track"
-msgstr ""
+msgstr "Nummer"
 
 #: front/src/components/library/Home.vue:65
 msgid "Home"
-msgstr ""
+msgstr "Startpagina"
 
 #: front/src/components/forms/PasswordInput.vue:25
 msgid "Show/hide password"
-msgstr ""
+msgstr "Wachtwoord tonen/verbergen"
 
 #: front/src/components/requests/Form.vue:73
 msgid "The Beatles, Mickael Jackson…"
-msgstr ""
+msgstr "The Beatles, Michael Jackson…"
 
 #: front/src/components/requests/Form.vue:74
 msgid "The White Album, Thriller…"
-msgstr ""
+msgstr "The White Album, Thriller…"
 
 #: front/src/components/requests/Form.vue:75
 msgid "Use this comment box to add details to your request if needed"
 msgstr ""
+"Gebruik, indien nodig, dit opmerkingsveld om iets extra's toe te voegen aan "
+"je verzoek"
 
 #: front/src/components/audio/PlayButton.vue:158
 msgid "%{ count } track was added to your queue"
 msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{ count } nummer toegevoegd aan je wachtrij"
+msgstr[1] "%{ count } nummers toegevoegd aan je wachtrij"
 
 #: front/src/components/audio/Search.vue:65
 msgid "Artist, album, track..."
-msgstr ""
+msgstr "Artiest, album, nummer..."
 
 #: front/src/components/audio/SearchBar.vue:20
 msgid "Search for artists, albums, tracks..."
-msgstr ""
+msgstr "Zoek naar artiesten, albums, nummers..."
 
 #: front/src/components/audio/Player.vue:216
 msgid "Queue shuffled!"
-msgstr ""
+msgstr "Wachtrij ingesteld op willekeurig!"
 
 #: front/src/components/audio/Player.vue:273
 msgid "Previous track"
-msgstr ""
+msgstr "Vorig nummer"
 
 #: front/src/components/audio/Player.vue:274
 msgid "Play track"
-msgstr ""
+msgstr "Nummer afspelen"
 
 #: front/src/components/audio/Player.vue:275
 msgid "Pause track"
-msgstr ""
+msgstr "Nummer pauzeren"
 
 #: front/src/components/audio/Player.vue:276
 msgid "Next track"
-msgstr ""
+msgstr "Volgend nummer"
 
 #: front/src/components/audio/Player.vue:277
 msgid "Unmute"
-msgstr ""
+msgstr "Ontdempen"
 
 #: front/src/components/audio/Player.vue:278
 msgid "Mute"
-msgstr ""
+msgstr "Dempen"
 
 #: front/src/components/audio/Player.vue:279
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr ""
+"Herhalen uitgeschakeld. Klik om over te schakelen naar één nummer-herhaling."
 
 #: front/src/components/audio/Player.vue:280
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr ""
+"Eén nummer wordt herhaald. Klik om over te schakelen naar wachtrijherhaling."
 
 #: front/src/components/audio/Player.vue:281
 msgid "Looping on whole queue. Click to disable looping."
-msgstr ""
+msgstr "Gehele wachtrij wordt herhaald. Klik om herhalen uit te schakelen."
 
 #: front/src/components/audio/Player.vue:282
 msgid "Shuffle your queue"
-msgstr ""
+msgstr "Willekeurig"
 
 #: front/src/components/audio/Player.vue:283
 msgid "Clear your queue"
-msgstr ""
+msgstr "Wachtrij wissen"
 
 #: front/src/components/Sidebar.vue:203
 msgid "Pending import requests"
-msgstr ""
+msgstr "In behandeling zijnde importverzoeken"
 
 #: front/src/components/Sidebar.vue:204
 msgid "Pending follow requests"
-msgstr ""
+msgstr "In behandeling zijnde volgverzoeken"
 
 #: front/src/components/metadata/Search.vue:114
 msgid "Enter your search query..."
-msgstr ""
+msgstr "Voer een zoekopdracht in..."
 
 #: front/src/components/manage/library/FilesTable.vue:176
 msgid "Search by title, artist, domain..."
-msgstr ""
+msgstr "Zoek op titel, artiest, domein..."
 
 #: front/src/components/manage/users/InvitationForm.vue:58
 msgid "Leave empty for a random code"
-msgstr ""
+msgstr "Laat leeg om een willekeurig code te krijgen"
 
 #: front/src/components/manage/users/InvitationsTable.vue:153
 msgid "Search by username, email, code..."
-msgstr ""
+msgstr "Zoek op gebruikersnaam, e-mailadres, code..."
 
 #: front/src/components/manage/users/UsersTable.vue:163
 msgid "Search by username, email, name..."
-msgstr ""
+msgstr "Zoek op naam, gebruikersnaam, e-mailadres..."
 
 #: front/src/components/manage/users/UsersTable.vue:181
 #: front/src/views/admin/users/UsersDetail.vue:185 src/views/admin/Settings.vue:83
 msgid "Federation"
-msgstr ""
+msgstr "Federatie"
 
 #: front/src/components/Home.vue:154
 msgid "Welcome"
-msgstr ""
+msgstr "Welkom"
 
 #: front/src/views/content/remote/ScanForm.vue:48
 msgid "Enter a library url"
-msgstr ""
+msgstr "Voer de url in van een verzameling"
 
 #: front/src/views/content/remote/Card.vue:165
 msgid "Scan launched"
-msgstr ""
+msgstr "Scan begonnen"
 
 #: front/src/views/content/remote/Card.vue:166
 msgid "Scan skipped (previous scan is too recent)"
-msgstr ""
+msgstr "Scan overgeslagen (vorige scan was zeer recent)"
 
 #: front/src/views/content/libraries/FilesTable.vue:226
 msgid "Search by title, artist, album..."
-msgstr ""
+msgstr "Zoek op titel, artiest, album..."
 
 #: front/src/views/content/libraries/FilesTable.vue:230
 msgid "Track was already present in one of your libraries"
-msgstr ""
+msgstr "Nummer is al aanwezig in één van je verzamelingen"
 
 #: front/src/views/content/libraries/FilesTable.vue:234
 msgid "Track is uploaded but not processed by the server yet"
-msgstr ""
+msgstr "Nummer is geüpload, maar nog niet verwerkt door de server"
 
 #: front/src/views/content/libraries/FilesTable.vue:238
 msgid "An error occured while processing this track, ensure the track is correctly tagged"
 msgstr ""
+"Er is een fout opgetreden tijdens het verwerken van dit nummer. Zorg ervoor "
+"dat het juist getagd is."
 
 #: front/src/views/content/libraries/FilesTable.vue:242
 msgid "Import went on successfully"
-msgstr ""
+msgstr "Import voltooid"
 
 #: front/src/views/content/libraries/FilesTable.vue:259
 msgid "Relaunch import"
-msgstr ""
+msgstr "Opnieuw importeren"
 
 #: front/src/views/content/libraries/Card.vue:58
 msgid "Visibility: nobody except me"
-msgstr ""
+msgstr "Zichtbaarheid: niemand, behalve ik"
 
 #: front/src/views/content/libraries/Card.vue:59
 msgid "Visibility: everyone on this instance"
-msgstr ""
+msgstr "Zichtbaarheid: iedereen op deze instantie"
 
 #: front/src/views/content/libraries/Card.vue:60
 msgid "Visibility: everyone, including other instances"
-msgstr ""
+msgstr "Zichtbaarheid: iedereen, inclusief personen op andere instanties"
 
 #: front/src/views/content/libraries/Card.vue:61
 msgid "Total size of the files in this library"
-msgstr ""
+msgstr "Totale grootte van de bestanden in deze verzameling"
 
 #: front/src/views/content/libraries/Form.vue:70
 msgid "My awesome library"
-msgstr ""
+msgstr "Mijn geweldige verzameling"
 
 #: front/src/views/content/libraries/Form.vue:71
 msgid "This library contains my personnal music, I hope you will like it!"
 msgstr ""
+"Deze verzameling bevat mijn persoonlijke muziek. Ik hoop dat je ervan zult "
+"genieten!"
 
 #: front/src/views/content/libraries/Form.vue:74
 msgid "Everyone, including other instances"
-msgstr ""
+msgstr "Iedereen, inclusief personen op andere instanties"
 
 #: front/src/views/content/libraries/Form.vue:106
 msgid "Library updated"
-msgstr ""
+msgstr "Verzameling bijgewerkt"
 
 #: front/src/views/content/libraries/Form.vue:109
 msgid "Library created"
-msgstr ""
+msgstr "Verzameling gecreëerd"
 
 #: front/src/views/content/Home.vue:35
 msgid "Add and manage content"
-msgstr ""
+msgstr "Inhoud toevoegen en beheren"
 
 #: front/src/views/radios/Detail.vue:80
 msgid "Radio"
-msgstr ""
+msgstr "Radio"
 
 #: front/src/views/instance/Timeline.vue:57
 msgid "Instance Timeline"
-msgstr ""
+msgstr "Instantietijdlijn"
 
 #: front/src/views/playlists/Detail.vue:90
 msgid "Playlist"
-msgstr ""
+msgstr "Afspeellijst"
 
 #: front/src/views/playlists/List.vue:105
 msgid "Enter an playlist name..."
-msgstr ""
+msgstr "Voer een naam in voor de afspeellijst..."
 
 #: front/src/views/admin/library/Base.vue:16
 msgid "Manage library"
-msgstr ""
+msgstr "Verzameling beheren"
 
 #: front/src/views/admin/users/UsersDetail.vue:169
 msgid "Determine if the user account is active or not. Inactive users cannot login or use the service."
 msgstr ""
+"Bepaal of het gebruikersaccount actief is of niet. Inactieve gebruikers "
+"kunnen niet inloggen of gebruikmaken van de dienst."
 
 #: front/src/views/admin/users/UsersDetail.vue:170
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr ""
+"Bepaald hoeveel een gebruiker kan uploaden. Laat leeg om de standaardwaarde "
+"te gebruiken van deze instantie."
 
 #: front/src/views/admin/users/Base.vue:20
 msgid "Manage users"
-msgstr ""
+msgstr "Gebruikers beheren"
 
 #: front/src/views/admin/Settings.vue:75
 msgid "Instance settings"
-msgstr ""
+msgstr "Instantie-instellingen"
 
 #: front/src/views/admin/Settings.vue:80
 msgid "Instance information"
-msgstr ""
+msgstr "Instantie-informatie"
 
 #: front/src/views/admin/Settings.vue:84
 msgid "Subsonic"
-msgstr ""
+msgstr "Subsonic"
 
 #: front/src/views/admin/Settings.vue:85
 msgid "Statistics"
-msgstr ""
+msgstr "Statistieken"
 
 #: front/src/views/admin/Settings.vue:86
 msgid "Error reporting"
-msgstr ""
+msgstr "Foutrapportage"
diff --git a/front/locales/oc/LC_MESSAGES/app.po b/front/locales/oc/LC_MESSAGES/app.po
index feffda9dcf57203744d5eff6aa4f986e7404e064..f622786573b4d4b22b982128a260f879e7b7e5b2 100644
--- a/front/locales/oc/LC_MESSAGES/app.po
+++ b/front/locales/oc/LC_MESSAGES/app.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
-"PO-Revision-Date: 2019-01-20 16:50+0000\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
+"PO-Revision-Date: 2019-05-07 09:29+0000\n"
 "Last-Translator: Quentí <quentin_antonin@hotmail.com>\n"
 "Language-Team: none\n"
 "Language: oc\n"
@@ -19,1871 +19,3116 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\", de %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } sus %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(voida)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "%{ app } vòl accedir a vòstre compte Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } sus %{ total } element seleccionat"
 msgstr[1] "%{ count } sus %{ total } elements seleccionats"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } pista"
 msgstr[1] "%{ count } pistas"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } pista dins %{ albumsCount } albums"
 msgstr[1] "%{ count } pistas dins %{ albumsCount } albums"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } pista correspond als filtres seleccionats"
 msgstr[1] "%{ count } pistas correspondon als filtres seleccionats"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "%{ count } pista ajustada a la fila"
-msgstr[1] "%{ count } pistas ajustadas a la fila"
-
 #: front/src/components/playlists/Card.vue:18
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} pista"
 msgstr[1] "%{ count} pistas"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ count } utilizat sus %{ total } autorizat"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } h %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
-msgstr ""
-"%{ username } acceptèt vòstra demanda de seguiment de la bibliotèca « %{ "
-"library } »"
+msgstr "%{ username } acceptèt vòstra demanda de seguiment de la bibliotèca « %{ library } »"
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr "%{ username } seguís vòstra bibliotèca « %{ library } »"
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } vòl seguir vòstra bibliotèca « %{ library } »"
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Perfil de %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
-msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">Tocant "
-"%{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
+msgstr "<strong>%{ track }</strong> es ja dins <strong>%{ playlist }</strong>."
 
 #: front/src/components/audio/artist/Card.vue:41
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 album"
 msgstr[1] "%{ count } albums"
 
 #: front/src/components/favorites/List.vue:10
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 favorit"
 msgstr[1] "%{ count } favorits"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Bibliotèca de qualitat"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Una error de ret s’es producha en enviar aqueste fichièr"
 
+#: front/src/components/library/EditForm.vue:145
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Una descripcion pichona per explicar vòstres cambiaments."
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "A prepaus de %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "A prepaus de %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "A prepaus de Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Pagina « a prepaus »"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "A prepaus d’aquesta instància"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Acceptar"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Acceptat"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Accès desactivat"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
-msgstr "Accedissètz a vòstra musica d’una interfàcia afinada estant, adaptada a çò que compta vertadièrament"
-
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr "Accès als fichièrs àudio, bibliotècas, artistas, albums e pistas"
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Accès als filtre de contengut"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Accès a las modificacions"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr "Accès als corrièls, nom d’utilizaire e informacions del perfil"
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Accès als favorits"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr "Accès al seguiment"
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr "Accès a l’istoric d’escota"
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Accès a las notificacions"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Accès a las listas de lectura"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Accès a las ràdios"
+
+#: front/src/components/Home.vue:101
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr ""
+"Accedissètz a vòstra musica d’una interfàcia afinada estant, adaptada a çò "
+"que compta vertadièrament"
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
 msgstr "Data d’accès"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Compte"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Compte"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Donadas del compte"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Paramètres del compte"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Paramètres del compte"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Estat del compte"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Adreça electronica del compte"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Comptes"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Accion"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "L’action %{ action } es estada lançada corrèctament sus %{ count } element"
 msgstr[1] "L’action %{ action } es estada lançada corrèctament sus %{ count } elements"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Accions"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Actiu"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Activitat"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Visibilitat de l’activitat"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Ajustar"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Ajustar un domeni"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Ajustar una règla de moderacion"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Ajustar una nòva règla de moderacion"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Ajustar e gerir lo contengut"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr "Ajustar pr’aquò"
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Ajustar de contengut"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
-msgstr "Ajustar de filtres"
+msgstr "Ajustar lo filtre"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
-msgstr "Ajustar de filtre per dire de personalizar vòstra ràdio"
+msgstr "Ajustar de filtres per dire de personalizar vòstra ràdio"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Ajustar a la lista actuala"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Ajustar als favorits"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Ajustar a la lista de lectura…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Ajustar a la lista"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Ajustar a aquesta lista de lectura"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Ajustar una pista"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Admin"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administracion"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Album"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Album contenent %{ count } pista, de %{ artist }"
-msgstr[1] "Album contenent %{ count } pistas, de %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Album"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
+#: front/src/views/admin/library/TrackDetail.vue:128
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Artista d’aqueste album"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
+msgstr "Donadas de l’album"
+
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Album name"
 msgstr "Nom de l’album"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Pagina de l’album"
-
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Albums"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Albums d’aqueste artista"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Tot"
 
+#: front/src/components/common/ActionTable.vue:59
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "%{ count } sus %{ total } element seleccionat"
+msgstr[1] "%{ count } sus %{ total } elements seleccionats"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr "Autorizar l’aplicacion"
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+"Una error s’es producha pendent lo processús de mandadís. Trobaretz mai d’"
+"informacion çai-jos."
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "Una error s’es producha en enregistrar vòstras modificacions"
 
+#: front/src/components/federation/FetchButton.vue:21
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Una error s’es producha en actualizar las donadas :"
+
+#: front/src/components/federation/FetchButton.vue:41
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Una error HTTP s’es producha en contactar lo servidor alonhat"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Una error desconeguda encontrada, aquò pòt significar que lo servidor es fòra servici o pòt pas èsser atengut"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr "Una error desconeguda s’es producha"
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Aplicacion"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr "Detalhs de l’aplicacion"
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr "ID de l’aplicacion"
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+"L’ID e lo secrèt de l’aplicacion son de donadas vertadièrament sensiblas e "
+"devon èsser consideradas coma de senhals. Partegetz-las pas amb degun."
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr "Secret de l’aplicacion"
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "Validar"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Validat"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr "Validada e aplicada"
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Volètz vertadièrament vos desconnectar ?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artista"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artista"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
+msgstr "Donadas de l’artista"
+
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Artist name"
 msgstr "Nom de l’artista"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Pagina de l’artista"
-
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artista, album, pista…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artistas"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artistas"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "Ascendent"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Demandar un nòu senhal"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Contengut àudio"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Acorchis del lector àudio"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr "Autorizar %{ app }"
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr "Autorizar una tèrça aplicacion"
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr "Aplicacions autorizadas"
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Listas de lectura disponiblas"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Tornar a la pagina de connexion"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Tornar als paramètres"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Debit"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "O blocar tot"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"O blocar tot d’aqueste compte estant. Empacharà totas interaccion amb l’"
-"entitat e purgarà lo contengut ligat (pistas, bibliotèca, seguiments, etc.)"
+msgstr "O blocar tot d’aqueste compte estant. Empacharà totas interaccion amb l’entitat e purgarà lo contengut ligat (pistas, bibliotèca, seguiments, etc.)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Percórrer"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Percórrer la bibliotèca"
 
+#: front/src/components/library/Albums.vue:4
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Percórrer los albums"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Percórrer los artistas"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Percórrer las listas de lectura"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Percórrer las ràdios"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Editor"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "De %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
-msgstr ""
-"En quitar de seguir aquesta bibliotèca, perdretz l’accès a son contengut."
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+msgstr "En quitar de seguir aquesta bibliotèca, perdretz l’accès a son contengut."
+
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr "Talha del cache"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Anullar"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Pistas candidatas"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Lo senhal pòt pas se cambiar"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "Mandadís del fichièr impossible, asseguratz-vos qu’es pas tròp pesuc"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Cambiar la lenga"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Cambiar lo senhal"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Cambiar lo senhal"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Cambiar lo senhal"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Cambiar lo senhal ?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Cambiament sincronizat amb lo servidor"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "L’actualizacion de vòstra senhal cambiarà tanben lo de l’API Subsonic se n’avètz un."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
-msgstr "Lo cambiament de senhal a las consequéncias seguentas"
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
+msgstr "Lo cambiament de senhal a las consequéncias seguentas :"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Sala de discutida"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+"Causir l’autorizacion «Lectura» o «Escritura» sul parent implica l’accès a "
+"totes los jos elements correspondents."
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Causissètz vòstra instància"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Bibliotèca de qualitat"
+#: front/src/components/library/EditForm.vue:75
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Escafar"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Escafar"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Escafar la lista de lectura"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Voidar la fila"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Amb un clic, escotatz d’oras de musica a la ràdio"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+"Clicar per mostrar mai d’informacion tocant lo processús d’import d’aqueste "
+"mandadís"
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Clicatz per causir los fichièrs d’enviar o lisatz los fichièrs o repertòris"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "Tampar"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "Tampar"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr "Tampar e tornar cargar la pagina"
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Còdi"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Plegar"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Configuracion"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Confirmar"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Confirmar vòstra adreça electronica"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Còdi de confirmacion"
 
-#: front/src/components/common/ActionTable.vue:7
-msgid "Content have been updated, click refresh to see up-to-date content"
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr "Filtre de contengut corrèctament ajustat"
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Filtres de contengut"
+
+#: front/src/components/auth/Settings.vue:116
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Filtres de contengut"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
 msgstr ""
-"Lo contengut es estat actualizat, clicar per tornar cargar e veire lo "
-"contengut a jorn"
+"Los filtres de contengut vos ajudan a amagar los contenguts que volètz pas "
+"veire sus aqueste servici."
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "Lo contengut es estat actualizat, clicar per tornar cargar e veire lo contengut a jorn"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Contribuir"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Copiar"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
 msgstr "Copiar las pistas de la fila a la lista de lectura"
 
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr "Copiatz-pegatz lo còdi seguent dins l’aplicacion :"
+
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr "Copiatz / Pegatz aqueste còdi al vòstre site HTML"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Copyright"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Confirmacion vòstra adreça electronica impossibla"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Error en recuperar la bibliotèca alonhada"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-"Una error s’es producha en tractar aquesta pista, asseguratz-vos qu’es "
-"corrèctament etiquetada"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Jaqueta d’albums, paraulas, nòstra tòca es d’o aver tot ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Crear"
 
 #: front/src/components/auth/Signup.vue:4
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Crear un compte funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Crear una nòva aplicacion"
+
+#: front/src/components/auth/Settings.vue:220
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Crear una nòva aplicacion"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Crear una nòva bibliotèca"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Crear una nòva lista de lectura"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Crear un compte"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Crear una aplicacion"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Crear una bibliotèca"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Crear mon compte"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr "Creatz-ne un per integrar Funkwhale amb de tèrças aplicacions."
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Crear la lista de lectura"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Crear vòstra pròpria ràdio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Data de creacion"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Avatar actual"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Bibliotèca actuala"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Pista actuala"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Utilizacion actuala"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+"Las donadas tornadas pel servidor alonhat an d’atributs mancants o invalids"
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+"Las donadas son estadas actualizadas corrèctament del servidors alonhat "
+"estant."
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Data"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Informacions de debug"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Reduire lo volum"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Suprimir"
 
+#: front/src/components/auth/Settings.vue:254
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Suprimir l’aplicacion"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr "Suprimir l’aplicacion « %{ application } » ?"
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Suprimir la bibliotèca"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Suprimir la règla de moderacion"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Suprimir la lista de lectura"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Suprimir la ràdio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Suprimir aqueste album ?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Suprimir aqueste artista ?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Suprimir aquesta bibliotèca ?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Suprimir aquesta règla de moderacion ?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Suprimir aquesta règla de moderacion ?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Suprimir aqueste mandadís ?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Descendent"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Descripcion"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Detalhs"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Descripcion"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Detalhs"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Definissètz la quantitat de contengut que l’utilizaire pòt enviar. Daissatz void per emplegar las valors per defaut de l’instància."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Determinatz lo nivèl de visibilitat de vòstra activitat"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Desactivar l’accès"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Desactivar l’accès via Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Desactivar l’accès a l’API Subsonic ?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Desactivat"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr "Numèro del disc"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Aprenètz a utilizar Funkwhale amb d’autras aplicacions"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Nom public"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Mostrar publicament"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Telecargar pas cap de mèdia (àudio, album, tampa, avatar de compte…) d’"
-"aqueste compte o domeni. Purgarà tanben lo contengut existent."
+msgstr "Telecargar pas cap de mèdia (àudio, album, tampa, avatar de compte…) d’aqueste compte o domeni. Purgarà tanben lo contengut existent."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Volètz voidar la lista de lectura « %{ playlist } »  ?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Volètz confirmar aquesta accion ?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Volètz suprimir la lista de lectura « %{ playlist } »  ?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Volètz suprimir la ràdio « %{ playlist } »  ?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Volètz rescondre lo contengut de l’artista « %{ name } »  ?"
+
+#: front/src/components/common/ActionTable.vue:37
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
-msgstr[0] "Volètz lançar l’accion « %{ action } » sus %{ count } element ?"
-msgstr[1] "Volètz lançar l’accion « %{ action } » sus %{ count } elements ?"
+msgstr[0] "Volètz lançar l’accion « %{ action } » sus %{ count } element ?"
+msgstr[1] "Volètz lançar l’accion « %{ action } » sus %{ count } elements ?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Volètz restablir vòstra fila precedenta ?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Documentacion"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Domenu"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Domenis"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Telecargar"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Lisatz las linhas per triar las pistas de la lista de lectura"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Durada"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Corrièl confirmat"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Simple d’utilizar"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Modificar"
+
+#: front/src/components/auth/Settings.vue:246
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Modificar"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Modificar l’aplicacion"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Editrar las informacions d’aquesta instància"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Modificar…"
-
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Actualizar las règlas de moderacion"
+
+#: front/src/components/library/AlbumEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Modificar aqueste album"
+
+#: front/src/components/library/ArtistEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Modificar aqueste artista"
+
+#: front/src/components/library/TrackEdit.vue:4
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Modificar aquesta pista"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Modificacions"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Modificacions"
+
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Corrièl"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Adreça electronica"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Integrar"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "Còdi d’integracion"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr "Integrar aqueste album a un site web"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Integrar aquesta pista a vòstre site web"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "Integrar aquesta pista a un site web"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr "Seguiments de bibliotècas enviats"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr "Messatge emés"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "Activat"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Acabar l’edicion"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Picatz l’URL d’una bibliotèca"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Escrivètz un nom de ràdio…"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr "Picatz lo títol de l’album…"
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Escrivètz un nom d’artista…"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Escrivètz un nom de lista de lectura…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Picatz l’adreça de corrièl ligada a vòstre compte"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Escrivètz vòstre adreça electronica"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Escrivètz vòstre còdi d’invitacion (pas sensible a la cassa)"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Escrivètz vòstra recèrca…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Escrivètz vòstre nom d’utilizaire"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Escrivètz vòstre nom d’utilizaire o corrièl"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Error"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Detalhs de l’error"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Rapòrt d’error"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Tip d’error"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Error en tractar l’accion"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Error en demandar un novèl senhal"
 
+#: front/src/components/auth/Authorize.vue:6
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Error en autorizar l’aplicacion"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Error en cambiar lo senhal"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Error en crear lo domeni"
 
+#: front/src/components/moderation/FilterModal.vue:13
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Error en crear lo filtre"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Error en crear l’invitacion"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Error en crear la règla"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Error en recuperar las donadas de l’aplicacion"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Error en recuperar las informacions del nos"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Error en enregistrar los paramètres"
+
+#: front/src/components/federation/FetchButton.vue:73
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Error en enregistrar los paramètres"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Error en enviar la modificacion"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Perturbat"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Fichièrs amb errors"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Tot lo monde"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Lo monde d’aquesta instància"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Tot lo monde, per totas las instàncias"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Exclure"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Data d’expiracion"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Expirada"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Expirada/utilizada"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
+msgstr "Explicatz perque aplicatz aquesta politica. Segon la configuracion de l’instància, aquò vos ajudarà a vos rapelar perque avètz agit sus aqueste compte o domeni, e aquò pòt èsser mostrat publicament per ajudar als utilizaires a comprendre qualas règlas de moderacion son en plaça."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "Fracàs"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Pistas en error :"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Pistas en favorit"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Favorits"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Favorits"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federacion"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "ID Federacion"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr "Camp"
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nom del fichièr"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Fichièrs"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Nom del filtre"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Acabat"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr "Primièra aparicion"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Data de primièra aparicion"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Seguir"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Seguir de bibliotècas alonhadas"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Abonament en espèra de validacion"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Seguidors"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Seguidors"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Abonat"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "De l’album %{ album } per %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Seguir"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr "De l’album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> per <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+
+#: front/src/components/auth/Authorize.vue:28
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Accès complèt"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale es compatible amb d’autres lectors de musica compatibles amb l’API Subsonic."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale es simple d’utilizar."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale es concebut per facilitar l’escota de las musicas que vos agradan e descobrir de novèls artistas."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale es a gratís e vos dòna lo contròla de vòstra musica."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale prend cura de vòstra musica"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "Acrochis generals"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Obténer una novèla invitacion"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Menatz-me a la bibliotèca"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
-msgstr "Obtenètz de metadonadas de qualitat per vòstra musica gràcia a <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
+msgstr ""
+"Obtenètz de metadonadas de qualitat per vòstra musica gràcia a <a href=\"%{ "
+"url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Començar"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Obténer d’ajuda"
+
 #: front/src/components/Footer.vue:37
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "Obténer d’ajuda"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Zo"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Tornar a l’acuèlh"
 
+#: front/src/components/auth/Settings.vue:128
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Artistas amagats"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr "Amagar lo contengut del compte o del demoni, levat pels seguidors."
 
+#: front/src/components/moderation/FilterModal.vue:40
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Amagar lo contengut"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr "Amagar lo contengut d’aqueste artista"
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr "Amagar lo contengut d’aqueste artista…"
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Acuèlh"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Oras de musica"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Pr’aquò, accedir a Funkwhale d’un client estant demanda un senhal diferent que podètz configurar çai-jos."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Se l’adreça qu’avètz provesida es valida e associada a un compte utilizaire, sètz per recebre un messatge amb las consignas de reïnicializacion d’aquí una estona."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Data d’import"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
+"S’autorizatz de tèrças aplicacions a accedir a vòstras donadas, seràn "
+"listadas aquí."
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importatz la musica de diferentas plataforma, coma YouTube o Soundcloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Detalhs de l’import"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Importar la referéncia"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Estatut de l’import"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "Estatut de l’import"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importat"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Data d’import"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr "Connexion impossibla al servidor alonhat"
+
+#: front/src/components/moderation/FilterModal.vue:26
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Dins lo widget « Ajustada i a res »"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr "Dins las listas d’artistas e d’albums"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "Als favorits"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr "Dins los favorits e istorics d’escota d’autres utilizaires"
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr "Dins las suggestions de ràdios"
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Actiu"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "Aumentar lo volum"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Picatz l’adreça de corrièl ligada a vòstre compte"
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Inserir de la fila (%{ count } pista)"
 msgstr[1] "Inserir de la fila (%{ count } pistas)"
 
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Instància"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Donadas de l’instància"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Info. de l’instància"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Ràdios de l’instància"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Paramètres de l’intància"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "URL de l’instància"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
-msgstr ""
-"Tipe de fichièr pas valid, asseguratz-vos d’enviar un fichièr àudio. Las "
-"extensions compatiblas son %{ extensions }"
+msgstr "Tipe de fichièr pas valid, asseguratz-vos d’enviar un fichièr àudio. Las extensions compatiblas son %{ extensions }"
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
+msgstr "Metadonada invalida"
+
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Còdi d’invitacion"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Còdi d’invitacion (opcional)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Invitacions"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Traçador de problèmas"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr "Connexion impossibla a l’URL donada"
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Gardatz una traça de vòstras cançons favoritas"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr "Acorchis clavièr"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Comptes coneguts"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Bibliotècas conegudas"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Darrièra activitat"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "Darrièra verificacion"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Darrièra modificacion"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "Darrièra visita"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Darrièra visita"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Darrièra actualizacion :"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Aviar"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Ne saber mai tocant aquesta instància"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Daissar void per obténer un còdi aleatòri"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Daissar void per un widget adaptatiu"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+msgctxt "*/*/*/Noun"
 msgid "Libraries"
 msgstr "Bibliotècas"
 
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+msgctxt "*/*/*"
+msgid "Libraries"
+msgstr "Bibliotècas"
+
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Bibliotèca e mandadís"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "Las bibliotècas vos ajudan a organizar e partejar vòstras colleccions de musica. Podètz enviar vòstra pròpria collecion musicala a Funkwhale e la partejar amb vòstres amics e vòstra familha."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Bibliotèca"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Bibliotèca creada"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Donadas de bibliotèca"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Bibliotèca suprimida"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
-msgstr "Fichièrs de la bibliotèca"
+#: front/src/views/admin/library/EditsList.vue:4
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
+msgstr "Modificacions de la bibliotèca"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Bibliotèca actualizada"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "Licéncia"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr "Escotas"
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr "Escotas"
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Ne cargar mai…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Cargament dels seguidors…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Cargament de las bibliotècas…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Cargament de las donadas de la bibliotèca…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Cargament de las notificacions…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
-msgstr "Cargament de las bibliotècas alonhadas..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
+msgstr "Cargament de las bibliotècas alonhadas…"
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Cargament de l’utilizacion de las donadas…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Cargament dels favorits…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr "Local"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Compte local"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Connexion"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Connectatz-vos a vòstre compte Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Desconnexion"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Connectat coma %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Connexion"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Estat del compte"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Desconnexion"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
-msgstr ""
-"Sembla qu’avètz pas cap de bibliotèca pel moment, es ora de ne crear una."
+msgstr "Sembla qu’avètz pas cap de bibliotèca pel moment, es ora de ne crear una."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Repeticion desactivada. Clicatz per activar la repeticion de la pista actuala."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Repeticion de la pista actuala. Clicatz per activar la repeticion de tota la fila."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Repeticion de tota la fila, clicatz per desactivar la repeticion."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Paraulas"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "Menú màger"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Gerir la bibliotèca"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Gerir las listas de lectura"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Gerir los utilizaires"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Gerir vòstras listas de lectura"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Las marcar totas coma legidas"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Marcar coma legidas"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Marcar coma pas legidas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "Mo"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr "Lector mèdia"
 
+#: front/src/components/auth/Profile.vue:12
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Membre dempuèi %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "Aplicacions mobil e de burèu"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Moderacion"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
-"Las politicas de moderacion vos ajudan a contrarotlar cossí vòstra instància "
-"deu interagir amb un compte o domeni donat."
+msgstr "Las politicas de moderacion vos ajudan a contrarotlar cossí vòstra instància deu interagir amb un compte o domeni donat."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Modificacion %{ id }"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Data de modificacion"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr "Mai…"
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Musica"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Copar lo son"
 
-#: front/src/components/Sidebar.vue:34
-msgid "My account"
-msgstr "Mon compte"
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Amagar l’activitat"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Amagar las notificacions"
+
+#: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
+msgid "My account"
+msgstr "Mon compte"
+
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Ma descripcion tròp crana"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Ma bibliotèca tròp crana"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "Ma lista de lectura tròp crana"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Ma ràdio tròp crana"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Mas bibliotècas"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "ND"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nom"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nom"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nom"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nòu senhal"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Las novèlas pistas seràn automaticament ajustadas aquí."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr "Nòva valor"
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Pista seguenta"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Non"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Cap d’extension d’installar, vos cal pas qu’una bibliotèca sul web"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Cap d’album correspond pas a vòstra recèrca"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Cap d’artista correspond pas a vòstra recèrca"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
-msgstr "Cap de paraulas pas disponiblas per aquesta pista."
+#: front/src/components/library/TrackDetail.vue:14
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
+msgstr ""
+"Cap d’informacions pas disponiblas per aquesta pista tocant los dreches "
+"d’autor"
+
+#: front/src/components/library/TrackDetail.vue:25
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Avèm pas cap d’informacion de licéncia per aquesta pista"
 
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Cap de bibliotèca correspondenta."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
-msgstr "Cap de notificacion pel moment."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
+msgstr "Cap de notificacion de mostrar."
+
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr "Cap de resultat pas trobat."
 
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Degun fòra ieu"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Degun sèc pas aquesta bibliotèca"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Pas utilizat"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Notificacions"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Notificacions"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Site oficial"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Senhal precedent"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr "Anciana valor"
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Accès liure"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Dobrir dins l’interfàcia de moderacion"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Dobrir lo perfil local"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Veire sus MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "Dobrir lo perfil"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Dobrir lo perfil alonhat"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Dobrir lo site web"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "O personalizatz aquesta règla"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Ã’rdre"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Ã’rdre"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Direccion"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Proprietari"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Pagina pas trobada"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Pagina pas trobada !"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr "Paginacion"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Senhal"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Senhal actualizat"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Senhal corrèctament modificat"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Pausar"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr "Pausar/Legir la pista actuala"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "En pausa"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "En espèra"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "En espèra de validacion"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Fichièrs en espèra"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Demandas d’abonament en espèra"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "En espèra de validacion"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Fichièrs en espèra"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Autorizacions"
+
+#: front/src/components/auth/Settings.vue:176
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Autorizacions"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Legir"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "O legir tot"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Legir totes los albums"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Legir en seguida"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Legir la pista seguenta"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Legir ara"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Legir la pista precedenta"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr "Legir de cançons similaras"
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Legir aquesta pista"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Legir"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Legir…"
+
+#: front/src/views/playlists/Detail.vue:91
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Lista de lectura"
 
 #: front/src/views/playlists/Detail.vue:12
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Lista de lectura contenent %{ count } pista, per %{ username }"
 msgstr[1] "Lista de lectura contenent %{ count } pistas, per %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Lista de lectura creada"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Editor de lista de lectura"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nom de la lista de lectura"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Lista de lectura actualizada"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Visibilitat de la lista de lectura"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Listas de lectura"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Listas de lectura"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
-msgstr "Las listas de lectura ? Son aicí !"
+msgstr "Las listas de lectura ? Las avèm"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Mercés de verificar que lo senhal es corrèct"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Mercés de verificar que lo nom d’utilizaire e lo senhal son corrèctes"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF o JPG. 2Mo al maximum. L’imatge serà retalhat en 400×400 pixèls."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Posicions"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
-"Empacha lo compte o domeni de far veire de notificacions, levat pels "
-"seguidors."
+msgstr "Empacha lo compte o domeni de far veire de notificacions, levat pels seguidors."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "Apercebut"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Pista precedenta"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr "Privat"
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Error en explorant"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Contunhar"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Contunhar cap a la pagina de connexion"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Tractament"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Perfil"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1892,1088 +3137,1901 @@ msgstr "Tractament"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Purgar"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Purgar los fichièrs amb errors ?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Purgar los fichièrs en espèra ?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Purgar los fichièrs ignorats ?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Fila"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "La fila es estada mesclada !"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Ràdio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Editor de ràdio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Nom de la ràdio"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nom de la ràdio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Ràdio actualizada"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Ràdios"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Ràdios"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr "Lectura"
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr "Legissètz nòstra documentacion per aquesta error"
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr "Lectura sola"
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr "Accès lectura sola de las donadas utilizaire"
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr "Rason"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr "Seguiments de bibliotècas recebuts"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "Messatges recebuts"
 
+#: front/src/components/library/EditForm.vue:27
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Modificacions recentas"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr "Modificacions recentas en espèra de relectura"
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Ajustats i a res"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Ajustadas als favorits i a res"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Escotadas i a res"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr "URI de redireccion"
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Actualizar"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Error en actualizar"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr "Actualizar del servidor alonhat estant"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr "Actualizar las info del nos"
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Actualizar las info del nos"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr "Actualizacion reüssida"
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "Actualizar lo contengut de la tabla"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Marcat dempuèi %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr "L’actualizada es estada passada"
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "Las inscripcions son tampadas sus aquestà instància, aurètz de téner un còdi d’invitacion per vos marcar."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
-msgstr "utilizaire estandard"
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
+msgstr "Utilizaire estandard"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Regetar"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Regetar lo mèdia"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Regetat"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Relançar l’import"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Data de sortida"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr "Espaci liure"
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Bibliotècas alonhadas"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Las bibliotècas alonhadas apertenon a d’autres utilizaires del malhum. I podètz accedir tant que sián publicas o qu’ajatz l’autorizacion."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Tirar"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Suprimir l’avatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Levar lo filtre"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Tirar dels favorits"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
-"Las pistas importadas que lo servidor a pas encara tractadas seràn "
-"complètament suprimidas. Lo quòta correspondent vos serà tornat."
+msgstr "Las pistas importadas que lo servidor a pas encara tractadas seràn complètament suprimidas. Lo quòta correspondent vos serà tornat."
 
 #: front/src/views/content/libraries/Quota.vue:64
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr "Aquò escafarà las pistas enviadas mas ignoradas pendent lo processús d’importacion per mantun rasons. Aquò tirarà complètament los fichièrs e vos donarà de nòu lo quòta escafat."
+msgstr "Las pistas enviadas mas ignoradas pendent lo processús d’importacion per mantun rasons seràn complètament suprimidas. Vos donarà de nòu lo quòta escafat."
 
 #: front/src/views/content/libraries/Quota.vue:90
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr "Aquò escafarà las pistas enviadas mas pas tractadas pel moment. Aquò tirarà los complètament los fichièrs e vos donarà de nòu lo quòta escafat."
+msgstr "Las pistas enviadas mas pas complètament tractadas pel servidor seràn complètament suprimidas. Vos donarà de nòu lo quòta escafat."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Demandar un nòu senhal"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Demandar un nòu senhal per l’API Subsonic ?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Demandar un senhal"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr "Tornar a la valor iniciala : %{ value }"
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Reïnicializar lo senhal"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Relançar l’import"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Resultats per pagina"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr "Restrénher  a la modifications pas repassadas"
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Tornar a la pagina de connexion"
 
+#: front/src/components/library/ArtistDetail.vue:9
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Validar mos filtres"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr "Revocar"
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr "Revocar l’accès"
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr "Revocar l’accès a l’aplicacion « %{ application } » ?"
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "Règla"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Enregistrar"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Exploracion lançada"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Explorar ara"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Analisi en espèra"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Exploracion sautada (la darrièra es tròp recenta)"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "Exploracion en espèra"
-
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Explorat"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Explorada amb d’errors"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Exploracion… (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr "Visibilitat"
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr "Visibilitats"
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Recercar"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Cercar una bibliotèca alonhada"
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Recercar per títol, artista, domeni…"
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Recercar per domeni, actor, nom, descripcion…"
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Recercar per domeni, actor, nom, referéncia, sorga…"
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Recercar per domeni, nom, ID MusicBrainz,…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Recercar per títol, artista, album, ID MusicBrainz…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Recercar per títol, artista, ID MusicBrainz…"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
-msgstr "Recercar per domenu, nom d’utilizaire, bio…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Recercar per domeni, nom d’utilizaire, bio…"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
-msgstr "Recercar per nom d’utilizaire…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Recercar per nom…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
 msgstr "Recercar per títol, artista, album…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "Recercar per títol, artista, domeni…"
-
 #: front/src/components/manage/users/InvitationsTable.vue:153
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Recercar per nom d’utilizaire, corrièl, còdi…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Recercar per nom d’utilizaire, corrièl, nom…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Recercar d’artistas, d’albums, de pistas…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Recercar de musica"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Recercar sus lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Recercar sus Wikipèdia"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr "Menú segondari"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Seccions"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Seleccionar un filtre"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "Seleccionar l’ensemble dels %{ total } element"
 msgstr[1] "Seleccionar l’ensemble dels %{ total } elements"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Seleccionar solament la pagina actuala"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Paramètres"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Paramètres actualizats"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Paramètres corrèctament modificats."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Ligam de partatge"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"Partajatz aqueste ligam amb d’autres utilizaires per que pòscan accedir a "
-"vòstra bibliotèca."
+msgstr "Partajatz aqueste ligam amb d’autres utilizaires per que pòscan accedir a vòstra bibliotèca."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Ligam de partatge"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "%{ count } pista mai"
 msgstr[1] "%{ count } pistas mai"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Mostrar 1 album mai"
 msgstr[1] "Mostrar %{ count } albums mai"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr "Mostrar totas las modificacions"
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "Mostrar los acorchis clavièr disponibles"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Mostrar las notificacions legidas"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Mostrar/amagar lo senhal"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Afichatge dels resultats %{ start }-%{ end } sus %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Mesclar la fila"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Mesclar la fila"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Inscripcion"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Inscripcion"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Data d’inscripcion"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
-msgid "Silence activity"
-msgstr "Far venir l’activitat silenciosa"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "Far venir las notificacions silenciosas"
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Talha"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Talha"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Ignorat"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Fichièrs ignorats"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "Logicial"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr "Unas pistas de la fila son ja dins aquesta lista de lectura :"
+
+#: front/src/components/PageNotFound.vue:10
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "O planhèm, la pagina demandada existís pas :"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Còdi font"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Membre de la còla"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Aviar"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Aviar la ràdio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Estatisticas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
+msgstr "Las estatisticas son calculadas amb las activitats conegudas e lo contengut de vòstra instància, son pas lo rebat de l’activitat generala d’aqueste compte"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
+msgstr "Las estatisticas son calculadas amb las activitats conegudas e lo contengut de vòstra instància, son pas lo rebat de l’activitat generala d’aqueste domeni"
+
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "Las estatisticas son calculadas amb las activitats conegudas e lo contengut de vòstra instància, son pas lo rebat de l’activitat generala d’aqueste compte"
+
+#: front/src/components/library/FileUpload.vue:95
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Estatut"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Estatut"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Estatut"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Estatut"
 
-#: front/src/components/library/FileUpload.vue:86
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Estatut"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Arrestar"
+#: front/src/views/content/libraries/Detail.vue:28
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Estatut"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Arrestar la ràdio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Validar"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr "Enviar e aplicar la modificacion"
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr "Enviar una modificacion de mai"
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr "Enviar la suggestion"
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Senhal de l’API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr "Suggerir un cambiament en utilizar lo formulari çai-jos."
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Podèm pas cargar aquesta pisata"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Podèm pas cargar aquesta pisata"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Podèm pas cargar aquesta pisata"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Suggestions"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Resumit"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr "Resumit (opcional)"
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "Forum d’assisténcia"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr "Extensions compatiblas : %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Sincronizacion dels cambiaments amb lo servidor…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Tèxte copiat al quichapapièr !"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "Es simple : nos agradava Grooveshark e voliam construire quicòm de melhor."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr "L’aplicacion demanda tanben las autorizacions desconegudas seguentas :"
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "Lo logotipe de Funkwhale foguèt dessenhat e fornit per Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr "L’adreça donada es pas un servidor Funkwhale"
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr "Aquesta bibliotèca e totas sas pistas seràn suprimidas. Aquesta accion se pòt pas anullar."
+
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
 msgstr ""
-"Aquesta bibliotèca e totas sas pistas seràn suprimidas. Aquesta accion se "
-"pòt pas anullar."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
-msgstr "Los fichièrs musicals que sètz a enviar son etiquetats coma cal :"
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
-msgstr "La pista seguenta serà legida automaticament dins una estona..."
+#: front/src/components/library/FileUpload.vue:38
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
+msgstr "Los fichièrs musicals que sètz a enviar son etiquetats coma cal."
 
-#: front/src/components/Home.vue:121
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
+msgstr "La pista seguenta serà legida automaticament dins una estona…"
+
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "La plataforma es gratuita e liura, podètz l’installar e la modificar sens cap de limit"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Lista de lectura creada"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "La suggestion serà complètament tirada, aquesta accion es irreversibla."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr "Se pòt que lo servidor siá atudat"
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "L’API Subsonic es pas disponibla per aquesta instància Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr "La suggestion serà complètament tirada, aquesta accion es irreversibla."
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Podèm pas ajustar aquesta pista a una lista de lectura"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr "La pista pòt pas èsser cargada"
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "La suggestion serà complètament tirada, aquesta accion es irreversibla."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Los fichièrs enviats son al format OGG, Flac o MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
-msgstr ""
-"Prepausam mantun biais de recuperar de nòu contengut e de lo far venir "
-"disponible aquí."
+msgstr "Prepausam mantun biais de recuperar de nòu contengut e de lo far venir disponible aquí."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "Aquesta accion se pòt pas anullar."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Aqueste album es present a las bibliotècas seguentas :"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Aqueste artista es present a las bibliotècas seguentas :"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr "Aqueste domeni es sosmés a de règlas de moderacion especificadas"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr "Aquesta instància provesís fins a %{quota} d’espaci per cada utilizaire."
+
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
 msgstr ""
-"Aquesta instància provesís fins a %{quota} d’espaci per cada utilizaire."
 
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "Sètz vos !"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Aquesta bibliotèca conten ma musica personala, espèri que vos agradarà."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
-"Aquesta bibliotèca es privada e son proprietari deu validar vòstra demanda d’"
-"accès per que accediscatz a son contengut"
+msgstr "Aquesta bibliotèca es privada e son proprietari deu validar vòstra demanda d’accès per que accediscatz a son contengut"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
-msgstr ""
-"Aqueste bibliotèca es publica e podètz accedir a son contengut liurament"
+msgstr "Aqueste bibliotèca es publica e podètz accedir a son contengut liurament"
 
-#: front/src/components/common/ActionTable.vue:45
-#, fuzzy
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
-msgstr "Aquesta operacion pòt afectar mantun elements, mercés de verificar s’es ben çò que desiratz."
+msgstr "Aquesta operacion pòt afectar mantun elements o pòt pas èsser anullada, mercés de verificar s’es ben çò que desiratz."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Utilizarem aquesta referéncia per gropar los fichièrs importats amassa."
 
-#: front/src/components/audio/PlayButton.vue:73
-msgid "This track is not available in any library you have access to"
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
 msgstr ""
-"Aquesta pista es pas disponibla dins cap de las bibliotècas qu’avètz accès"
+"Una error s’es producha en tractar aquesta pista, asseguratz-vos qu’es "
+"corrèctament etiquetada"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "La pista es enviada mas pas encara tractada pel servidor"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "La pista ja presenta dins una de vòstras bibliotècas"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
+msgid "This track is not available in any library you have access to"
+msgstr "Aquesta pista es pas disponibla dins cap de las bibliotècas qu’avètz accès"
+
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Aquesta pista es presenta a las bibliotècas seguentas :"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Aquò escafarà aquesta lista de lectura per totjorn e poirà pas èsser anullat."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Aquò escafarà aquesta ràdio per totjorn e poirà pas èsser anullat."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Aquò desactivarà complètament l’accès a l’API Subsonic de vòstre compte estant."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr ""
-"Aquò escafarà vòstras donadas localas e vos desconnectarà, volètz contunhar ?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Aquò vos desconnectarà de totes los periferics qu’utilizan aqueste senhal."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Aquò escafarà aquesta aplicacion per totjorn e totes los getons ligats."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Aquò escafarà totas las pistas de la lista de lectura e poirà pas èsser anullat."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+msgctxt "*/*/*/Noun"
 msgid "Title"
 msgstr "Títol"
 
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Títol"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr "Títol"
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr "Per contunhar, seleccionatz una instància Funkwhale que volètz vos i connectar. Picatz l’adreça dirèctament, o seleccionatz-ne una dins las en suggestion."
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr "Cambiar lo tipe de lectura de la lista"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "Talha totala"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Talha totala dels fichièrs d’aquesta bibliotèca"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Utilizaires totals"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Pista"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "La pista ja presenta dins una de vòstras bibliotècas"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Pista"
+
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr "Pista #%{ id } - %{ name }"
+
+#: front/src/views/admin/library/TrackDetail.vue:91
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Donada de la pista"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Informacions de la pista"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Pista correspondent al filtre"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Nom de la pista"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "La pista es enviada mas pas encara tractada pel servidor"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Pistas"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "pistas"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Pistas"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Pistas d’aqueste artista"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Pistas en favorits"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "pistas escotadas"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Pistas correspondentas al filtre"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Tipe"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Tipe"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
 msgstr "Jos règla de moderacion"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Quitar de seguir"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Quitar de seguir aquesta bibliotèca ?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
-msgstr "Malurosament, los gestionaris d’aquesta instància completèron pas aquesta pagina."
+#: front/src/components/About.vue:17
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
+msgstr "Malurosament, los gestionaris d’aquesta instància aguèron pas encara lo temps de completar pas aquesta pagina."
+
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr "Error desconeguda"
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr "Error desconeguda"
 
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Musica sens cap de limit"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Restablir lo son"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Actualizar"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Actualizar l’aplicacion"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Actualizar l’avatar"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Actualizar la bibliotèca"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "Actualizar la règla de moderacion"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Actualizar la lista de lectura"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Actualizar los paramètres"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Actualizar vòstre senhal"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Mandadís"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Enviar un nòu avatar"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Actualizar lo contengut àudio"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Data de mandadís"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Data de mandadís"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "Mandadís refusat, asseguratz-vos que lo fichièr es pas tròp grand e qu’avètz pas atenhut vòstre quòta"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
-"Mandadís refusat, asseguratz-vos que lo fichièr es pas tròp grand e qu’avètz "
-"pas atenhut vòstre quòta"
 
 #: front/src/views/content/Home.vue:7
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr "Enviatz vòstres fichièrs musicals (mp3, ogg, flac, etc.) de vòstra bibliotèca personala estant dirèctament amb vòstre navigador per ne profechar aquí."
+msgstr "Enviatz vòstres fichièrs musicals (MP3, OGG, FLAC, etc.) de vòstra bibliotèca personala estant dirèctament amb vòstre navigador per ne profechar aquí."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Enviar nòvas pistas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Quòta de mandadís"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Temps de transferiment expirat, ensajatz tornamai"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Enviat"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Mandadís en cors"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Mandadís…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Mandadís"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Mandadís"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "Mandadís"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Utilizar una autra instància"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Garnissètz aqueste formulari per demandar un nòu senhal. Auretz un corrièl a vòstra adreça indicada contenent las consignas de reïnicializacion."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
-"Utilizatz aqueste paramètre per activar/desactivar temporàriament la règla "
-"sens la suprimir complètament."
+msgstr "Utilizatz aqueste paramètre per activar/desactivar temporàriament la règla sens la suprimir complètament."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Utilizat"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Utilizaire"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Activitat dels utilizaires"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Bibliotècas de l’utilizaire"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Ràdios dels utilizaires"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nom d’utilizaire"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nom d’utilizaire o corrièl"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "utilizaires"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Utilizaires"
 
 #: front/src/components/Footer.vue:29
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
-msgstr "Utilizar de Funkwhale"
+msgstr "Utilizar Funkwhale"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Version %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Veire los fichièrs"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr "Veire sul panèl d’admin de Django"
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Veire sus MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Visibilitat"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Visibilitat : lo monde d’aquesta instància"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Visibilitat : totes, tanben las autras instàncias"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Visibilitat : degun levat ieu"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Visibilitat"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr "Volum %{ number }"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Podèm pas ajustar aquesta pista a una lista de lectura"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Podèm pas crear aquesta lista de lectura"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Podèm pas crear vòstre compte"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "Podèm pas cargar aquesta pisata"
+#: front/src/components/federation/FetchButton.vue:69
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "En espèra dels resultats…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Error pendent la connexion"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Podèm pas enregistrar vòstre avatar"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Podèm pas enregistrar vòstres paramètres"
+#: front/src/components/auth/ApplicationForm.vue:3
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Podèm pas enregistrar vòstras modificacions"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Vos pistam pas e vos mostram pas cap de reclama"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "Avèm pas cap d’informacion de copyright per aquesta pista"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "Avèm pas cap d’informacion de licéncia per aquesta pista"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "Vos recomandam d’utilizar lo logicial Picard per aquò far."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Pensam que l’accès a la musica deuriá èsser simple."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "O planhèm, la pagina demandada existís pas :"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "La benvenguda"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "La benvenguda a Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Perque Funkwhale ?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "Nautor del widget"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "Largor del widget"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr "Escritura"
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr "Escritura sola"
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Ã’c"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Òc-ben, desconnectatz-me !"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
-msgstr ""
-"Poiretz partejar vòstra bibiotèca amb d’autres gents, sens importància de sa "
-"visibilitat."
+msgstr "Poiretz partejar vòstra bibiotèca amb d’autres gents, sens importància de sa visibilitat."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Sètz a man d’enviar de la musica a vòstra bibliotèca. Abans de començar, mercés de vos assegurar que :"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr "Sètz actualament connectat a <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. Se contunhatz, seretz desconnectat de l’instància actuala e totas vòstras donadas localas seràn suprimidas."
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr "Amagatz lo contengut ligat a aqueste artista."
+
 #: front/src/components/auth/Logout.vue:7
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Sètz connectat coma %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr "Envietz pas cap de contengut jos dreches a una bibliotèca publica, autrament enfranhètz la lei"
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr "Utilizatz una instància Funkwhale a %{ url }"
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Podètz seguir las bibliotècas d’autres utilizaires per accedir a de nòvas musicas. Las bibliotècas publicas pòdon èsser seguidas còp sec, mentre qu’una bibliotèca privada demanda una aprovacion de sus proprietaris."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Podètz convidar vòstres amics e vòstra familha a aquesta instància per que pòscan profeitar de vòstra musica"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr "Podètz gerir e actualizar los filtres quand volgatz dels paramètres de compte estant."
+
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Podètz ara utilizar lo servici sens cap de limitacions."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Podètz utilizar aquesta interfàcia per realizar vòstra pròpria ràdio personalizada, que jogarà las listas segon los critèris indicats."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Podètz los utilizar per profeitar de vòstras listas de lectura e de vòstra musica en mòde fòra linha sus vòstre mobil, tableta, per exemple."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Avètz pas cap d‘aplicacion connectada a aqueste compte."
+
+#: front/src/components/auth/Settings.vue:261
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Avètz pas cap d‘aplicacion configurada pel moment."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr "Avètz pas cap de règla en plaça per aqueste compte."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr "Avètz pas cap de règla en plaça per aqueste domeni."
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
+msgstr "Avètz pas l’autorizacion de modificar aqueste objècte, mas podètz suggerir de cambiaments. Un còp mandadas, las suggestions seràn repassadas abans validacion."
+
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Escotatz una ràdio"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr "Poiriá arribar qu’ajatz de problèma de connexion."
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Vos cal causir una instància per contunhar"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Sètz per èsser desconnectat d’aquesta session e vos caldrà vos connectar amb lo nòu senhal"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr "Vos mostrarem un còdi de copiar-pegar dins l’aplicacion."
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Vos caldrà actualizar lo senhal sus totes los clients qu’utilizan aqueste senhal."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr "Veiretz pas mai las pistas, albums e las activitats d’utilizaires ligadas a aqueste artista :"
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "L’avatar pòt pas èsser enregistrat"
+
+#: front/src/components/auth/Settings.vue:215
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Vòstras aplicacions"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr "L’avatar pòt pas èsser enregistrat"
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr "La modificacion es estada corrèctament enviada."
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Vòstres favorits"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "Vòstra musica, coma volètz"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Vòstras notificacions"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr "Lo senhal pòt pas èsser cambiat"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Vòstre senhal es corrèctament cambiat."
 
+#: front/src/components/auth/Settings.vue:14
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Impossible d’actualizar vòstres paramètres"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "Vòstre senhal Subsonic serà remplaçat per un nòu aleatòri, aquò vos desconnectarà de totes los periferics qu’utilizan l’ancian senhal"
+
+#: front/src/edits.js:47
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Posicions"
+
+#: front/src/edits.js:54
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Copyright"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Album contenent %{ count } pista, de %{ artist }"
+msgstr[1] "Album contenent %{ count } pistas, de %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } pista ajustada a la fila"
+msgstr[1] "%{ count } pistas ajustadas a la fila"
diff --git a/front/locales/pl/LC_MESSAGES/app.po b/front/locales/pl/LC_MESSAGES/app.po
index 7f0047855aae07ee819d5eaaff6b2d0f1b898754..a49742b58262bfa77bac6667925d1aa07b65aa8d 100644
--- a/front/locales/pl/LC_MESSAGES/app.po
+++ b/front/locales/pl/LC_MESSAGES/app.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
 "PO-Revision-Date: 2018-11-11 08:36+0000\n"
 "Last-Translator: Marcin Mikołajczak <me@m4sk.in>\n"
 "Language-Team: \n"
@@ -19,56 +19,67 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "„%{ title }”, od %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } z %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(pusta)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Zaloguj siÄ™ na swoje konto Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } z %{ total } zaznaczonego"
 msgstr[1] "%{ count } z %{ total } zaznaczonych"
 msgstr[2] "%{ count } z %{ total } zaznaczonych"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } utwór"
 msgstr[1] "%{ count } utwory"
 msgstr[2] "%{ count } utworów"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+#, fuzzy
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } utwór w %{ albumsCount } albumach"
 msgstr[1] "%{ count } utwory w %{ albumsCount } albumach"
 msgstr[2] "%{ count } utworow w %{ albumsCount } albumach"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } utwór zgodny z wybranymi filtrami"
 msgstr[1] "%{ count } utwory zgodne z wybranymi filtrami"
 msgstr[2] "%{ count } utworów zgodnych z wybranymi filtrami"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "Dodano %{ count } utwór do kolejki"
-msgstr[1] "Dodano %{ count } utwory do kolejki"
-msgstr[2] "Dodano %{ count } utworów do kolejki"
-
 #: front/src/components/playlists/Card.vue:18
+#, fuzzy
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} utwór"
@@ -76,34 +87,48 @@ msgstr[1] "%{ count} utwory"
 msgstr[2] "%{ count} utworów"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "Wykorzystano %{ count } z dozwolonego %{ total }"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } godz. %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
 msgstr ""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr ""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Profil %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
 
 #: front/src/components/audio/artist/Card.vue:41
+#, fuzzy
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 album"
@@ -111,78 +136,190 @@ msgstr[1] "%{ count } albumy"
 msgstr[2] "%{ count } albumów"
 
 #: front/src/components/favorites/List.vue:10
+#, fuzzy
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 polubienie"
 msgstr[1] "%{ count} polubienia"
 msgstr[2] "%{ count} polubień"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+#, fuzzy
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Przejrzysta biblioteka"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Wystąpił błąd sieci podczas wysyłania tego pliku"
 
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Wystąpił błąd podczas zapisywania zmian"
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "O %{ instance }"
 
 #: front/src/components/Footer.vue:6
-#, fuzzy
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "O %{ instance }"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "O Funkwhale"
 
 #: front/src/components/Footer.vue:10
-#, fuzzy
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Strona albumu"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "O tej instancji"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Zaakceptuj"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Zaakceptowano"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Brak dostępu"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Zaznacz filtr"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Brak dostępu"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Dodaj do ulubionych"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Twoje powiadomienia"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Dodaj do playlisty…"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Brak dostępu"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
 msgstr "Uzyskaj dostęp do swojej muzyki z przejrzystego interfejsu skupionego na tym, co naprawdę ważne"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "Data dostępu"
+msgstr "Brak dostępu"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Stan konta"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
 #, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Stan konta"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Konto aktywne"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Ustawienia konta"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Ustawienia konta"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Stan konta"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Adres e-mail konta"
 
@@ -190,1682 +327,2826 @@ msgstr "Adres e-mail konta"
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
 #, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Stan konta"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Działanie"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "Działanie %{ action } zostało rozpoczęte pomyślnie na %{ count } elemencie"
 msgstr[1] "Działanie %{ action } zostało rozpoczęte pomyślnie na %{ count } elementach"
 msgstr[2] "Działanie %{ action } zostało rozpoczęte pomyślnie na %{ count } elementach"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Działania"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Aktywny"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Aktywność"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Widoczność aktywności"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr ""
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
-msgstr ""
+msgstr "Usuń radio"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Dodaj i zarządzaj zawartością"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Dodaj zawartość"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Dodaj filtr"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Dodaj filtry aby dostosować swoje radio"
 
-#: front/src/components/audio/PlayButton.vue:64
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Dodaj do kolejki"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Dodaj do ulubionych"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
-#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Dodaj do playlisty…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Dodaj do kolejki"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Dodaj do tej playlisty"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Dodaj utwór"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Administrator"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administracja"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Album"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Album zawiera %{ count } utwór od %{ artist }"
-msgstr[1] "Album zawiera %{ count } utwory od %{ artist }"
-msgstr[2] "Album zawiera %{ count } utworów od %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Album"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Albumy tego wykonawcy"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "Nazwa albumu"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Strona albumu"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Nazwa albumu"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Albumy"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Albumy tego wykonawcy"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Wszystkie"
 
+#: front/src/components/common/ActionTable.vue:59
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "%{ count } z %{ total } zaznaczonego"
+msgstr[1] "%{ count } z %{ total } zaznaczonych"
+msgstr[2] "%{ count } z %{ total } zaznaczonych"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "Wystąpił błąd podczas zapisywania zmian"
 
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Wystąpił błąd podczas zapisywania zmian"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Wystąpił błąd podczas zapisywania zmian"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Wystąpił nieznany błąd, może oznaczać to że serwer jest wyłączony lub nieosiągalny"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Działanie"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Czy na pewno chcesz się wylogować?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Wykonawca"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Wykonawca"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Nazwa wykonawcy"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Strona wykonawcy"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Nazwa wykonawcy"
 
 #: front/src/components/audio/Search.vue:65
-#, fuzzy
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Wykonawca, album, utwór…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Wykonawcy"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Wykonawcy"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "RosnÄ…co"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Poproś o zresetowanie hasła"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
-#, fuzzy
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Dodaj zawartość"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Dostępne playlisty"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Awatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Wróć do logowania"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Aktualizuj ustawienia"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Bitrate"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "PrzeglÄ…daj"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "PrzeglÄ…daj bibliotekÄ™"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Przeglądanie radiów"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Przeglądanie wykonawców"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "PrzeglÄ…danie list odtwarzania"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Przeglądanie radiów"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Budowanie"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "Od %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr "Gdy przestaniesz obserwować tę bibliotekę, stracisz dostęp do jej zawartości."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Anuluj"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Kandydaci"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Nie udało się zmienić Twojego hasła"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "Nie można było zaimportować tego pliku, upewnij się że nie jest zbyt duży"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Zmień język"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Zmień moje hasło"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Zmień hasło"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Zmień swoje hasło"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Zmienić Twoje hasło?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Zsynchronizowano zmiany z serwerem"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Zmiana Twojego hasła zmieni też Twoje hasło API Subsonic, jeżeli uzyskałeś(-aś) je."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "Zmiana hasła będzie miała następujące konsekwencje"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr ""
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Wybierz instancjÄ™"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Przejrzysta biblioteka"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Wyczyść"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Wyczyść"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Wyczyść listę odtwarzania"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Wyczyść swoją kolejkę"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Naciśnij raz, słuchaj godzinami dzięki wbudowanemu radio"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Naciśnij aby wybrać pliki do wysłania lub przeciągnij i upuść pliki lub katalogi"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr ""
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Kod"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Zwiń"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Konfiguracja"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Potwierdź"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
-#, fuzzy
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Potwierdź swój e-mail"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Kod potwierdzajÄ…cy"
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Zaznacz filtr"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Zaznacz filtr"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
 msgstr ""
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Kopiuj"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
 msgstr "Skopiuj utwory z obecnej kolejki do listy odtwarzania"
 
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
+
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr ""
 
-#: front/src/components/library/Track.vue:91
-#, fuzzy
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Kopiuj"
 
 #: front/src/views/auth/EmailConfirm.vue:7
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Potwierdź swój e-mail"
 
 #: front/src/views/content/remote/ScanForm.vue:3
-#, fuzzy
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Wystąpił błąd podczas uzyskiwania zdalnej biblioteki"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-#, fuzzy
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr "Wystąpił błąd w trakcie przetwarzania tego utworu, upewnij się że posiada on poprawne metadane"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Covery, teksty, naszym celem jest mieć je wszystkie ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Utwórz importowanie"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Utwórz konto funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Utwórz nową listę odtwarzania"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Utwórz nową listę odtwarzania"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Utwórz nową bibliotekę"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Utwórz nową listę odtwarzania"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Utwórz konto"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Utwórz listę odtwarzania"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Utwórz bibliotekę"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Utwórz konto"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Utwórz listę odtwarzania"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Utwórz własne radio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Data utworzenia"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Obecny awatar"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Obecna biblioteka"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Obecny utwór"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Obecne użycie"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Data"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Informacje o utworze"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Usuń"
 
-#: front/src/views/content/libraries/Form.vue:39
-msgid "Delete library"
-msgstr "Usuń bibliotekę"
-
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+#: front/src/components/auth/Settings.vue:254
 #, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Usuń listę odtwarzania"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
+msgid "Delete library"
+msgstr "Usuń bibliotekę"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Usuń radio"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Usuń listę odtwarzania"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Usuń radio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Czy chcesz usunąć tę bibliotekę?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Czy chcesz usunąć tę bibliotekę?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Czy chcesz usunąć tę bibliotekę?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
-#, fuzzy
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Czy chcesz usunąć tę bibliotekę?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Czy chcesz usunąć tę bibliotekę?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Czy chcesz usunąć tę bibliotekę?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "MalejÄ…co"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Opis"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Szczegóły"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Opis"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Szczegóły"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Określ jak dużo zawartości może zaimportować użytkownik. Pozostaw puste, aby użyć domyślnej wartości instancji"
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Ustal poziom widoczności twojej aktywności"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Wyłącz dostęp"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Wyłącz dostęp Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Wyłączyć dostęp do API Subsonic?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Wyłącz dostęp"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Odkryj, jak korzystać z Funkwhale z innych aplikacji"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Nazwa pliku"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Wyświetlaj publicznie"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Czy chcesz wyczyścić listę odtwarzania „%{ playlist }”?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Czy chcesz potwierdzić to działanie?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Czy chcesz usunąć listę odtwarzania „%{ playlist }”?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Czy chcesz usunąć radio „%{ radio }”?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Czy chcesz usunąć radio „%{ radio }”?"
+
+#: front/src/components/common/ActionTable.vue:37
+#, fuzzy
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Czy chcesz wykonać działanie %{ action } na %{ count } elemencie?"
 msgstr[1] "Czy chcesz wykonać działanie %{ action } na %{ count } elementach?"
 msgstr[2] "Czy chcesz wykonać działanie %{ action } na %{ count } elementach?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Czy chcesz przywrócić poprzednią kolejkę?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Dokumentacja"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr ""
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr ""
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Pobierz"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Przeciągnij i upuść aby zmienić kolejność utworów w liście odtwarzania"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Długość"
 
 #: front/src/views/auth/EmailConfirm.vue:23
-#, fuzzy
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Potwierdzono e-mail"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Prosty w użyciu"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Edytuj"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Edytuj"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Błąd podczas zastosowywania działania"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Edytuj informacje o instancji"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Usuń radio"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Odtwórz utwór"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Odtwórz utwór"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Odtwórz utwór"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Edytuj"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
 #, fuzzy
-msgid "Edit…"
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
 msgstr "Edytuj"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "E-mail"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Adres e-mail"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr ""
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr ""
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr ""
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr "Wprowadź adres URL biblioteki"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Enabled"
-msgstr ""
+msgstr "Wyłącz dostęp"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Zakończ edytowanie"
 
 #: front/src/views/content/remote/ScanForm.vue:50
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Wprowadź adres URL biblioteki"
 
-#: front/src/components/library/Radios.vue:140
-#, fuzzy
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Wprowadź nazwę radia…"
 
-#: front/src/components/library/Artists.vue:118
-#, fuzzy
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Wprowadź nazwę wykonawcy…"
 
 #: front/src/views/playlists/List.vue:107
-#, fuzzy
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Wprowadź nazwę listy odtwarzania…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Wprowadź swój e-mail"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Wprowadź swój kod zapraszający (wielkość znaków nie ma znaczenia)"
 
 #: front/src/components/metadata/Search.vue:114
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Wprowadź swoje kryterium wyszukiwania…"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Wprowadź swoją nazwę użytkownika"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Wprowadź swoją nazwę użytkownika lub e-mail"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "BÅ‚Ä…d"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Zgłaszanie błędów"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Zgłaszanie błędów"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Zakończono błędem"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Błąd podczas zastosowywania działania"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Wystąpił błąd podczas prośby o zresetowanie hasła"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Błąd podczas zastosowywania działania"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Wystąpił błąd podczas zmiany hasła"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
-#, fuzzy
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Wystąpił błąd podczas tworzenia zaproszenia"
 
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Wystąpił błąd podczas tworzenia zaproszenia"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Wystąpił błąd podczas tworzenia zaproszenia"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
-#, fuzzy
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Wystąpił błąd podczas tworzenia zaproszenia"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
 #, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Wystąpił błąd podczas tworzenia zaproszenia"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Wystąpił błąd podczas uzyskiwania zdalnej biblioteki"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Wystąpił błąd podczas zapisywania ustawień"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Wystąpił błąd podczas zapisywania ustawień"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+#, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Wystąpił błąd podczas zapisywania ustawień"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Zakończono błędem"
 
 #: front/src/views/content/libraries/Quota.vue:75
-#, fuzzy
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Zakończono błędem"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Wszyscy"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Wszyscy na tej instancji"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
 #, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Wszyscy na tej instancji"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Wyłącz"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Data wygaśnięcia"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Wyczerpany"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Wyczerpany/zużyty"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+#, fuzzy
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
-msgstr ""
+msgstr "Sfederowane utwory"
 
-#: front/src/views/content/remote/Card.vue:58
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Sfederowane utwory"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Sfederowane utwory"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Ulubione"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Ulubione"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federacja"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
 #, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Federacja"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nazwa pliku"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Pliki"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Filtruj nazwÄ™"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Ukończono"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
-msgstr ""
+msgstr "Data wygaśnięcia"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Data wygaśnięcia"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Śledź"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Śledź zdalne biblioteki"
 
-#: front/src/views/content/remote/Card.vue:88
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Åšledzenie oczekuje na zatwierdzenie"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "ÅšledzÄ…cy"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "ÅšledzÄ…cy"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Åšledzisz"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Z albumu %{ album } od %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Śledź"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Wyłącz dostęp"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale jest kompatybilny z innymi odtwarzaczami muzycznymi obsługującymi API Subsonic."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale jest niezwykle prosty w użyciu."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale został zaprojektowany, aby uczynić słuchanie muzyki którą lubisz i poznawanie nowych wykonawców prostym."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale jest wolny i oddaje Ci kontrolÄ™ nad TwojÄ… muzykÄ…."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale dba o TwojÄ… bibliotekÄ™ muzycznÄ…"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Uzyskaj nowe zaproszenie"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Pokaż mi bibliotekę"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "Uzyskaj dobrej jakości metadane o Twojej muzyce dzięki <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Rozpocznij"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Ustawienia"
+
 #: front/src/components/Footer.vue:37
 #, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "Ustawienia"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Przejdź"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Przejdź na stronę główną"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Przeglądanie wykonawców"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr ""
 
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Dodaj zawartość"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr ""
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Strona główna"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Godziny muzyki"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Korzystanie z Funkwhale z tych klientów wymaga jednak oddzielnego hasła, które możesz ustawić poniżej."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Jeżeli adres e-mail podany w poprzednim kroku jest prawidłowy i przypisany do konta użytkownika, powinieneś dostać wiadomość z instrukcjami resetowania hasła w przeciągu kilku minut."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Data zaimportowania"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importuj muzykę z różnych platform, takich jak YouTube i SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Stan importu"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Importuj źródło"
 
-#: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Import status"
 msgstr "Stan importu"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/manage/library/UploadsTable.vue:20
+#: front/src/views/content/libraries/FilesTable.vue:11
+#: front/src/views/content/libraries/FilesTable.vue:59
 #, fuzzy
+msgctxt "Content/Library/*/Noun"
+msgid "Import status"
+msgstr "Stan importu"
+
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Data zaimportowania"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Data zaimportowania"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
+#, fuzzy
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Ostatnio dodane"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "W ulubionych"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Nieaktywny"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr ""
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr ""
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Dodaj z kolejki (%{ count } utwór)"
 msgstr[1] "Dodaj z kolejki (%{ count } utwory)"
 msgstr[2] "Dodaj z kolejki (%{ count } utworów)"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:71
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
 #, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Radia instancji"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Radia instancji"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Informacje o instancji"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Radia instancji"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Ustawienia instancji"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Radia instancji"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Kod zapraszajÄ…cy"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Kod zapraszajÄ…cy (nieobowiÄ…zkowy)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Zaproszenia"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Śledzenie błędów"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Zachowaj kontrolÄ™ nad ulubionymi utworami"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Moje konto"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Znane biblioteki"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Ostatnia aktywność"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#, fuzzy
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
-msgstr ""
+msgstr "Ostatnia aktualizacja:"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Ostatnia modyfikacja"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
-msgstr ""
+msgstr "Ostatnia aktualizacja:"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Ostatnia aktualizacja:"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Ostatnia aktualizacja:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Uruchom"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Dowiedz się więcej o tej instancji"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Pozostaw puste, aby wygenerować kod"
 
 #: front/src/components/audio/EmbedWizard.vue:7
-#, fuzzy
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Pozostaw puste, aby wygenerować kod"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Biblioteki"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Biblioteki"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Zaktualizowano bibliotekÄ™"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "Biblioteki pomagają organizować i udostępniać kolekcje muzyki. Możesz wysłać własną kolekcję muzyki na Funkwhale i dzielić się nią z rodziną i znajomymi."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Biblioteka"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Utworzono bibliotekÄ™"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
 #, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Zaktualizowano bibliotekÄ™"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Zaktualizowano bibliotekÄ™"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "Pliki z biblioteki"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Zaktualizowano bibliotekÄ™"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr ""
 
-#: front/src/views/content/libraries/Detail.vue:21
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
 #, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Ładowanie śledzących…"
+
+#: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Ładowanie śledzących…"
 
 #: front/src/views/content/libraries/Home.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Ładowanie bibliotek…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Ładowanie danych biblioteki…"
 
-#: front/src/views/Notifications.vue:4
-#, fuzzy
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Ładowanie powiadomień…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
 msgstr "Ładowanie zdalnych bibliotek…"
 
 #: front/src/views/content/libraries/Quota.vue:4
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Ładowanie danych o użyciu…"
 
 #: front/src/components/favorites/List.vue:5
-#, fuzzy
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Ładowanie Twoich ulubionych…"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
 #, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Moje konto"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Zaloguj siÄ™"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Zaloguj siÄ™ na swoje konto Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Wyloguj siÄ™"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Zalogowano jako %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Logowanie"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Stan konta"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Wyloguj siÄ™"
 
 #: front/src/views/content/libraries/Home.vue:9
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
 msgstr "Wygląda na to, że nie masz jeszcze żadnej biblioteki — czas na jej utworzenie!"
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Zapętlanie jest wyłączone. Naciśnij, aby przełączyć na powtarzanie jednego utworu."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Zapętlanie jednego utworu jest włączone. Naciśnij, aby przełączyć na powtarzanie całej kolejki."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Zapętlanie całej kolejki jest włączone. Naciśnij, aby wyłączyć zapętlanie."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Tekst"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr ""
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "ZarzÄ…dzaj bibliotekÄ…"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "ZarzÄ…dzaj listami odtwarzania"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Zarządzaj użytkownikami"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "ZarzÄ…dzaj swoimi listami odtwarzania"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Oznacz wszystko jako przeczytane"
 
-#: front/src/components/notifications/NotificationRow.vue:44
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Oznacz wszystko jako przeczytane"
 
-#: front/src/components/notifications/NotificationRow.vue:45
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Oznacz wszystko jako przeczytane"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr ""
 
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Zarejestrowany od %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
 #, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Federacja"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Data modyfikacji"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Data modyfikacji"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Muzyka"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Wycisz"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Ostatnia aktywność"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Twoje powiadomienia"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Moje konto"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Mój wspaniały opis"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Moja wspaniała biblioteka"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "Moja wspaniała playlista"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Moje wspaniałe radio"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Moje biblioteki"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "N/A"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nazwa"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nazwa"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nazwa"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nowe hasło"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Nowe utwory automatycznie pojawiÄ… siÄ™ tutaj."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Następny utwór"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Nie"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Brak wtyczek, brak dodatków: potrzebujesz tylko biblioteki sieciowej"
 
 #: front/src/components/audio/Search.vue:25
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Przepraszamy, nie znaleziono albumu spełniającego Twoje kryteria"
 
 #: front/src/components/audio/Search.vue:16
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Przepraszamy, nie znaleziono wykonawcy spełniającego Twoje kryteria"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "Tekst nie jest dostępny dla tego utworu."
 
+#: front/src/components/library/TrackDetail.vue:25
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Brak powiadomień do wyświetlenia!"
+
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Brak pasujÄ…cej biblioteki."
 
-#: front/src/views/Notifications.vue:26
-#, fuzzy
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
 msgstr "Twoje powiadomienia"
 
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr ""
+
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Nikt poza mnÄ…"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Nikt nie śledzi tej biblioteki"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Nie użyty"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Powiadomienia"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Powiadomienia"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Oficjalna strona"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Poprzednie hasło"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Otwórz"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Usuń radio"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Wyświetl na MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr ""
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr ""
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
-#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Oficjalna strona"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
-#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "Dodaj filtry aby dostosować swoje radio"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
-#, fuzzy
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "PorzÄ…dkowanie"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "PorzÄ…dkowanie"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Kolejność porządkowania"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Właściciel"
 
 #: front/src/components/PageNotFound.vue:33
-#, fuzzy
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Nie odnaleziono strony!"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Nie odnaleziono strony!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr ""
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Haslo"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Zmieniono hasło"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Pomyślnie zmieniono hasło"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Wstrzymaj utwór"
 
 #: front/src/components/ShortcutsModal.vue:59
+#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
-msgstr ""
+msgstr "Odtwórz utwór"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "OczekujÄ…ce"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Oczekiwanie na przyjęcie"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "OczekujÄ…ce pliki"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Oczekujące prośby o możliwość śledzenia"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "OczekujÄ…ce pliki"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "OczekujÄ…ce pliki"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Uprawnienia"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Uprawnienia"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Odtwórz"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Odtwórz wszystkie"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Odtwórz wszystkie albumy"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Odtwórz następny"
 
 #: front/src/components/ShortcutsModal.vue:67
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Odtwórz utwór"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Odtwórz teraz"
 
 #: front/src/components/ShortcutsModal.vue:63
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Poprzedni utwór"
 
-#: front/src/components/Sidebar.vue:211
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Odtwórz utwór"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Odtwórz utwór"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Odtwórz"
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Lista odtwarzania"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Lista odtwarzania zawierająca %{ count } utwór od %{ username }"
@@ -1873,77 +3154,122 @@ msgstr[1] "Lista odtwarzania zawierajÄ…ca %{ count } utwory od %{ username }"
 msgstr[2] "Lista odtwarzania zawierająca %{ count } utworów od %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Utworzono listÄ™ odtwarzania"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Edytor list odtwarzania"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nazwa listy odtwarzania"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Zaktualizowano listÄ™ odtwarzania"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Widoczność listy odtwarzania"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Listy odtwarzania"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Listy odtwarzania"
 
 #: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "Listy odtwarzania? Mamy je"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Sprawdź dwukrotnie, czy Twoje hasło jest poprawne"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Sprawdź dwukrotnie, czy połączenie nazwy użytkownika i hasła jest poprawne"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie pomniejszony do 400x400 pikseli."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Opis"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
 msgstr ""
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Poprzedni utwór"
 
-#: front/src/views/content/remote/Card.vue:39
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "BÅ‚Ä…d podczas skanowania"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Przejdź"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Przejdź, aby zalogować się"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Przetwarzanie"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1952,348 +3278,606 @@ msgstr "Przetwarzanie"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Wyczyść"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Wyczyścić pliki z błędami?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Wyczyścić oczekujące pliki?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Wyczyścić pominięte pliki?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Kolejka"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "Wymieszano kolejkÄ™!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Radio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Tworzenie radia"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Utworzono radio"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nazwa radia"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Zaktualizowano radio"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Radia"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Radia"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
-msgstr ""
+msgstr "Wprowadź adres URL biblioteki"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Ostatnio dodane"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Ostatnio dodane"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Ostatnio dodane do ulubionych"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Ostatnio słuchane"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Odśwież"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Odśwież"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "MalejÄ…co"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr ""
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Zarejestrowany od %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "Rejestracja na tej instancji jest wyłączona, potrzebujesz kodu zapraszającego aby zarejestrować się."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "zwykły użytkownik"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Odrzuć"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
 #, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Odrzucono"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Odrzucono"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Uruchom importowanie ponownie"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Ostatnia aktualizacja:"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Zdalne biblioteki"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Zdalne biblioteki należą do innych użytkowników sieci. Możesz uzyskać do nich dostęp jeżeli są publiczne lub został Ci on przyznany."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Usuń"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Usuń awatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Usuń awatar"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Usuń z ulubionych"
 
 #: front/src/views/content/libraries/Quota.vue:38
+#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Ta opcja usunie utwory które zostały wysłane, ale nie zostały jeszcze przetworzone. Bezpowrotnie usunie te pliki i zostanie Ci przywrócona odpowiednia przestrzeń."
 
 #: front/src/views/content/libraries/Quota.vue:64
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
 msgstr "Ta opcja usunie utwory które zostały wysłane, lecz zostały z jakiegoś powodu pominięte w procesie importowania. Bezpowrotnie usunie te pliki i zostanie Ci przywrócona odpowiednia przestrzeń."
 
 #: front/src/views/content/libraries/Quota.vue:90
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
 msgstr "Ta opcja usunie utwory które zostały wysłane, ale nie zostały jeszcze przetworzone. Bezpowrotnie usunie te pliki i zostanie Ci przywrócona odpowiednia przestrzeń."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Poproś o nowe hasło"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Poprosić o nowe hasło API Subsonic?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Poproś o nowe hasło"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Ustaw nowe hasło"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Uruchom importowanie ponownie"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Wyniki na stronÄ™"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
-#, fuzzy
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Przejdź, aby zalogować się"
 
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Zobacz pliki"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr ""
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Zapisz"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Uruchomiono skanowanie"
 
-#: front/src/views/content/remote/Card.vue:63
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Odtwórz teraz"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "RosnÄ…co"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Skanowanie pominęte (poprzednie skanowanie było zbyt wcześnie)"
 
-#: front/src/views/content/remote/Card.vue:31
-#, fuzzy
-msgid "Scan waiting"
-msgstr "Oczekiwanie na skanowanie"
-
-#: front/src/views/content/remote/Card.vue:43
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Uruchomiono skanowanie"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Zeskanowano z błędami"
 
-#: front/src/views/content/remote/Card.vue:35
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Skanowanie... (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Szukaj"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Wyszukaj w zdalnej bibliotece"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:171
+#: front/src/components/manage/library/EditsCardList.vue:211
 #, fuzzy
-msgid "Search by domain, username, bio..."
-msgstr "Szukaj według nazwy użytkownika, adresu e-mail, kodu…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Szukaj według tytułu, wykonawcy, domeny…"
 
-#: front/src/components/manage/moderation/DomainsTable.vue:151
+#: front/src/components/manage/library/LibrariesTable.vue:191
 #, fuzzy
-msgid "Search by name..."
-msgstr "Szukaj według nazwy użytkownika, adresu e-mail, nazwy…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Szukaj według nazwy użytkownika, adresu e-mail, kodu…"
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/components/manage/library/UploadsTable.vue:241
 #, fuzzy
-msgid "Search by title, artist, album…"
-msgstr "Szukaj według tytułu, wykonawcy, albumu…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Szukaj według nazwy użytkownika, adresu e-mail, kodu…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
+#: front/src/components/manage/library/ArtistsTable.vue:164
 #, fuzzy
-msgid "Search by title, artist, domain…"
-msgstr "Szukaj według tytułu, wykonawcy, domeny…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Szukaj według nazwy użytkownika, adresu e-mail, kodu…"
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Szukaj według tytułu, wykonawcy, albumu…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Szukaj według tytułu, wykonawcy, albumu…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Szukaj według nazwy użytkownika, adresu e-mail, kodu…"
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Szukaj według nazwy użytkownika, adresu e-mail, nazwy…"
+
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
+msgid "Search by title, artist, album…"
+msgstr "Szukaj według tytułu, wykonawcy, albumu…"
 
 #: front/src/components/manage/users/InvitationsTable.vue:153
 #, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Szukaj według nazwy użytkownika, adresu e-mail, kodu…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
-#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Szukaj według nazwy użytkownika, adresu e-mail, nazwy…"
 
 #: front/src/components/audio/SearchBar.vue:20
-#, fuzzy
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Szukaj wykonawców, albumów, utworów…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Wyszukaj trochÄ™ muzyki"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Szukaj na lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Szukaj na Wikipedii"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Sekcje"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Zaznacz filtr"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "Zaznacz %{ total } element"
 msgstr[1] "Zaznacz wszystkie %{ total } elementy"
 msgstr[2] "Zaznacz wszystkie %{ total } elementów"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Zaznacz tylko obecnÄ… stronÄ™"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Ustawienia"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Zaktualizowano ustawienia"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Pomyślnie zaktualizowano ustawienia."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Udostępnij odnośnik"
 
 #: front/src/views/content/libraries/Detail.vue:15
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
 msgstr "Podziel się tym odnośnikiem z innymi użytkownikami, aby mogli poprosić od dostęp do Twojej biblioteki."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Odnośnik do udostępnienia"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "Pokaż %{ count } utwór więcej"
@@ -2301,760 +3885,1372 @@ msgstr[1] "Pokaż %{ count } utwory więcej"
 msgstr[2] "Pokaż %{ count } utworów więcej"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Pokaż 1 kolejny album"
 msgstr[1] "Pokaż %{ count } kolejne albumy"
 msgstr[2] "Pokaż %{ count } kolejnych albumów"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr ""
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Pokaż przeczytane powiadomienia"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Pokaż/ukryj hasło"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Wyświetlanie wyników %{ start }-%{ end } z %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Wymieszaj kolejkÄ™"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Wymieszaj kolejkÄ™"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Rejestracja"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Rejestracja"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Data rejestracji"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
 #, fuzzy
-msgid "Silence activity"
-msgstr "Aktywność użytkownika"
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Rozmiar"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
 #, fuzzy
-msgid "Silence notifications"
-msgstr "Pokaż przeczytane powiadomienia"
-
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Rozmiar"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Pominięto"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Pominięte pliki"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr ""
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Przepraszamy, strona której szukasz nie istnieje:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Kod źródłowy"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Członek administracji"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Rozpocznij"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Zatrzymaj radio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Statystyki"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:86
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Stan"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Stan"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Stan"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Stan"
+
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Stan"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Zatrzymaj"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Stan"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Zatrzymaj radio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Wyślij"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Hasło API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Nie udało się dodać tego utworu do listy odtwarzania"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Nie udało się dodać tego utworu do listy odtwarzania"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Nie udało się dodać tego utworu do listy odtwarzania"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Polecane wybory"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Podsumowanie"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr ""
 
 #: front/src/components/playlists/Editor.vue:9
-#, fuzzy
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Synchronizowanie zmian z serwerem…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Skopiowano tekst do schowka!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "To proste: kochamy Grooveshark i chcemy utworzyć coś jeszcze lepszego."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "Logo Funkwhale zostało zaprojektowane i dostarczone przez Francisa Gadinga."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
 msgstr "Biblioteka i wszystkie utwory z niej zostaną usunięte. To działanie jest nieodwracalne."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr "Pliki muzyczne które wysyłasz są poprawnie otagowane:"
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
 msgstr ""
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "Platforma jest wolna i otwartoźródłowa, każdy może bez zmartwień zainstalować i modyfikować ją"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Utworzono listÄ™ odtwarzania"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "API Subsonic nie jest dostępne na tej instancji Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Nie udało się dodać tego utworu do listy odtwarzania"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Wysyłane pliki muzyczne są w formacie OGG, FLAC lub MP3"
 
 #: front/src/views/content/Home.vue:4
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
 msgstr "Oferujemy różne sposoby zdobywania nowej zawartości i udostępniania jej tutaj"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr ""
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Ten album występuje w następujących bibliotekach:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Ten artysta występuje w następujących bibliotekach:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr ""
 
 #: front/src/views/content/Home.vue:9
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr "Ta instancja oferuje maksymalnie %{quota} przestrzeni dla każdego użytkownika."
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "To Ty!"
 
-#: front/src/views/content/libraries/Form.vue:71
-#, fuzzy
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Ta instancja zawiera moją personalną bibliotekę, mam nadzieję że ją polubisz!"
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:45
-#, fuzzy
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
 msgstr "Może to wpływać na wiele rzeczy, sprawdź dwukrotnie czy to na pewno to, czego chcesz."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Te źródła zostaną wykorzystane, aby pogrubować zaimportowane pliki"
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Wystąpił błąd w trakcie przetwarzania tego utworu, upewnij się że posiada on poprawne metadane"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "Utwór został zaimportowany, ale jeszcze nie jest przetworzony przez serwer"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "Utwór jest już w jednej z twoich bibliotek"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
 msgstr ""
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Ten utwór występuje w następujących bibliotekach:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "To całkowicie usunie listę odtwarzania i nie może zostać cofnięte."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "To bezpowrotnie usunie radio."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "To całkowicie wyłączy dostęp do API Subsonic z tego konta."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-#, fuzzy
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr "To wyczyści Twoje lokalne dane i rozłączy Cię, czy chcesz kontynuować?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "To wyloguje Cię z urządzeń na których jesteś obecnie zalogowany."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "To całkowicie usunie listę odtwarzania i nie może zostać cofnięte."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "To bezpowrotnie usunie wszystkie utwory z tej listy odtwarzania."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Tytuł"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Tytuł"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
 msgid "Title"
 msgstr "Tytuł"
 
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
-msgstr ""
+msgstr "Nie użyty"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Łączny rozmiar wszystkich plików w tej bibliotece"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
-#, fuzzy
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Nie użyty"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Utwór"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Utwór"
+
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:91
 #, fuzzy
-msgid "Track already present in one of your libraries"
-msgstr "Utwór jest już w jednej z twoich bibliotek"
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Tytuł utworu"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Informacje o utworze"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Utwór zgodny z filtrem"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Tytuł utworu"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-#, fuzzy
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "Utwór został zaimportowany, ale jeszcze nie jest przetworzony przez serwer"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Utwory"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "utwory"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Utwory"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Utwory tego wykonawcy"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Ulubione utwory"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "wysłuchane utwory"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Utwór zgodny z filtrem"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Rodzaj"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Rodzaj"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr ""
+msgstr "Usuń radio"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Przestań śledzić"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Czy chcesz przestać śledzić tę bibliotekę?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "Niestety, właściciele tej instancji nie znaleźli czasu na wypełnienie tej strony."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Nieograniczona muzyka"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Cofnij wyciszenie"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Data wysyłania"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Aktualizuj listÄ™ odtwarzania"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Aktualizuj awatar"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Aktualizuj bibliotekÄ™"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr ""
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Aktualizuj listÄ™ odtwarzania"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Aktualizuj ustawienia"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Aktualizuj swoje hasło"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Wyślij"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Dodaj nowy awatar"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Wyślij zawartość dźwiękową"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Data wysyłania"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Data wysyłania"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
 msgstr "Błąd wysyłania, upewnij się że plik nie jest zbyt duży i że nie przekroczyłeś swojego limitu"
 
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
+msgstr ""
+
 #: front/src/views/content/Home.vue:7
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
 msgstr "Wyślij pliki muzyczne (mp3, ogg, flac itp.) ze swojej biblioteki bezpośrednio z przeglądarki, aby cieszyć się nimi tutaj."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Wyślij nowe utwory"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Powierzchnia dyskowa"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Importowanie zajęło zbyt długo, spróbuj jeszcze raz"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Wysłano"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Wysyłanie"
 
-#: front/src/components/library/FileUpload.vue:103
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Wysyłanie"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/manage/library/LibrariesTable.vue:52
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Wyślij"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
 #, fuzzy
+msgctxt "*/*/*"
 msgid "Uploads"
 msgstr "Wyślij"
 
+#: front/src/components/manage/moderation/AccountsTable.vue:41
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Uploads"
+msgstr "Wyślij"
+
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Skorzystaj z innej instancji"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Użyj tego formularza aby poprosić o zresetowanie hasła. Otrzymasz e-mail z instrukcjami resetowania hasła na podany adres."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Zużyty"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Użytkownik"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Aktywność użytkownika"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Biblioteki użytkownika"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Radia użytkownika"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nazwa użytkownika"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nazwa użytkownika lub adres e-mail"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "użytkownicy"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Użytkownicy"
 
 #: front/src/components/Footer.vue:29
 #, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "O Funkwhale"
 
 #: front/src/components/Footer.vue:13
-#, fuzzy
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Kod źródłowy (%{version})"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Zobacz pliki"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Wyświetl na MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Widoczność"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Widoczność: wszyscy na tej instancji"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Widoczność: wszyscy, uwzględniając inne instancje"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Widoczność: nikt poza mną"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Widoczność"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Nie udało się dodać tego utworu do listy odtwarzania"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Nie udało się utworzyć listy odtwarzania"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Nie udało się utworzyć Ci konta"
-
-#: front/src/components/audio/Player.vue:64
+#: front/src/components/federation/FetchButton.vue:69
 #, fuzzy
-msgid "We cannot load this track"
-msgstr "Nie udało się dodać tego utworu do listy odtwarzania"
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Ładowanie Twoich ulubionych…"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Nie udało się zalogować Cię"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Nie udało się zapisać awatara"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Nie udało się zapisać ustawień"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Nie udało się utworzyć Ci konta"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Nie śledzimy Cię i nie wyświetlamy Ci reklam"
 
-#: front/src/components/library/Track.vue:95
-#, fuzzy
-msgid "We don't have any copyright information for this track"
-msgstr "Brak powiadomień do wyświetlenia!"
-
-#: front/src/components/library/Track.vue:106
-#, fuzzy
-msgid "We don't have any licensing information for this track"
-msgstr "Brak powiadomień do wyświetlenia!"
-
-#: front/src/components/library/FileUpload.vue:40
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "polecamy używać do tego Picarda"
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Uważamy, że słuchanie muzyki powinno być proste."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Przepraszamy, strona której szukasz nie istnieje:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Witaj"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Witamy na Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Dlaczego funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Tak"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Tak, wyloguj mnie!"
 
 #: front/src/views/content/libraries/Form.vue:19
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
 msgstr "Będziesz mógł udostępniać swoją bibliotekę innym, nie zważając na jej widoczność."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Za chwilę dodasz utwory do swojej biblioteki. Zanim kontynuujesz, upewnij się że:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "JesteÅ› obecnie zalogowany jako %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Możesz zaobserwować biblioteki innych użytkowników aby uzyskać dostęp do nowej muzyki. Publiczne biblioteki mogą być zaobserwowane natychmiast, a do zaobserwowania prywatnej biblioteki będziesz potrzebował zgody jej właściciela."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Możesz zaprosić znajomych i rodzinę na swoją instancję, aby mogli się cieszyć dodaną przez Ciebie muzyką"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Twój adres e-mail został potwierdzony, możesz używać usługi bez ograniczeń."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Możesz używać tego interfejsu aby utworzyć własne radio, które będzie odtwarzać utwory pasujące do Twoich kryteriów."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Możesz używać tego, aby cieszyć się muzyką i swoją listą odtwarzania w trybie offline, na przykład na smartfonie i tablecie."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Brak powiadomień do wyświetlenia!"
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Brak powiadomień do wyświetlenia!"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
-msgstr ""
+msgstr "Brak powiadomień do wyświetlenia!"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
+msgstr "Brak powiadomień do wyświetlenia!"
+
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
 msgstr ""
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Odtwarzasz radio"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr ""
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Musisz wybrać instancję aby kontynuować"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Zostaniesz wylogowany z tej sesji i musisz zalogować się nowym hasłem"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Będziesz musiał zmienić hasło na klientach używających tego hasła."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Utworzono listÄ™ odtwarzania"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Twoje powiadomienia"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Twoje ulubione"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "Twoja muzyka, po Twojemu"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Twoje powiadomienia"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Twoje hasło zostało pomyślnie zmienione."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Zaktualizowano ustawienia"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "Twoje hasło Subsonic zostanie zmienione na nowe, losowe i zostaniesz wylogowany z urządzeń korzystających ze starego hasła Subsonic"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Opis"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Kopiuj"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Album zawiera %{ count } utwór od %{ artist }"
+msgstr[1] "Album zawiera %{ count } utwory od %{ artist }"
+msgstr[2] "Album zawiera %{ count } utworów od %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "Dodano %{ count } utwór do kolejki"
+msgstr[1] "Dodano %{ count } utwory do kolejki"
+msgstr[2] "Dodano %{ count } utworów do kolejki"
diff --git a/front/locales/pt_BR/LC_MESSAGES/app.po b/front/locales/pt_BR/LC_MESSAGES/app.po
new file mode 100644
index 0000000000000000000000000000000000000000..5b02315fabd39257d1734874692d802fae47f3e5
--- /dev/null
+++ b/front/locales/pt_BR/LC_MESSAGES/app.po
@@ -0,0 +1,2938 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the front package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: front 0.1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-01-11 16:04+0100\n"
+"PO-Revision-Date: 2019-04-16 07:46+0000\n"
+"Last-Translator: Matroid <matroid@outlook.com.br>\n"
+"Language-Team: none\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 3.2.2\n"
+
+#: front/src/components/playlists/PlaylistModal.vue:9
+msgid "\"%{ title }\", by %{ artist }"
+msgstr "\"%{ title }\", por %{ artist }"
+
+#: front/src/components/Sidebar.vue:24
+msgid "(%{ index } of %{ length })"
+msgstr "(%{ index } de %{ length })"
+
+#: front/src/components/Sidebar.vue:22
+msgid "(empty)"
+msgstr "(vazio)"
+
+#: front/src/components/common/ActionTable.vue:57
+#: front/src/components/common/ActionTable.vue:66
+msgid "%{ count } on %{ total } selected"
+msgid_plural "%{ count } on %{ total } selected"
+msgstr[0] "%{ count } de %{ total } selecionado"
+msgstr[1] "%{ count } de %{ total } selecionados"
+
+#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
+#: front/src/views/content/libraries/Card.vue:39 src/views/content/remote/Card.vue:26
+msgid "%{ count } track"
+msgid_plural "%{ count } tracks"
+msgstr[0] "%{ count } faixa"
+msgstr[1] "%{ count } faixas"
+
+#: front/src/components/library/Artist.vue:13
+msgid "%{ count } track in %{ albumsCount } albums"
+msgid_plural "%{ count } tracks in %{ albumsCount } albums"
+msgstr[0] "%{ count } faixa em %{ albumsCount } álbuns"
+msgstr[1] "%{ count } faixas em %{ albumsCount } álbuns"
+
+#: front/src/components/library/radios/Builder.vue:80
+msgid "%{ count } track matching combined filters"
+msgid_plural "%{ count } tracks matching combined filters"
+msgstr[0] "%{ count } faixa encontrada com os filtros"
+msgstr[1] "%{ count } faixas encontradas com os filtros"
+
+#: front/src/components/audio/PlayButton.vue:180
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } faixa adicionada à fila"
+msgstr[1] "%{ count } faixas adicionadas à fila"
+
+#: front/src/components/playlists/Card.vue:18
+msgid "%{ count} track"
+msgid_plural "%{ count } tracks"
+msgstr[0] "%{ count } faixa"
+msgstr[1] "%{ count } faixas"
+
+#: front/src/views/content/libraries/Quota.vue:11
+msgid "%{ current } used on %{ max } allowed"
+msgstr "%{ current } usados de %{ max } permitidos"
+
+#: front/src/components/common/Duration.vue:2
+msgid "%{ hours } h %{ minutes } min"
+msgstr "%{ hours } h %{ minutes } min"
+
+#: front/src/components/common/Duration.vue:5
+msgid "%{ minutes } min"
+msgstr "%{ minutes } min"
+
+#: front/src/components/notifications/NotificationRow.vue:40
+msgid "%{ username } accepted your follow on library \"%{ library }\""
+msgstr ""
+"%{ username } aceitou seu pedido para seguir a biblioteca \"%{ library }\""
+
+#: front/src/components/notifications/NotificationRow.vue:39
+msgid "%{ username } followed your library \"%{ library }\""
+msgstr "%{ username } seguiu sua biblioteca \"%{ library }\""
+
+#: front/src/components/auth/Profile.vue:46
+msgid "%{ username }'s profile"
+msgstr "Perfil de %{ username }"
+
+#: front/src/components/Footer.vue:5
+msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+msgstr ""
+"<translate :translate-params=\"{instanceName: instanceHostname}\">Sobre "
+"%{instanceName}</translate>"
+
+#: front/src/components/audio/artist/Card.vue:41
+msgid "1 album"
+msgid_plural "%{ count } albums"
+msgstr[0] "1 álbum"
+msgstr[1] "%{ count } álbuns"
+
+#: front/src/components/favorites/List.vue:10
+msgid "1 favorite"
+msgid_plural "%{ count } favorites"
+msgstr[0] "1 favorito"
+msgstr[1] "%{ count } favoritos"
+
+#: front/src/components/library/FileUpload.vue:225
+#: front/src/components/library/FileUpload.vue:226
+msgid "A network error occured while uploading this file"
+msgstr "Um erro de rede ocorreu ao enviar este arquivo"
+
+#: front/src/components/About.vue:5
+msgid "About %{ instance }"
+msgstr "Sobre %{ instance }"
+
+#: front/src/components/Footer.vue:6
+msgid "About %{instanceName}"
+msgstr "Sobre %{instanceName}"
+
+#: front/src/components/Footer.vue:45
+msgid "About Funkwhale"
+msgstr "Sobre o Funkwhale"
+
+#: front/src/components/Footer.vue:10
+msgid "About page"
+msgstr "Sobre"
+
+#: front/src/components/About.vue:8 src/components/About.vue:64
+msgid "About this instance"
+msgstr "Sobre esta instância"
+
+#: front/src/views/content/libraries/Detail.vue:48
+msgid "Accept"
+msgstr "Aceitar"
+
+#: front/src/views/content/libraries/Detail.vue:40
+msgid "Accepted"
+msgstr "Aceito"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:111
+msgid "Access disabled"
+msgstr "Acesso desabilitado"
+
+#: front/src/components/Home.vue:106
+msgid "Access your music from a clean interface that focus on what really matters"
+msgstr ""
+"Ouça suas músicas em uma interface limpa voltada para o que realmente importa"
+
+#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:20
+msgid "Accessed date"
+msgstr "Data de acesso"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
+msgid "Account data"
+msgstr "Dados da conta"
+
+#: front/src/components/auth/Settings.vue:5
+msgid "Account settings"
+msgstr "Configurações da conta"
+
+#: front/src/components/auth/Settings.vue:264
+msgid "Account Settings"
+msgstr "Configurações de Conta"
+
+#: front/src/components/manage/users/UsersTable.vue:39
+msgid "Account status"
+msgstr "Situação da conta"
+
+#: front/src/views/auth/PasswordReset.vue:14
+msgid "Account's email"
+msgstr "Email da conta"
+
+#: front/src/views/admin/moderation/AccountsList.vue:3
+#: front/src/views/admin/moderation/AccountsList.vue:24
+#: front/src/views/admin/moderation/Base.vue:8
+msgid "Accounts"
+msgstr "Contas"
+
+#: front/src/views/content/libraries/Detail.vue:29
+msgid "Action"
+msgstr "Ação"
+
+#: front/src/components/common/ActionTable.vue:99
+msgid "Action %{ action } was launched successfully on %{ count } element"
+msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
+msgstr[0] "Ação %{ action } aplicada com sucesso em %{ count } elemento"
+msgstr[1] "Ação %{ action } aplicada com sucesso em %{ count } elementos"
+
+#: front/src/components/common/ActionTable.vue:21
+#: front/src/components/library/radios/Builder.vue:64
+msgid "Actions"
+msgstr "Ações"
+
+#: front/src/components/manage/users/UsersTable.vue:53
+msgid "Active"
+msgstr "Ativo"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:199
+#: front/src/views/admin/moderation/DomainsDetail.vue:144
+msgid "Activity"
+msgstr "Atividade"
+
+#: front/src/components/mixins/Translations.vue:7
+#: front/src/components/mixins/Translations.vue:8
+msgid "Activity visibility"
+msgstr "Visibilidade da atividade"
+
+#: front/src/views/admin/moderation/DomainsList.vue:18
+msgid "Add"
+msgstr "Adicionar"
+
+#: front/src/views/admin/moderation/DomainsList.vue:13
+msgid "Add a domain"
+msgstr "Adicionar domínio"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgid "Add a new moderation rule"
+msgstr "Adicionar nova regra de moderação"
+
+#: front/src/views/content/Home.vue:35
+msgid "Add and manage content"
+msgstr "Adicionar e administrar conteúdo"
+
+#: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+msgid "Add content"
+msgstr "Adicionar conteúdo"
+
+#: front/src/components/library/radios/Builder.vue:50
+msgid "Add filter"
+msgstr "Adicionar filtro"
+
+#: front/src/components/library/radios/Builder.vue:40
+msgid "Add filters to customize your radio"
+msgstr "Adicionar filtros para personalizar sua rádio"
+
+#: front/src/components/audio/PlayButton.vue:64
+msgid "Add to current queue"
+msgstr "Adicionar à fila atual"
+
+#: front/src/components/favorites/TrackFavoriteIcon.vue:4
+#: front/src/components/favorites/TrackFavoriteIcon.vue:28
+msgid "Add to favorites"
+msgstr "Adicionar aos favoritos"
+
+#: front/src/components/playlists/TrackPlaylistIcon.vue:6
+#: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgid "Add to playlist…"
+msgstr "Adicionar à lista…"
+
+#: front/src/components/audio/PlayButton.vue:14
+msgid "Add to queue"
+msgstr "Adicionar à fila"
+
+#: front/src/components/playlists/PlaylistModal.vue:116
+msgid "Add to this playlist"
+msgstr "Adicionar a esta lista"
+
+#: front/src/components/playlists/PlaylistModal.vue:54
+msgid "Add track"
+msgstr "Adicionar faixa"
+
+#: front/src/components/manage/users/UsersTable.vue:69
+msgid "Admin"
+msgstr "Administrador/a"
+
+#: front/src/components/Sidebar.vue:79
+msgid "Administration"
+msgstr "Administração"
+
+#: front/src/components/audio/SearchBar.vue:26 src/components/audio/track/Table.vue:8
+#: front/src/components/library/Album.vue:159
+#: front/src/components/manage/library/FilesTable.vue:39
+#: front/src/components/metadata/Search.vue:134
+#: front/src/views/content/libraries/FilesTable.vue:56
+msgid "Album"
+msgstr "Álbum"
+
+#: front/src/components/library/Album.vue:12
+msgid "Album containing %{ count } track, by %{ artist }"
+msgid_plural "Album containing %{ count } tracks, by %{ artist }"
+msgstr[0] "Álbum com %{ count } faixa, de %{ artist }"
+msgstr[1] "Álbum com %{ count } faixas, de %{ artist }"
+
+#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:25
+msgid "Album name"
+msgstr "Nome do álbum"
+
+#: front/src/components/library/Track.vue:27
+msgid "Album page"
+msgstr "Página do álbum"
+
+#: front/src/components/audio/Search.vue:19 src/components/instance/Stats.vue:48
+#: front/src/views/admin/moderation/AccountsDetail.vue:321
+#: front/src/views/admin/moderation/DomainsDetail.vue:257
+msgid "Albums"
+msgstr "Álbuns"
+
+#: front/src/components/library/Artist.vue:44
+msgid "Albums by this artist"
+msgstr "Álbuns deste artista"
+
+#: front/src/components/manage/users/InvitationsTable.vue:19
+#: front/src/views/content/libraries/FilesTable.vue:13
+msgid "All"
+msgstr "Todos"
+
+#: front/src/components/playlists/Editor.vue:13
+msgid "An error occured while saving your changes"
+msgstr "Um erro ocorreu ao salvar suas alterações"
+
+#: front/src/components/auth/Login.vue:10
+msgid "An unknown error happend, this can mean the server is down or cannot be reached"
+msgstr ""
+"Um erro desconhecido ocorreu; o servidor pode estar fora dou ar ou "
+"inacessível"
+
+#: front/src/components/notifications/NotificationRow.vue:62
+msgid "Approve"
+msgstr "Aprovar"
+
+#: front/src/components/auth/Logout.vue:5
+msgid "Are you sure you want to log out?"
+msgstr "Tem certeza que deseja sair?"
+
+#: front/src/components/audio/SearchBar.vue:25 src/components/audio/track/Table.vue:7
+#: front/src/components/library/Artist.vue:137
+#: front/src/components/manage/library/FilesTable.vue:38
+#: front/src/components/metadata/Search.vue:130
+#: front/src/views/content/libraries/FilesTable.vue:55
+msgid "Artist"
+msgstr "Artista"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+msgid "Artist name"
+msgstr "Nome do/a artista"
+
+#: front/src/components/library/Album.vue:22 src/components/library/Track.vue:33
+msgid "Artist page"
+msgstr "Página do/a artista"
+
+#: front/src/components/audio/Search.vue:65
+msgid "Artist, album, track…"
+msgstr "Artista, álbum, faixa…"
+
+#: front/src/components/audio/Search.vue:10 src/components/instance/Stats.vue:42
+#: front/src/components/library/Artists.vue:119 src/components/library/Library.vue:7
+#: front/src/views/admin/moderation/AccountsDetail.vue:313
+#: front/src/views/admin/moderation/DomainsDetail.vue:249
+msgid "Artists"
+msgstr "Artistas"
+
+#: front/src/components/favorites/List.vue:33 src/components/library/Artists.vue:25
+#: front/src/components/library/Radios.vue:44
+#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/manage/moderation/AccountsTable.vue:21
+#: front/src/components/manage/moderation/DomainsTable.vue:19
+#: front/src/components/manage/users/UsersTable.vue:19
+#: front/src/views/content/libraries/FilesTable.vue:31
+#: front/src/views/playlists/List.vue:27
+msgid "Ascending"
+msgstr "Crescente"
+
+#: front/src/views/auth/PasswordReset.vue:27
+msgid "Ask for a password reset"
+msgstr "Solicitar redefinição de senha"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgid "Audio content"
+msgstr "Conteúdo de áudio"
+
+#: front/src/components/ShortcutsModal.vue:55
+msgid "Audio player shortcuts"
+msgstr "Atalhos do reprodutor de som"
+
+#: front/src/components/playlists/PlaylistModal.vue:26
+msgid "Available playlists"
+msgstr "Listas disponíveis"
+
+#: front/src/components/auth/Settings.vue:34
+msgid "Avatar"
+msgstr "Imagem de perfil"
+
+#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordResetConfirm.vue:18
+msgid "Back to login"
+msgstr "Voltar à página de entrada"
+
+#: front/src/components/library/Track.vue:129
+#: front/src/components/manage/library/FilesTable.vue:42
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+msgid "Bitrate"
+msgstr "Taxa de bits"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:19
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgid "Block everything"
+msgstr "Bloquear tudo"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
+msgstr ""
+"Bloquear tudo desta conta ou domínio. Isso desabilitará a interação e "
+"eliminará conteúdos relacionados (envios, bibliotecas, seguidas, etc.)"
+
+#: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+msgid "Browse"
+msgstr "Explorar"
+
+#: front/src/components/Sidebar.vue:65
+msgid "Browse library"
+msgstr "Explorar biblioteca"
+
+#: front/src/components/library/Artists.vue:4
+msgid "Browsing artists"
+msgstr "Explorando artistas"
+
+#: front/src/views/playlists/List.vue:3
+msgid "Browsing playlists"
+msgstr "Explorando listas"
+
+#: front/src/components/library/Radios.vue:4
+msgid "Browsing radios"
+msgstr "Explorando rádios"
+
+#: front/src/components/library/radios/Builder.vue:5
+msgid "Builder"
+msgstr "Construtor"
+
+#: front/src/components/audio/album/Card.vue:13
+msgid "By %{ artist }"
+msgstr "De %{ artist }"
+
+#: front/src/views/content/remote/Card.vue:103
+msgid "By unfollowing this library, you loose access to its content."
+msgstr ""
+"Ao deixar de seguir esta biblioteca você perderá o acesso a seu conteúdo."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgid "Cached size"
+msgstr "Tamanho em cache"
+
+#: front/src/components/common/DangerousButton.vue:17
+#: front/src/components/library/Album.vue:58 src/components/library/Track.vue:76
+#: front/src/components/library/radios/Filter.vue:53
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:63
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: front/src/components/library/radios/Builder.vue:63
+msgid "Candidates"
+msgstr "Candidatos/as"
+
+#: front/src/components/auth/Settings.vue:76
+msgid "Cannot change your password"
+msgstr "Não é possível alterar a senha"
+
+#: front/src/components/library/FileUpload.vue:222
+#: front/src/components/library/FileUpload.vue:223
+msgid "Cannot upload this file, ensure it is not too big"
+msgstr ""
+"Não é possível enviar este arquivo; tenha certeza de que não é grande demais"
+
+#: front/src/components/Footer.vue:21
+msgid "Change language"
+msgstr "Alterar idioma"
+
+#: front/src/components/auth/Settings.vue:67
+msgid "Change my password"
+msgstr "Alterar minha senha"
+
+#: front/src/components/auth/Settings.vue:95
+msgid "Change password"
+msgstr "Alterar senha"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:4
+#: front/src/views/auth/PasswordResetConfirm.vue:62
+msgid "Change your password"
+msgstr "Alterar sua senha"
+
+#: front/src/components/auth/Settings.vue:96
+msgid "Change your password?"
+msgstr "Alterar sua senha?"
+
+#: front/src/components/playlists/Editor.vue:21
+msgid "Changes synced with server"
+msgstr "Alterações sincronizadas com o servidor"
+
+#: front/src/components/auth/Settings.vue:70
+msgid "Changing your password will also change your Subsonic API password if you have requested one."
+msgstr ""
+"A alteração de sua senha também modificará - caso a utilize - a senha da API "
+"Subsonic."
+
+#: front/src/components/auth/Settings.vue:98
+msgid "Changing your password will have the following consequences"
+msgstr "A alteração da senha terá as seguintes consequências"
+
+#: front/src/components/Footer.vue:40
+msgid "Chat room"
+msgstr "Sala de chat"
+
+#: front/src/App.vue:13
+msgid "Choose your instance"
+msgstr "Escolha sua instância"
+
+#: front/src/components/Home.vue:64
+msgid "Clean library"
+msgstr "Biblioteca limpa"
+
+#: front/src/components/manage/users/InvitationForm.vue:37
+msgid "Clear"
+msgstr "Limpar"
+
+#: front/src/components/playlists/Editor.vue:40
+#: front/src/components/playlists/Editor.vue:45
+msgid "Clear playlist"
+msgstr "Limpar lista"
+
+#: front/src/components/audio/Player.vue:363
+msgid "Clear your queue"
+msgstr "Limpar sua fila"
+
+#: front/src/components/Home.vue:44
+msgid "Click once, listen for hours using built-in radios"
+msgstr "Clique uma vez e ouça as rádios nativas por horas"
+
+#: front/src/components/library/FileUpload.vue:75
+msgid "Click to select files to upload or drag and drop files or directories"
+msgstr ""
+"Clique para selecionar arquivos para enviar ou arraste e solte arquivos ou "
+"pastas"
+
+#: front/src/components/ShortcutsModal.vue:20
+msgid "Close"
+msgstr "Fechar"
+
+#: front/src/components/manage/users/InvitationForm.vue:26
+#: front/src/components/manage/users/InvitationsTable.vue:42
+msgid "Code"
+msgstr "Código"
+
+#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/artist/Card.vue:33
+msgid "Collapse"
+msgstr "Esconder"
+
+#: front/src/components/library/radios/Builder.vue:62
+msgid "Config"
+msgstr "Configuração"
+
+#: front/src/components/common/DangerousButton.vue:21
+msgid "Confirm"
+msgstr "Confirmar"
+
+#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
+#: front/src/views/auth/EmailConfirm.vue:51
+msgid "Confirm your e-mail address"
+msgstr "Confirmar seu endereço de email"
+
+#: front/src/views/auth/EmailConfirm.vue:13
+msgid "Confirmation code"
+msgstr "Código de confirmação"
+
+#: front/src/components/common/ActionTable.vue:7
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "Conteúdo modificado; atualize a página para ver o conteúdo atual"
+
+#: front/src/components/Footer.vue:48
+msgid "Contribute"
+msgstr "Contribua"
+
+#: front/src/components/audio/EmbedWizard.vue:19
+#: front/src/components/common/CopyInput.vue:8
+msgid "Copy"
+msgstr "Copiar"
+
+#: front/src/components/playlists/Editor.vue:163
+msgid "Copy tracks from current queue to playlist"
+msgstr "Copiar faixas da fila atual para lista"
+
+#: front/src/components/audio/EmbedWizard.vue:21
+msgid "Copy/paste this code in your website HTML"
+msgstr "Copie e cole este código HTML em seu site"
+
+#: front/src/components/library/Track.vue:91
+msgid "Copyright"
+msgstr "Direitos autorais"
+
+#: front/src/views/auth/EmailConfirm.vue:7
+msgid "Could not confirm your e-mail address"
+msgstr "Não foi possível confirmar seu endereço de email"
+
+#: front/src/views/content/remote/ScanForm.vue:3
+msgid "Could not fetch remote library"
+msgstr "Não foi possível obter a biblioteca remota"
+
+#: front/src/views/content/libraries/FilesTable.vue:213
+msgid "Could not process this track, ensure it is tagged correctly"
+msgstr ""
+"Não foi possível processar esta faixa; verifique se ela possui as tags "
+"corretas"
+
+#: front/src/components/Home.vue:85
+msgid "Covers, lyrics, our goal is to have them all ;)"
+msgstr "Capas, letras, nosso objetivo é tudo isso! ;)"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgid "Create"
+msgstr "Criar"
+
+#: front/src/components/auth/Signup.vue:4
+msgid "Create a funkwhale account"
+msgstr "Criar conta funkwhale"
+
+#: front/src/views/content/libraries/Home.vue:14
+msgid "Create a new library"
+msgstr "Criar nova biblioteca"
+
+#: front/src/components/playlists/Form.vue:2
+msgid "Create a new playlist"
+msgstr "Criar nova lista"
+
+#: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+msgid "Create an account"
+msgstr "Criar uma conta"
+
+#: front/src/views/content/libraries/Form.vue:26
+msgid "Create library"
+msgstr "Criar biblioteca"
+
+#: front/src/components/auth/Signup.vue:51
+msgid "Create my account"
+msgstr "Criar minha conta"
+
+#: front/src/components/playlists/Form.vue:34
+msgid "Create playlist"
+msgstr "Criar lista"
+
+#: front/src/components/library/Radios.vue:23
+msgid "Create your own radio"
+msgstr "Criar sua própria rádio"
+
+#: front/src/components/manage/users/InvitationsTable.vue:40
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+msgid "Creation date"
+msgstr "Data de criação"
+
+#: front/src/components/auth/Settings.vue:54
+msgid "Current avatar"
+msgstr "Imagem de perfil atual"
+
+#: front/src/views/content/libraries/DetailArea.vue:4
+msgid "Current library"
+msgstr "Biblioteca atual"
+
+#: front/src/components/playlists/PlaylistModal.vue:8
+msgid "Current track"
+msgstr "Faixa atual"
+
+#: front/src/views/content/libraries/Quota.vue:2
+msgid "Current usage"
+msgstr "Uso atual"
+
+#: front/src/views/content/libraries/Detail.vue:27
+msgid "Date"
+msgstr "Data"
+
+#: front/src/components/ShortcutsModal.vue:75
+msgid "Decrease volume"
+msgstr "Diminuir volume"
+
+#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:61
+#: front/src/components/manage/users/InvitationsTable.vue:167
+#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/content/libraries/Form.vue:29 src/views/playlists/Detail.vue:33
+msgid "Delete"
+msgstr "Excluir"
+
+#: front/src/views/content/libraries/Form.vue:39
+msgid "Delete library"
+msgstr "Excluir biblioteca"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgid "Delete moderation rule"
+msgstr "Excluir regra de moderação"
+
+#: front/src/views/playlists/Detail.vue:38
+msgid "Delete playlist"
+msgstr "Excluir lista"
+
+#: front/src/views/radios/Detail.vue:28
+msgid "Delete radio"
+msgstr "Excluir rádio"
+
+#: front/src/views/content/libraries/Form.vue:31
+msgid "Delete this library?"
+msgstr "Excluir esta biblioteca?"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgid "Delete this moderation rule?"
+msgstr "Excluir esta regra de moderação?"
+
+#: front/src/components/favorites/List.vue:34 src/components/library/Artists.vue:26
+#: front/src/components/library/Radios.vue:47
+#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/manage/moderation/AccountsTable.vue:22
+#: front/src/components/manage/moderation/DomainsTable.vue:20
+#: front/src/components/manage/users/UsersTable.vue:20
+#: front/src/views/content/libraries/FilesTable.vue:32
+#: front/src/views/playlists/List.vue:28
+msgid "Descending"
+msgstr "Descendente"
+
+#: front/src/components/library/radios/Builder.vue:25
+#: front/src/views/content/libraries/Form.vue:14
+msgid "Description"
+msgstr "Descrição"
+
+#: front/src/views/content/libraries/Card.vue:47
+msgid "Detail"
+msgstr "Detalhe"
+
+#: front/src/views/content/remote/Card.vue:50
+msgid "Details"
+msgstr "Detalhes"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:455
+msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
+msgstr ""
+"Determine quanto conteúdo o usuário pode enviar. Deixe em branco para "
+"utilizar o valor padrão da instância."
+
+#: front/src/components/mixins/Translations.vue:8
+#: front/src/components/mixins/Translations.vue:9
+msgid "Determine the visibility level of your activity"
+msgstr "Determine o nível de visibilidade de sua atividade"
+
+#: front/src/components/auth/Settings.vue:104
+#: front/src/components/auth/SubsonicTokenForm.vue:52
+msgid "Disable access"
+msgstr "Desabilitar acesso"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgid "Disable Subsonic access"
+msgstr "Desabilitar acesso Subsonic"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgid "Disable Subsonic API access?"
+msgstr "Desabilitar acesso da API Subsonic?"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:18
+#: front/src/views/admin/moderation/AccountsDetail.vue:128
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgid "Disabled"
+msgstr "Desabilitado"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:14
+msgid "Discover how to use Funkwhale from other apps"
+msgstr "Aprenda como usar o Funkwhale em outros aplicativos"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:103
+msgid "Display name"
+msgstr "Nome de exibição"
+
+#: front/src/components/library/radios/Builder.vue:30
+msgid "Display publicly"
+msgstr "Mostrar publicamente"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
+msgstr ""
+"Não baixar nenhum arquivo de mídia (áudio, capa de álbum, imagem de "
+"exibição...) desta conta ou domínio. Esta ação também deletará o conteúdo já "
+"existente."
+
+#: front/src/components/playlists/Editor.vue:42
+msgid "Do you want to clear the playlist \"%{ playlist }\"?"
+msgstr "Você quer limpar a lista \"%{ playlist }\"?"
+
+#: front/src/components/common/DangerousButton.vue:7
+msgid "Do you want to confirm this action?"
+msgstr "Você deseja confirmar esta ação?"
+
+#: front/src/views/playlists/Detail.vue:35
+msgid "Do you want to delete the playlist \"%{ playlist }\"?"
+msgstr "Você deseja excluir a lista \"%{ playlist }\"?"
+
+#: front/src/views/radios/Detail.vue:26
+msgid "Do you want to delete the radio \"%{ radio }\"?"
+msgstr "Você deseja excluir a rádio \"%{ radio }\"?"
+
+#: front/src/components/common/ActionTable.vue:36
+msgid "Do you want to launch %{ action } on %{ count } element?"
+msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
+msgstr[0] "Você deseja executar %{ action } em %{ count } elemento?"
+msgstr[1] "Você deseja executar %{ action } em %{ count } elementos?"
+
+#: front/src/components/Sidebar.vue:107
+msgid "Do you want to restore your previous queue?"
+msgstr "Você deseja restaurar sua fila anterior?"
+
+#: front/src/components/Footer.vue:31
+msgid "Documentation"
+msgstr "Documentação"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:40
+#: front/src/components/mixins/Translations.vue:34
+#: front/src/views/admin/moderation/AccountsDetail.vue:93
+#: front/src/components/mixins/Translations.vue:35
+msgid "Domain"
+msgstr "Domínio"
+
+#: front/src/views/admin/moderation/Base.vue:5
+#: front/src/views/admin/moderation/DomainsList.vue:3
+#: front/src/views/admin/moderation/DomainsList.vue:48
+msgid "Domains"
+msgstr "Domínios"
+
+#: front/src/components/library/Track.vue:55
+msgid "Download"
+msgstr "Baixar"
+
+#: front/src/components/playlists/Editor.vue:49
+msgid "Drag and drop rows to reorder tracks in the playlist"
+msgstr "Arraste as colunas para reorganizar as faixas na lista"
+
+#: front/src/components/audio/track/Table.vue:9 src/components/library/Track.vue:111
+#: front/src/components/manage/library/FilesTable.vue:43
+#: front/src/components/mixins/Translations.vue:30
+#: front/src/views/content/libraries/FilesTable.vue:59
+#: front/src/components/mixins/Translations.vue:31
+msgid "Duration"
+msgstr "Duração"
+
+#: front/src/views/auth/EmailConfirm.vue:23
+msgid "E-mail address confirmed"
+msgstr "Endereço de email confirmado"
+
+#: front/src/components/Home.vue:93
+msgid "Easy to use"
+msgstr "Fácil de usar"
+
+#: front/src/views/content/libraries/Detail.vue:9
+msgid "Edit"
+msgstr "Editar"
+
+#: front/src/components/About.vue:21
+msgid "Edit instance info"
+msgstr "Editar informações da instância"
+
+#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
+msgid "Edit…"
+msgstr "Editar…"
+
+#: front/src/components/auth/Signup.vue:29
+#: front/src/components/manage/users/UsersTable.vue:38
+msgid "Email"
+msgstr "Email"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:111
+msgid "Email address"
+msgstr "Endereço de email"
+
+#: front/src/components/library/Album.vue:44 src/components/library/Track.vue:62
+msgid "Embed"
+msgstr "Incorporar"
+
+#: front/src/components/audio/EmbedWizard.vue:20
+msgid "Embed code"
+msgstr "Código para incorporação"
+
+#: front/src/components/library/Album.vue:48
+msgid "Embed this album on your website"
+msgstr "Incorpore este álbum em seu site"
+
+#: front/src/components/library/Track.vue:66
+msgid "Embed this track on your website"
+msgstr "Incorpore esta faixa em seu site"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgid "Emitted library follows"
+msgstr "Seguidas de biblioteca emitidas"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgid "Emitted messages"
+msgstr "Mensagens emitidas"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:8
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:17
+#: front/src/views/admin/moderation/AccountsDetail.vue:127
+#: front/src/views/admin/moderation/AccountsDetail.vue:131
+msgid "Enabled"
+msgstr "Habilitado"
+
+#: front/src/views/playlists/Detail.vue:29
+msgid "End edition"
+msgstr "Finalizar edição"
+
+#: front/src/views/content/remote/ScanForm.vue:50
+msgid "Enter a library URL"
+msgstr "Insira o endereço URL de uma biblioteca"
+
+#: front/src/components/library/Radios.vue:140
+msgid "Enter a radio name…"
+msgstr "Insira o nome de uma rádio…"
+
+#: front/src/components/library/Artists.vue:118
+msgid "Enter artist name…"
+msgstr "Insira o nome do/a artista…"
+
+#: front/src/views/playlists/List.vue:107
+msgid "Enter playlist name…"
+msgstr "Insira o nome da lista…"
+
+#: front/src/components/auth/Signup.vue:100
+msgid "Enter your email"
+msgstr "Insira seu email"
+
+#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+msgid "Enter your invitation code (case insensitive)"
+msgstr "Insira seu código de convite (não diferencia maiúsculas de minúsculas)"
+
+#: front/src/components/metadata/Search.vue:114
+msgid "Enter your search query…"
+msgstr "Entre sua busca…"
+
+#: front/src/components/auth/Signup.vue:99
+msgid "Enter your username"
+msgstr "Entre seu nome de usuário"
+
+#: front/src/components/auth/Login.vue:77
+msgid "Enter your username or email"
+msgstr "Entre seu nome de usuário ou email"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/views/content/libraries/Form.vue:4
+msgid "Error"
+msgstr "Erro"
+
+#: front/src/views/admin/Settings.vue:87
+msgid "Error reporting"
+msgstr "Relatos de erro"
+
+#: front/src/components/common/ActionTable.vue:92
+msgid "Error while applying action"
+msgstr "Erro ao executar ação"
+
+#: front/src/views/auth/PasswordReset.vue:7
+msgid "Error while asking for a password reset"
+msgstr "Erro ao solicitar redefinição de senha"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:7
+msgid "Error while changing your password"
+msgstr "Erro ao alterar sua senha"
+
+#: front/src/views/admin/moderation/DomainsList.vue:6
+msgid "Error while creating domain"
+msgstr "Erro ao criar domínio"
+
+#: front/src/components/manage/users/InvitationForm.vue:4
+msgid "Error while creating invitation"
+msgstr "Erro ao criar convite"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgid "Error while creating rule"
+msgstr "Erro ao criar regra"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:126
+msgid "Error while fetching node info"
+msgstr "Erro ao solicitar node info"
+
+#: front/src/components/admin/SettingsGroup.vue:5
+msgid "Error while saving settings"
+msgstr "Erro ao salvar configurações"
+
+#: front/src/views/content/libraries/FilesTable.vue:212
+msgid "Errored"
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:75
+msgid "Errored files"
+msgstr ""
+
+#: front/src/components/playlists/Form.vue:89
+msgid "Everyone"
+msgstr "Todo mundo"
+
+#: front/src/components/mixins/Translations.vue:11
+#: front/src/components/playlists/Form.vue:85 src/views/content/libraries/Form.vue:73
+#: front/src/components/mixins/Translations.vue:12
+msgid "Everyone on this instance"
+msgstr "Todo mundo nesta instância"
+
+#: front/src/views/content/libraries/Form.vue:74
+msgid "Everyone, across all instances"
+msgstr "Todo mundo, em todas as instâncias"
+
+#: front/src/components/library/radios/Builder.vue:61
+msgid "Exclude"
+msgstr "Excluir"
+
+#: front/src/components/manage/users/InvitationsTable.vue:41
+#: front/src/components/mixins/Translations.vue:22
+#: front/src/components/mixins/Translations.vue:23
+msgid "Expiration date"
+msgstr "Data de expiração"
+
+#: front/src/components/manage/users/InvitationsTable.vue:50
+msgid "Expired"
+msgstr "Expirado"
+
+#: front/src/components/manage/users/InvitationsTable.vue:21
+msgid "Expired/used"
+msgstr "Expirado/utilizado"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
+msgstr ""
+"Explique por que está aplicando esta regra. Dependendo da configuração de "
+"sua instância, a descrição te ajudará a se lembrar o motivo da ação e também "
+"será exposta publicamente para que os usuários possam saber quais regras de "
+"moderação estão ativas."
+
+#: front/src/views/content/libraries/FilesTable.vue:16
+msgid "Failed"
+msgstr "Falhou"
+
+#: front/src/views/content/remote/Card.vue:58
+msgid "Failed tracks:"
+msgstr "Faixas que falharam:"
+
+#: front/src/components/Sidebar.vue:66
+msgid "Favorites"
+msgstr "Favoritos"
+
+#: front/src/views/admin/Settings.vue:84
+msgid "Federation"
+msgstr "Federação"
+
+#: front/src/components/library/FileUpload.vue:84
+msgid "Filename"
+msgstr "Nome do arquivo"
+
+#: front/src/views/admin/library/Base.vue:5 src/views/admin/library/FilesList.vue:21
+msgid "Files"
+msgstr "Arquivos"
+
+#: front/src/components/library/radios/Builder.vue:60
+msgid "Filter name"
+msgstr "Nome do filtro"
+
+#: front/src/views/content/libraries/FilesTable.vue:17
+#: front/src/views/content/libraries/FilesTable.vue:216
+msgid "Finished"
+msgstr "Finalizado"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:42
+#: front/src/components/manage/moderation/DomainsTable.vue:41
+#: front/src/views/admin/moderation/AccountsDetail.vue:159
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgid "First seen"
+msgstr "Visto primeiro"
+
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+msgid "First seen date"
+msgstr "Data do primeiro acesso"
+
+#: front/src/views/content/remote/Card.vue:83
+msgid "Follow"
+msgstr "Seguir"
+
+#: front/src/views/content/Home.vue:16
+msgid "Follow remote libraries"
+msgstr "Seguir bibliotecas remotas"
+
+#: front/src/views/content/remote/Card.vue:88
+msgid "Follow request pending approval"
+msgstr "Solicitação de seguidor pendente"
+
+#: front/src/components/mixins/Translations.vue:38
+#: front/src/views/content/libraries/Detail.vue:7
+#: front/src/components/mixins/Translations.vue:39
+msgid "Followers"
+msgstr "Seguidores"
+
+#: front/src/views/content/remote/Card.vue:93
+msgid "Following"
+msgstr "Seguindo"
+
+#: front/src/components/library/Track.vue:17
+msgid "From album %{ album } by %{ artist }"
+msgstr "Do álbum %{ album } de %{ artist }"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgid "Funkwhale is compatible with other music players that support the Subsonic API."
+msgstr ""
+"O Funkwhale funciona em outros reprodutores de música compatíveis com a "
+"Subsonic API."
+
+#: front/src/components/Home.vue:95
+msgid "Funkwhale is dead simple to use."
+msgstr "O Funkwhale é muito fácil de usar."
+
+#: front/src/components/Home.vue:39
+msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
+msgstr ""
+"O Funkwhale foi feito para ser fácil ouvir as músicas que você curte ou "
+"conhecer novos/as artistas."
+
+#: front/src/components/Home.vue:116
+msgid "Funkwhale is free and gives you control on your music."
+msgstr "O Funkwhale é gratuito e te coloca no controle de suas músicas."
+
+#: front/src/components/Home.vue:66
+msgid "Funkwhale takes care of handling your music"
+msgstr "O Funkwhale cuida da organização de suas músicas"
+
+#: front/src/components/ShortcutsModal.vue:38
+msgid "General shortcuts"
+msgstr "Atalhos gerais"
+
+#: front/src/components/manage/users/InvitationForm.vue:16
+msgid "Get a new invitation"
+msgstr "Solicitar novo convite"
+
+#: front/src/components/Home.vue:13
+msgid "Get me to the library"
+msgstr "Me leve à biblioteca"
+
+#: front/src/components/Home.vue:76
+msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
+msgstr ""
+"Tenha metadados de qualidade sobre suas músicas graças ao <a href=\"%{ url }"
+"\" target=\"_blank\">MusicBrainz</a>"
+
+#: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgid "Get started"
+msgstr "Comece"
+
+#: front/src/components/Footer.vue:37
+msgid "Getting help"
+msgstr "Procurando ajuda"
+
+#: front/src/components/common/ActionTable.vue:34
+#: front/src/components/common/ActionTable.vue:54
+msgid "Go"
+msgstr "Ir"
+
+#: front/src/components/PageNotFound.vue:14
+msgid "Go to home page"
+msgstr "Ir à página inicial"
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgid "Hide account or domain content, except from followers."
+msgstr "Esconder conteúdo de conta ou domínio, exceto de seguidores."
+
+#: front/src/components/library/Home.vue:65
+msgid "Home"
+msgstr "Início"
+
+#: front/src/components/instance/Stats.vue:36
+msgid "Hours of music"
+msgstr "Horas de música"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:11
+msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
+msgstr ""
+"Entretanto, para acessar o Funkwhale a partir desses clientes você precisa "
+"de uma senha que pode ser configurada abaixo."
+
+#: front/src/views/auth/PasswordResetConfirm.vue:24
+msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
+msgstr ""
+"Se o endereço de email inserido anteriormente for válido e associado a uma "
+"conta de usuário, você receberá um email com as instruções de redefinição "
+"nos próximos minutos."
+
+#: front/src/components/manage/library/FilesTable.vue:40
+#, fuzzy
+msgid "Import date"
+msgstr "Importar data"
+
+#: front/src/components/Home.vue:71
+msgid "Import music from various platforms, such as YouTube or SoundCloud"
+msgstr "Importação de músicas de várias plataformas, como YouTube e SoundCloud"
+
+#: front/src/components/library/FileUpload.vue:51
+msgid "Import reference"
+msgstr "Importar referência"
+
+#: front/src/views/content/libraries/FilesTable.vue:11
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgid "Import status"
+msgstr "Importar status"
+
+#: front/src/views/content/libraries/FilesTable.vue:217
+msgid "Imported"
+msgstr "Importado"
+
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgid "Imported date"
+msgstr "Data importada"
+
+#: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgid "In favorites"
+msgstr "Nos favoritos"
+
+#: front/src/components/manage/users/UsersTable.vue:54
+msgid "Inactive"
+msgstr "Inativo"
+
+#: front/src/components/ShortcutsModal.vue:71
+msgid "Increase volume"
+msgstr "Aumentar volume"
+
+#: front/src/views/auth/PasswordReset.vue:53
+msgid "Input the email address binded to your account"
+msgstr "Insira o endereço de email associado a sua conta"
+
+#: front/src/components/playlists/Editor.vue:31
+msgid "Insert from queue (%{ count } track)"
+msgid_plural "Insert from queue (%{ count } tracks)"
+msgstr[0] "Inserir da fila (%{ count } faixa)"
+msgstr[1] "Inserir da fila (%{ count } faixas)"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgid "Instance data"
+msgstr "Dados da instância"
+
+#: front/src/views/admin/Settings.vue:80
+msgid "Instance information"
+msgstr "Informação da instância"
+
+#: front/src/components/library/Radios.vue:9
+msgid "Instance radios"
+msgstr "Rádios da instância"
+
+#: front/src/views/admin/Settings.vue:75
+msgid "Instance settings"
+msgstr "Configurações da instância"
+
+#: front/src/components/library/FileUpload.vue:229
+#: front/src/components/library/FileUpload.vue:230
+msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr ""
+"Formato de arquivo inválido. Certifique-se de estar enviando um arquivo de "
+"áudio. As extensões permitidas são %{ extensions }"
+
+#: front/src/components/auth/Signup.vue:42
+#: front/src/components/manage/users/InvitationForm.vue:11
+msgid "Invitation code"
+msgstr "Código de convite"
+
+#: front/src/components/auth/Signup.vue:43
+msgid "Invitation code (optional)"
+msgstr "Código de convite (opcional)"
+
+#: front/src/views/admin/users/Base.vue:8 src/views/admin/users/InvitationsList.vue:3
+#: front/src/views/admin/users/InvitationsList.vue:24
+msgid "Invitations"
+msgstr "Convites"
+
+#: front/src/components/Footer.vue:41
+msgid "Issue tracker"
+msgstr ""
+
+#: front/src/components/Home.vue:50
+msgid "Keep a track of your favorite songs"
+msgstr ""
+
+#: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgid "Keyboard shortcuts"
+msgstr "Atalhos de teclado"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgid "Known accounts"
+msgstr "Contas conhecidas"
+
+#: front/src/views/content/remote/Home.vue:14
+msgid "Known libraries"
+msgstr ""
+
+#: front/src/components/manage/users/UsersTable.vue:41
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/views/admin/moderation/AccountsDetail.vue:184
+#: front/src/components/mixins/Translations.vue:33
+msgid "Last activity"
+msgstr "Última atividade"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:167
+#: front/src/views/admin/moderation/DomainsDetail.vue:86
+msgid "Last checked"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:32
+msgid "Last modification"
+msgstr "Última modificação"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:43
+msgid "Last seen"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:19
+msgid "Last seen date"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:56
+msgid "Last update:"
+msgstr "Última atualização:"
+
+#: front/src/components/common/ActionTable.vue:47
+msgid "Launch"
+msgstr ""
+
+#: front/src/components/Home.vue:10
+msgid "Learn more about this instance"
+msgstr ""
+
+#: front/src/components/manage/users/InvitationForm.vue:58
+msgid "Leave empty for a random code"
+msgstr ""
+
+#: front/src/components/audio/EmbedWizard.vue:7
+msgid "Leave empty for a responsive widget"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:297
+#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/content/Base.vue:5
+msgid "Libraries"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:2
+msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
+msgstr ""
+
+#: front/src/components/instance/Stats.vue:30
+#: front/src/components/manage/users/UsersTable.vue:173
+#: front/src/views/admin/moderation/AccountsDetail.vue:464
+msgid "Library"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:109
+msgid "Library created"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:129
+msgid "Library deleted"
+msgstr ""
+
+#: front/src/views/admin/library/FilesList.vue:3
+msgid "Library files"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:106
+msgid "Library updated"
+msgstr ""
+
+#: front/src/components/library/Track.vue:100
+msgid "License"
+msgstr "Licença"
+
+#: front/src/views/content/libraries/Detail.vue:21
+msgid "Loading followers…"
+msgstr "Carregando seguidores…"
+
+#: front/src/views/content/libraries/Home.vue:3
+msgid "Loading Libraries…"
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:3
+#: front/src/views/content/libraries/Upload.vue:3
+msgid "Loading library data…"
+msgstr ""
+
+#: front/src/views/Notifications.vue:4
+msgid "Loading notifications…"
+msgstr "Carregando notificações…"
+
+#: front/src/views/content/remote/Home.vue:3
+msgid "Loading remote libraries..."
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:4
+msgid "Loading usage data…"
+msgstr ""
+
+#: front/src/components/favorites/List.vue:5
+msgid "Loading your favorites…"
+msgstr ""
+
+#: front/src/components/manage/moderation/AccountsTable.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:18
+msgid "Local account"
+msgstr "Conta local"
+
+#: front/src/components/auth/Login.vue:78
+msgid "Log In"
+msgstr "Entrar"
+
+#: front/src/components/auth/Login.vue:4
+msgid "Log in to your Funkwhale account"
+msgstr ""
+
+#: front/src/components/auth/Logout.vue:20
+msgid "Log Out"
+msgstr "Sair"
+
+#: front/src/components/Sidebar.vue:38
+msgid "Logged in as %{ username }"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+msgid "Login"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:119
+msgid "Login status"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:52
+msgid "Logout"
+msgstr "Sair"
+
+#: front/src/views/content/libraries/Home.vue:9
+msgid "Looks like you don't have a library, it's time to create one."
+msgstr ""
+
+#: front/src/components/audio/Player.vue:353 src/components/audio/Player.vue:354
+msgid "Looping disabled. Click to switch to single-track looping."
+msgstr ""
+
+#: front/src/components/audio/Player.vue:356 src/components/audio/Player.vue:357
+msgid "Looping on a single track. Click to switch to whole queue looping."
+msgstr ""
+
+#: front/src/components/audio/Player.vue:359 src/components/audio/Player.vue:360
+msgid "Looping on whole queue. Click to disable looping."
+msgstr ""
+
+#: front/src/components/library/Track.vue:150
+msgid "Lyrics"
+msgstr "Letra"
+
+#: front/src/components/Sidebar.vue:210
+msgid "Main menu"
+msgstr "Menu principal"
+
+#: front/src/views/admin/library/Base.vue:16
+msgid "Manage library"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:3
+msgid "Manage playlists"
+msgstr "Gerenciar listas de reprodução"
+
+#: front/src/views/admin/users/Base.vue:20
+msgid "Manage users"
+msgstr "Gerenciar usuários"
+
+#: front/src/views/playlists/List.vue:8
+msgid "Manage your playlists"
+msgstr ""
+
+#: front/src/views/Notifications.vue:17
+msgid "Mark all as read"
+msgstr ""
+
+#: front/src/components/notifications/NotificationRow.vue:44
+msgid "Mark as read"
+msgstr ""
+
+#: front/src/components/notifications/NotificationRow.vue:45
+msgid "Mark as unread"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#, fuzzy
+msgid "MB"
+msgstr "MB"
+
+#: front/src/components/audio/Player.vue:346
+msgid "Media player"
+msgstr "Reprodutor de mídia"
+
+#: front/src/components/Footer.vue:32
+msgid "Mobile and desktop apps"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:97 src/components/manage/users/UsersTable.vue:177
+#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/Base.vue:21
+msgid "Moderation"
+msgstr "Moderação"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgid "Moderation policies help you control how your instance interact with a given domain or account."
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:21
+msgid "Modification date"
+msgstr "Data de modificação"
+
+#: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+msgid "Music"
+msgstr "Música"
+
+#: front/src/components/audio/Player.vue:352
+msgid "Mute"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:34
+msgid "My account"
+msgstr "Minha conta"
+
+#: front/src/components/library/radios/Builder.vue:236
+msgid "My awesome description"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:70
+msgid "My awesome library"
+msgstr ""
+
+#: front/src/components/playlists/Form.vue:74
+msgid "My awesome playlist"
+msgstr ""
+
+#: front/src/components/library/radios/Builder.vue:235
+msgid "My awesome radio"
+msgstr ""
+
+#: front/src/views/content/libraries/Home.vue:6
+msgid "My libraries"
+msgstr ""
+
+#: front/src/components/audio/track/Row.vue:40 src/components/library/Track.vue:115
+#: front/src/components/library/Track.vue:124 src/components/library/Track.vue:133
+#: front/src/components/library/Track.vue:142
+#: front/src/components/manage/library/FilesTable.vue:63
+#: front/src/components/manage/library/FilesTable.vue:69
+#: front/src/components/manage/library/FilesTable.vue:75
+#: front/src/components/manage/library/FilesTable.vue:81
+#: front/src/components/manage/users/UsersTable.vue:61
+#: front/src/views/admin/moderation/AccountsDetail.vue:171
+#: front/src/views/admin/moderation/DomainsDetail.vue:90
+#: front/src/views/content/libraries/FilesTable.vue:92
+#: front/src/views/content/libraries/FilesTable.vue:98
+#: front/src/views/admin/moderation/DomainsDetail.vue:109
+#: front/src/views/admin/moderation/DomainsDetail.vue:117
+msgid "N/A"
+msgstr ""
+
+#: front/src/components/manage/moderation/AccountsTable.vue:39
+#: front/src/components/manage/moderation/DomainsTable.vue:38
+#: front/src/components/mixins/Translations.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:31
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+#: front/src/views/content/libraries/Form.vue:10
+#: front/src/components/mixins/Translations.vue:27
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/Settings.vue:88
+#: front/src/views/auth/PasswordResetConfirm.vue:14
+msgid "New password"
+msgstr "Nova senha"
+
+#: front/src/components/Sidebar.vue:160
+msgid "New tracks will be appended here automatically."
+msgstr ""
+
+#: front/src/components/audio/Player.vue:350
+msgid "Next track"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:119
+msgid "No"
+msgstr "Não"
+
+#: front/src/components/Home.vue:100
+msgid "No add-ons, no plugins : you only need a web library"
+msgstr ""
+
+#: front/src/components/audio/Search.vue:25
+msgid "No album matched your query"
+msgstr ""
+
+#: front/src/components/audio/Search.vue:16
+msgid "No artist matched your query"
+msgstr ""
+
+#: front/src/components/library/Track.vue:158
+msgid "No lyrics available for this track."
+msgstr ""
+
+#: front/src/components/federation/LibraryWidget.vue:6
+msgid "No matching library."
+msgstr ""
+
+#: front/src/views/Notifications.vue:26
+msgid "No notifications yet."
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:10
+#: front/src/components/playlists/Form.vue:81 src/views/content/libraries/Form.vue:72
+#: front/src/components/mixins/Translations.vue:11
+msgid "Nobody except me"
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:57
+msgid "Nobody is following this library"
+msgstr ""
+
+#: front/src/components/manage/users/InvitationsTable.vue:51
+msgid "Not used"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+msgid "Notifications"
+msgstr "Notificações"
+
+#: front/src/components/Footer.vue:47
+msgid "Official website"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:83
+msgid "Old password"
+msgstr "Senha antiga"
+
+#: front/src/components/manage/users/InvitationsTable.vue:20
+msgid "Open"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgid "Open profile"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgid "Open website"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgid "Or customize your rule"
+msgstr ""
+
+#: front/src/components/favorites/List.vue:31 src/components/library/Radios.vue:41
+#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/users/UsersTable.vue:17
+#: front/src/views/playlists/List.vue:25
+msgid "Order"
+msgstr ""
+
+#: front/src/components/favorites/List.vue:23 src/components/library/Artists.vue:15
+#: front/src/components/library/Radios.vue:33
+#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/manage/moderation/AccountsTable.vue:11
+#: front/src/components/manage/moderation/DomainsTable.vue:9
+#: front/src/components/manage/users/InvitationsTable.vue:9
+#: front/src/components/manage/users/UsersTable.vue:9
+#: front/src/views/content/libraries/FilesTable.vue:21
+#: front/src/views/playlists/List.vue:17
+msgid "Ordering"
+msgstr ""
+
+#: front/src/components/library/Artists.vue:23
+#: front/src/components/manage/moderation/AccountsTable.vue:19
+#: front/src/components/manage/moderation/DomainsTable.vue:17
+#: front/src/views/content/libraries/FilesTable.vue:29
+msgid "Ordering direction"
+msgstr ""
+
+#: front/src/components/manage/users/InvitationsTable.vue:38
+msgid "Owner"
+msgstr "Proprietário"
+
+#: front/src/components/PageNotFound.vue:33
+msgid "Page Not Found"
+msgstr "Página Não Encontrada"
+
+#: front/src/components/PageNotFound.vue:7
+msgid "Page not found!"
+msgstr "Página não encontrada!"
+
+#: front/src/components/Pagination.vue:39
+msgid "Pagination"
+msgstr "Paginação"
+
+#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+msgid "Password"
+msgstr "Senha"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:95
+msgid "Password updated"
+msgstr "Senha atualizada"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:28
+msgid "Password updated successfully"
+msgstr "Senha atualizada com sucesso"
+
+#: front/src/components/audio/Player.vue:349
+msgid "Pause track"
+msgstr ""
+
+#: front/src/components/ShortcutsModal.vue:59
+msgid "Pause/play the current track"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgid "Paused"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:106
+#: front/src/views/content/libraries/FilesTable.vue:14
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgid "Pending"
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:37
+msgid "Pending approval"
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:22
+msgid "Pending files"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:212
+msgid "Pending follow requests"
+msgstr ""
+
+#: front/src/components/manage/users/UsersTable.vue:42
+#: front/src/views/admin/moderation/AccountsDetail.vue:137
+msgid "Permissions"
+msgstr "Permissões"
+
+#: front/src/components/audio/PlayButton.vue:9 src/components/library/Track.vue:40
+msgid "Play"
+msgstr "Reproduzir"
+
+#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/artist/Card.vue:44 src/components/library/Album.vue:28
+#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+msgid "Play all"
+msgstr "Reproduzir tudo"
+
+#: front/src/components/library/Artist.vue:26
+msgid "Play all albums"
+msgstr "Reproduzir todos os álbuns"
+
+#: front/src/components/audio/PlayButton.vue:15
+#: front/src/components/audio/PlayButton.vue:65
+msgid "Play next"
+msgstr ""
+
+#: front/src/components/ShortcutsModal.vue:67
+msgid "Play next track"
+msgstr ""
+
+#: front/src/components/audio/PlayButton.vue:16
+#: front/src/components/audio/PlayButton.vue:63
+#: front/src/components/audio/PlayButton.vue:70
+msgid "Play now"
+msgstr ""
+
+#: front/src/components/ShortcutsModal.vue:63
+msgid "Play previous track"
+msgstr "Reproduzir faixa anterior"
+
+#: front/src/components/Sidebar.vue:211
+msgid "Play this track"
+msgstr "Reproduzir esta faixa"
+
+#: front/src/components/audio/Player.vue:348
+msgid "Play track"
+msgstr "Reproduzir faixa"
+
+#: front/src/views/playlists/Detail.vue:90
+msgid "Playlist"
+msgstr "Lista de reprodução"
+
+#: front/src/views/playlists/Detail.vue:12
+msgid "Playlist containing %{ count } track, by %{ username }"
+msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
+msgstr[0] ""
+msgstr[1] ""
+
+#: front/src/components/playlists/Form.vue:9
+msgid "Playlist created"
+msgstr "Lista de reprodução criada"
+
+#: front/src/components/playlists/Editor.vue:4
+msgid "Playlist editor"
+msgstr ""
+
+#: front/src/components/playlists/Form.vue:21
+msgid "Playlist name"
+msgstr "Nome da lista de reprodução"
+
+#: front/src/components/playlists/Form.vue:6
+msgid "Playlist updated"
+msgstr "Lista de reprodução atualizada"
+
+#: front/src/components/playlists/Form.vue:25
+msgid "Playlist visibility"
+msgstr "Visibilidade da lista de reprodução"
+
+#: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
+#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
+#: front/src/views/playlists/List.vue:106
+msgid "Playlists"
+msgstr "Listas de reprodução"
+
+#: front/src/components/Home.vue:56
+msgid "Playlists? We got them"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:79
+msgid "Please double-check your password is correct"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:9
+msgid "Please double-check your username/password couple is correct"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:46
+msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgid "Prevent account or domain from triggering notifications, except from followers."
+msgstr ""
+
+#: front/src/components/audio/EmbedWizard.vue:29
+msgid "Preview"
+msgstr "Prévia"
+
+#: front/src/components/audio/Player.vue:347
+msgid "Previous track"
+msgstr "Faixa anterior"
+
+#: front/src/views/content/remote/Card.vue:39
+msgid "Problem during scanning"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:58
+msgid "Proceed"
+msgstr ""
+
+#: front/src/views/auth/EmailConfirm.vue:26
+#: front/src/views/auth/PasswordResetConfirm.vue:31
+msgid "Proceed to login"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:17
+msgid "Processing"
+msgstr "Processando"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:188
+#: front/src/components/manage/moderation/DomainsTable.vue:168
+#: front/src/views/content/libraries/Quota.vue:36
+#: front/src/views/content/libraries/Quota.vue:39
+#: front/src/views/content/libraries/Quota.vue:62
+#: front/src/views/content/libraries/Quota.vue:65
+#: front/src/views/content/libraries/Quota.vue:88
+#: front/src/views/content/libraries/Quota.vue:91
+msgid "Purge"
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:89
+msgid "Purge errored files?"
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:37
+msgid "Purge pending files?"
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:63
+msgid "Purge skipped files?"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:20
+msgid "Queue"
+msgstr "Fila"
+
+#: front/src/components/audio/Player.vue:282
+msgid "Queue shuffled!"
+msgstr ""
+
+#: front/src/views/radios/Detail.vue:80
+msgid "Radio"
+msgstr "Rádio"
+
+#: front/src/components/library/radios/Builder.vue:233
+msgid "Radio Builder"
+msgstr ""
+
+#: front/src/components/library/radios/Builder.vue:15
+msgid "Radio created"
+msgstr ""
+
+#: front/src/components/library/radios/Builder.vue:21
+msgid "Radio name"
+msgstr ""
+
+#: front/src/components/library/radios/Builder.vue:12
+msgid "Radio updated"
+msgstr ""
+
+#: front/src/components/library/Library.vue:10 src/components/library/Radios.vue:141
+msgid "Radios"
+msgstr "Rádios"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:39
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgid "Reason"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgid "Received library follows"
+msgstr ""
+
+#: front/src/components/manage/moderation/DomainsTable.vue:40
+#: front/src/components/mixins/Translations.vue:36
+#: front/src/components/mixins/Translations.vue:37
+msgid "Received messages"
+msgstr "Mensagens recebidas"
+
+#: front/src/components/library/Home.vue:24
+msgid "Recently added"
+msgstr ""
+
+#: front/src/components/library/Home.vue:11
+msgid "Recently favorited"
+msgstr ""
+
+#: front/src/components/library/Home.vue:6
+msgid "Recently listened"
+msgstr ""
+
+#: front/src/views/content/remote/Home.vue:15
+msgid "Refresh"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:135
+msgid "Refresh node info"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:272
+msgid "Refresh table content"
+msgstr ""
+
+#: front/src/components/auth/Profile.vue:12
+msgid "Registered since %{ date }"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:9
+msgid "Registration are closed on this instance, you will need an invitation code to signup."
+msgstr ""
+
+#: front/src/components/manage/users/UsersTable.vue:71
+msgid "regular user"
+msgstr "usuário regular"
+
+#: front/src/views/content/libraries/Detail.vue:51
+msgid "Reject"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:32
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+msgid "Reject media"
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:43
+msgid "Rejected"
+msgstr ""
+
+#: front/src/views/content/libraries/FilesTable.vue:234
+msgid "Relaunch import"
+msgstr ""
+
+#: front/src/views/content/remote/Home.vue:6
+msgid "Remote libraries"
+msgstr ""
+
+#: front/src/views/content/remote/Home.vue:7
+msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
+msgstr ""
+
+#: front/src/components/library/radios/Filter.vue:59
+msgid "Remove"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:58
+msgid "Remove avatar"
+msgstr ""
+
+#: front/src/components/favorites/TrackFavoriteIcon.vue:26
+msgid "Remove from favorites"
+msgstr "Remover dos favoritos"
+
+#: front/src/views/content/libraries/Quota.vue:38
+msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:64
+msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:90
+msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+#: front/src/components/auth/SubsonicTokenForm.vue:37
+msgid "Request a new password"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgid "Request a new Subsonic API password?"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:43
+msgid "Request a password"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:52
+msgid "Reset your password"
+msgstr "Redefinir sua senha"
+
+#: front/src/components/favorites/List.vue:38 src/components/library/Artists.vue:30
+#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+msgid "Results per page"
+msgstr "Resultados por página"
+
+#: front/src/views/auth/EmailConfirm.vue:17
+msgid "Return to login"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgid "Rule"
+msgstr "Regra"
+
+#: front/src/components/admin/SettingsGroup.vue:63
+#: front/src/components/library/radios/Builder.vue:33
+msgid "Save"
+msgstr "Salvar"
+
+#: front/src/views/content/remote/Card.vue:165
+msgid "Scan launched"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:63
+msgid "Scan now"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:166
+msgid "Scan skipped (previous scan is too recent)"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:31
+msgid "Scan waiting"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgid "Scanned"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:47
+msgid "Scanned with errors"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:35
+msgid "Scanning… (%{ progress }%)"
+msgstr ""
+
+#: front/src/components/library/Artists.vue:10 src/components/library/Radios.vue:29
+#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/manage/moderation/AccountsTable.vue:5
+#: front/src/components/manage/moderation/DomainsTable.vue:5
+#: front/src/components/manage/users/InvitationsTable.vue:5
+#: front/src/components/manage/users/UsersTable.vue:5
+#: front/src/views/content/libraries/FilesTable.vue:5 src/views/playlists/List.vue:13
+msgid "Search"
+msgstr "Pesquisar"
+
+#: front/src/views/content/remote/ScanForm.vue:9
+msgid "Search a remote library"
+msgstr ""
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgid "Search by domain, username, bio..."
+msgstr ""
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgid "Search by name..."
+msgstr ""
+
+#: front/src/views/content/libraries/FilesTable.vue:201
+msgid "Search by title, artist, album…"
+msgstr ""
+
+#: front/src/components/manage/library/FilesTable.vue:176
+msgid "Search by title, artist, domain…"
+msgstr ""
+
+#: front/src/components/manage/users/InvitationsTable.vue:153
+msgid "Search by username, e-mail address, code…"
+msgstr ""
+
+#: front/src/components/manage/users/UsersTable.vue:163
+msgid "Search by username, e-mail address, name…"
+msgstr ""
+
+#: front/src/components/audio/SearchBar.vue:20
+msgid "Search for artists, albums, tracks…"
+msgstr ""
+
+#: front/src/components/audio/Search.vue:2
+msgid "Search for some music"
+msgstr ""
+
+#: front/src/components/library/Track.vue:162
+msgid "Search on lyrics.wikia.com"
+msgstr ""
+
+#: front/src/components/library/Album.vue:33 src/components/library/Artist.vue:31
+#: front/src/components/library/Track.vue:47
+msgid "Search on Wikipedia"
+msgstr ""
+
+#: front/src/components/library/Library.vue:32 src/views/admin/library/Base.vue:17
+#: front/src/views/admin/moderation/Base.vue:22 src/views/admin/users/Base.vue:21
+#: front/src/views/content/Base.vue:19
+msgid "Secondary menu"
+msgstr "Menu secundário"
+
+#: front/src/views/admin/Settings.vue:15
+msgid "Sections"
+msgstr "Seções"
+
+#: front/src/components/library/radios/Builder.vue:45
+msgid "Select a filter"
+msgstr "Selecione um filtro"
+
+#: front/src/components/common/ActionTable.vue:77
+msgid "Select all %{ total } elements"
+msgid_plural "Select all %{ total } elements"
+msgstr[0] ""
+msgstr[1] ""
+
+#: front/src/components/common/ActionTable.vue:86
+msgid "Select only current page"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/manage/users/UsersTable.vue:181
+#: front/src/views/admin/moderation/AccountsDetail.vue:472
+msgid "Settings"
+msgstr "Configurações"
+
+#: front/src/components/auth/Settings.vue:10
+msgid "Settings updated"
+msgstr "Configurações atualizadas"
+
+#: front/src/components/admin/SettingsGroup.vue:11
+msgid "Settings updated successfully."
+msgstr ""
+
+#: front/src/components/manage/users/InvitationForm.vue:27
+msgid "Share link"
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:15
+msgid "Share this link with other users so they can request access to your library."
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:14
+#: front/src/views/content/remote/Card.vue:73
+msgid "Sharing link"
+msgstr ""
+
+#: front/src/components/audio/album/Card.vue:40
+msgid "Show %{ count } more track"
+msgid_plural "Show %{ count } more tracks"
+msgstr[0] ""
+msgstr[1] ""
+
+#: front/src/components/audio/artist/Card.vue:30
+msgid "Show 1 more album"
+msgid_plural "Show %{ count } more albums"
+msgstr[0] ""
+msgstr[1] ""
+
+#: front/src/components/ShortcutsModal.vue:42
+msgid "Show available keyboard shortcuts"
+msgstr ""
+
+#: front/src/views/Notifications.vue:10
+msgid "Show read notifications"
+msgstr ""
+
+#: front/src/components/forms/PasswordInput.vue:25
+msgid "Show/hide password"
+msgstr ""
+
+#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/moderation/AccountsTable.vue:88
+#: front/src/components/manage/moderation/DomainsTable.vue:74
+#: front/src/components/manage/users/InvitationsTable.vue:76
+#: front/src/components/manage/users/UsersTable.vue:87
+#: front/src/views/content/libraries/FilesTable.vue:114
+msgid "Showing results %{ start }-%{ end } on %{ total }"
+msgstr "Mostrando resultados %{ start }-%{ end } de %{ total }"
+
+#: front/src/components/ShortcutsModal.vue:83
+msgid "Shuffle queue"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:362
+msgid "Shuffle your queue"
+msgstr "Embaralhar sua fila"
+
+#: front/src/components/auth/Signup.vue:95
+msgid "Sign Up"
+msgstr "Registrar"
+
+#: front/src/components/manage/users/UsersTable.vue:40
+msgid "Sign-up"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:31
+#: front/src/views/admin/moderation/AccountsDetail.vue:176
+#: front/src/components/mixins/Translations.vue:32
+msgid "Sign-up date"
+msgstr "Data de registro"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+msgid "Silence activity"
+msgstr "Silenciar atividade"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+msgid "Silence notifications"
+msgstr "Silenciar notificações"
+
+#: front/src/components/library/FileUpload.vue:85
+#: front/src/components/library/Track.vue:120
+#: front/src/components/manage/library/FilesTable.vue:44
+#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:29
+msgid "Size"
+msgstr "Tamanho"
+
+#: front/src/views/content/libraries/FilesTable.vue:15
+#: front/src/views/content/libraries/FilesTable.vue:204
+msgid "Skipped"
+msgstr ""
+
+#: front/src/views/content/libraries/Quota.vue:49
+msgid "Skipped files"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+msgid "Software"
+msgstr "Software"
+
+#: front/src/components/Footer.vue:49
+msgid "Source code"
+msgstr "Código fonte"
+
+#: front/src/components/auth/Profile.vue:23
+#: front/src/components/manage/users/UsersTable.vue:70
+msgid "Staff member"
+msgstr ""
+
+#: front/src/components/radios/Button.vue:4
+msgid "Start"
+msgstr ""
+
+#: front/src/views/admin/Settings.vue:86
+msgid "Statistics"
+msgstr "Estatísticas"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:454
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:358
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:86
+#: front/src/components/manage/users/InvitationsTable.vue:17
+#: front/src/components/manage/users/InvitationsTable.vue:39
+#: front/src/components/manage/users/UsersTable.vue:43
+#: front/src/views/admin/moderation/DomainsDetail.vue:123
+#: front/src/views/content/libraries/Detail.vue:28
+msgid "Status"
+msgstr ""
+
+#: front/src/components/radios/Button.vue:3
+msgid "Stop"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:161
+msgid "Stop radio"
+msgstr "Parar rádio"
+
+#: front/src/App.vue:22
+msgid "Submit"
+msgstr "Enviar"
+
+#: front/src/views/admin/Settings.vue:85
+#, fuzzy
+msgid "Subsonic"
+msgstr "Subsonic"
+
+#: front/src/components/auth/SubsonicTokenForm.vue:2
+msgid "Subsonic API password"
+msgstr "Senha da API Subsonic"
+
+#: front/src/App.vue:26
+msgid "Suggested choices"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:3
+msgid "Summary"
+msgstr ""
+
+#: front/src/components/Footer.vue:39
+msgid "Support forum"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:78
+msgid "Supported extensions: %{ extensions }"
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:9
+msgid "Syncing changes to server…"
+msgstr ""
+
+#: front/src/components/common/CopyInput.vue:3
+msgid "Text copied to clipboard!"
+msgstr "Texto copiado para a área de transferência!"
+
+#: front/src/components/Home.vue:26
+msgid "That's simple: we loved Grooveshark and we want to build something even better."
+msgstr ""
+
+#: front/src/components/Footer.vue:53
+msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:34
+msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:39
+msgid "The music files you are uploading are tagged properly:"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:67
+msgid "The next track will play automatically in a few seconds..."
+msgstr "A próxima faixa será reproduzida automaticamente em alguns segundos..."
+
+#: front/src/components/Home.vue:121
+msgid "The plaform is free and open-source, you can install it and modify it without worries"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:4
+msgid "The Subsonic API is not available on this Funkwhale instance."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:43
+msgid "The uploaded music files are in OGG, Flac or MP3 format"
+msgstr ""
+
+#: front/src/views/content/Home.vue:4
+msgid "There are various ways to grab new content and make it available here."
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgid "This action is irreversible."
+msgstr "Esta ação é irreversível."
+
+#: front/src/components/library/Album.vue:91
+msgid "This album is present in the following libraries:"
+msgstr ""
+
+#: front/src/components/library/Artist.vue:63
+msgid "This artist is present in the following libraries:"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgid "This domain is subject to specific moderation rules"
+msgstr "Este domínio está sujeito a regras específicas de moderação"
+
+#: front/src/views/content/Home.vue:9
+msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr ""
+
+#: front/src/components/auth/Profile.vue:16
+msgid "This is you!"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:71
+msgid "This library contains my personal music, I hope you like it."
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:131
+msgid "This library is private and your approval from its owner is needed to access its content"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:132
+msgid "This library is public and you can access its content freely"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:45
+msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:52
+msgid "This reference will be used to group imported files together."
+msgstr ""
+
+#: front/src/components/audio/PlayButton.vue:73
+msgid "This track is not available in any library you have access to"
+msgstr ""
+
+#: front/src/components/library/Track.vue:171
+msgid "This track is present in the following libraries:"
+msgstr ""
+
+#: front/src/views/playlists/Detail.vue:37
+msgid "This will completely delete this playlist and cannot be undone."
+msgstr ""
+
+#: front/src/views/radios/Detail.vue:27
+msgid "This will completely delete this radio and cannot be undone."
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgid "This will completely disable access to the Subsonic API using from account."
+msgstr ""
+
+#: front/src/App.vue:129 src/components/Footer.vue:72
+msgid "This will erase your local data and disconnect you, do you want to continue?"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+msgid "This will log you out from existing devices that use the current password."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:44
+msgid "This will remove all tracks from this playlist and cannot be undone."
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:6
+#: front/src/components/manage/library/FilesTable.vue:37
+#: front/src/components/mixins/Translations.vue:27
+#: front/src/views/content/libraries/FilesTable.vue:54
+#: front/src/components/mixins/Translations.vue:28
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/ShortcutsModal.vue:79
+msgid "Toggle queue looping"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgid "Total size"
+msgstr "Tamanho total"
+
+#: front/src/views/content/libraries/Card.vue:61
+msgid "Total size of the files in this library"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:113
+msgid "Total users"
+msgstr ""
+
+#: front/src/components/audio/SearchBar.vue:27 src/components/library/Track.vue:262
+#: front/src/components/metadata/Search.vue:138
+msgid "Track"
+msgstr ""
+
+#: front/src/views/content/libraries/FilesTable.vue:205
+msgid "Track already present in one of your libraries"
+msgstr ""
+
+#: front/src/components/library/Track.vue:85
+msgid "Track information"
+msgstr ""
+
+#: front/src/components/library/radios/Filter.vue:44
+msgid "Track matching filter"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:24
+msgid "Track name"
+msgstr ""
+
+#: front/src/views/content/libraries/FilesTable.vue:209
+msgid "Track uploaded, but not processed by the server yet"
+msgstr ""
+
+#: front/src/components/instance/Stats.vue:54
+msgid "tracks"
+msgstr ""
+
+#: front/src/components/library/Album.vue:81
+#: front/src/components/playlists/PlaylistModal.vue:33
+#: front/src/views/admin/moderation/AccountsDetail.vue:329
+#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
+#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+msgid "Tracks"
+msgstr ""
+
+#: front/src/components/library/Artist.vue:54
+msgid "Tracks by this artist"
+msgstr ""
+
+#: front/src/components/instance/Stats.vue:25
+msgid "Tracks favorited"
+msgstr ""
+
+#: front/src/components/instance/Stats.vue:19
+msgid "tracks listened"
+msgstr ""
+
+#: front/src/components/library/Track.vue:138
+#: front/src/components/manage/library/FilesTable.vue:41
+#: front/src/views/admin/moderation/AccountsDetail.vue:151
+msgid "Type"
+msgstr "Tipo"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:44
+#: front/src/components/manage/moderation/DomainsTable.vue:42
+msgid "Under moderation rule"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:100 src/views/content/remote/Card.vue:105
+msgid "Unfollow"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:101
+msgid "Unfollow this library?"
+msgstr ""
+
+#: front/src/components/About.vue:15
+msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+msgstr ""
+
+#: front/src/components/Home.vue:37
+msgid "Unlimited music"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:351
+msgid "Unmute"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgid "Update"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:50
+msgid "Update avatar"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:25
+msgid "Update library"
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+msgid "Update moderation rule"
+msgstr ""
+
+#: front/src/components/playlists/Form.vue:33
+msgid "Update playlist"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:27
+msgid "Update settings"
+msgstr ""
+
+#: front/src/views/auth/PasswordResetConfirm.vue:21
+msgid "Update your password"
+msgstr ""
+
+#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/DetailArea.vue:24
+msgid "Upload"
+msgstr "Enviar"
+
+#: front/src/components/auth/Settings.vue:45
+msgid "Upload a new avatar"
+msgstr ""
+
+#: front/src/views/content/Home.vue:6
+msgid "Upload audio content"
+msgstr ""
+
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgid "Upload date"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:219
+#: front/src/components/library/FileUpload.vue:220
+msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr ""
+
+#: front/src/views/content/Home.vue:7
+msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:31
+msgid "Upload new tracks"
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:269
+msgid "Upload quota"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:228
+msgid "Upload timeout, please try again"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:100
+msgid "Uploaded"
+msgstr "Enviado"
+
+#: front/src/components/library/FileUpload.vue:5
+msgid "Uploading"
+msgstr "Enviando"
+
+#: front/src/components/library/FileUpload.vue:103
+msgid "Uploading…"
+msgstr "Enviando…"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:41
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:305
+#: front/src/views/admin/moderation/DomainsDetail.vue:241
+#: front/src/components/mixins/Translations.vue:38
+msgid "Uploads"
+msgstr "Envios"
+
+#: front/src/components/Footer.vue:16
+msgid "Use another instance"
+msgstr ""
+
+#: front/src/views/auth/PasswordReset.vue:12
+msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
+msgstr ""
+
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
+msgstr ""
+
+#: front/src/components/manage/users/InvitationsTable.vue:49
+msgid "Used"
+msgstr ""
+
+#: front/src/views/content/libraries/Detail.vue:26
+msgid "User"
+msgstr "Usuário"
+
+#: front/src/components/instance/Stats.vue:5
+msgid "User activity"
+msgstr "Atividade de usuário"
+
+#: front/src/components/library/Album.vue:88 src/components/library/Artist.vue:60
+#: front/src/components/library/Track.vue:168
+msgid "User libraries"
+msgstr ""
+
+#: front/src/components/library/Radios.vue:20
+msgid "User radios"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:19
+#: front/src/components/manage/users/UsersTable.vue:37
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/views/admin/moderation/AccountsDetail.vue:85
+#: front/src/components/mixins/Translations.vue:34
+msgid "Username"
+msgstr "Nome de usuário"
+
+#: front/src/components/auth/Login.vue:15
+msgid "Username or email"
+msgstr "Nome de usuário ou email"
+
+#: front/src/components/instance/Stats.vue:13
+msgid "users"
+msgstr "usuários"
+
+#: front/src/components/Sidebar.vue:91
+#: front/src/components/manage/moderation/DomainsTable.vue:39
+#: front/src/components/mixins/Translations.vue:35 src/views/admin/Settings.vue:81
+#: front/src/views/admin/users/Base.vue:5 src/views/admin/users/UsersList.vue:3
+#: front/src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:36
+msgid "Users"
+msgstr "Usuários"
+
+#: front/src/components/Footer.vue:29
+msgid "Using Funkwhale"
+msgstr "Usando Funkwhale"
+
+#: front/src/components/Footer.vue:13
+msgid "Version %{version}"
+msgstr "Versão %{version}"
+
+#: front/src/views/content/libraries/Quota.vue:29
+#: front/src/views/content/libraries/Quota.vue:56
+#: front/src/views/content/libraries/Quota.vue:82
+msgid "View files"
+msgstr ""
+
+#: front/src/components/library/Album.vue:37 src/components/library/Artist.vue:35
+#: front/src/components/library/Track.vue:51
+#: front/src/components/metadata/ArtistCard.vue:49
+#: front/src/components/metadata/ReleaseCard.vue:53
+msgid "View on MusicBrainz"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:18
+msgid "Visibility"
+msgstr "Visibilidade"
+
+#: front/src/views/content/libraries/Card.vue:59
+msgid "Visibility: everyone on this instance"
+msgstr "Visibilidade: todos nesta instância"
+
+#: front/src/views/content/libraries/Card.vue:60
+msgid "Visibility: everyone, including other instances"
+msgstr "Visibilidade: todos, incluindo outras instâncias"
+
+#: front/src/views/content/libraries/Card.vue:58
+msgid "Visibility: nobody except me"
+msgstr ""
+
+#: front/src/components/library/Album.vue:67
+msgid "Volume %{ number }"
+msgstr "Volume %{ number }"
+
+#: front/src/components/playlists/PlaylistModal.vue:20
+msgid "We cannot add the track to a playlist"
+msgstr ""
+
+#: front/src/components/playlists/Form.vue:14
+msgid "We cannot create the playlist"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+msgid "We cannot create your account"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:64
+msgid "We cannot load this track"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:7
+msgid "We cannot log you in"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:38
+msgid "We cannot save your avatar"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:14
+msgid "We cannot save your settings"
+msgstr ""
+
+#: front/src/components/Home.vue:127
+msgid "We do not track you or bother you with ads"
+msgstr ""
+
+#: front/src/components/library/Track.vue:95
+msgid "We don't have any copyright information for this track"
+msgstr ""
+
+#: front/src/components/library/Track.vue:106
+msgid "We don't have any licensing information for this track"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:40
+msgid "We recommend using Picard for that purpose."
+msgstr ""
+
+#: front/src/components/Home.vue:7
+msgid "We think listening to music should be simple."
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+msgid "We're sorry, the page you asked for does not exist:"
+msgstr ""
+
+#: front/src/components/Home.vue:153
+msgid "Welcome"
+msgstr ""
+
+#: front/src/components/Home.vue:5
+msgid "Welcome on Funkwhale"
+msgstr ""
+
+#: front/src/components/Home.vue:24
+msgid "Why funkwhale?"
+msgstr ""
+
+#: front/src/components/audio/EmbedWizard.vue:13
+msgid "Widget height"
+msgstr ""
+
+#: front/src/components/audio/EmbedWizard.vue:6
+msgid "Widget width"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:118
+#: front/src/components/manage/moderation/AccountsTable.vue:72
+#: front/src/components/manage/moderation/DomainsTable.vue:58
+msgid "Yes"
+msgstr "Sim"
+
+#: front/src/components/auth/Logout.vue:8
+msgid "Yes, log me out!"
+msgstr ""
+
+#: front/src/views/content/libraries/Form.vue:19
+msgid "You are able to share your library with other people, regardless of its visibility."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:33
+msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
+msgstr ""
+
+#: front/src/components/auth/Logout.vue:7
+msgid "You are currently logged in as %{ username }"
+msgstr ""
+
+#: front/src/views/content/Home.vue:17
+msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
+msgstr ""
+
+#: front/src/components/Home.vue:133
+msgid "You can invite friends and family to your instance so they can enjoy your music"
+msgstr ""
+
+#: front/src/views/auth/EmailConfirm.vue:24
+msgid "You can now use the service without limitations."
+msgstr ""
+
+#: front/src/components/library/radios/Builder.vue:7
+msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:8
+msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
+msgstr ""
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:46
+msgid "You don't have any rule in place for this account."
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgid "You don't have any rule in place for this domain."
+msgstr ""
+
+#: front/src/components/Sidebar.vue:158
+msgid "You have a radio playing"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:71
+msgid "You may have a connectivity issue."
+msgstr ""
+
+#: front/src/App.vue:17
+msgid "You need to select an instance in order to continue"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:100
+msgid "You will be logged out from this session and have to log in with the new one"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:71
+msgid "You will have to update your password on your clients that use this password."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:112
+msgid "Your Favorites"
+msgstr ""
+
+#: front/src/components/Home.vue:114
+msgid "Your music, your way"
+msgstr ""
+
+#: front/src/views/Notifications.vue:7
+msgid "Your notifications"
+msgstr "Suas notificações"
+
+#: front/src/views/auth/PasswordResetConfirm.vue:29
+msgid "Your password has been updated successfully."
+msgstr "Sua senha foi atualizada com sucesso."
+
+#: front/src/components/auth/Settings.vue:101
+msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
+msgstr ""
diff --git a/front/locales/pt_PT/LC_MESSAGES/app.po b/front/locales/pt_PT/LC_MESSAGES/app.po
index 221a833c43f42505b907efe49f3c99d656837ce1..1f7ab2acdc32b41d2e338f7d429131284a7b65cf 100644
--- a/front/locales/pt_PT/LC_MESSAGES/app.po
+++ b/front/locales/pt_PT/LC_MESSAGES/app.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 1.0.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 15:55+0100\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
 "PO-Revision-Date: 2019-01-18 21:50+0000\n"
 "Last-Translator: troll <my_name_is_troll@protonmail.com>\n"
 "Language-Team: none\n"
@@ -19,1875 +19,3253 @@ msgstr ""
 "X-Generator: Weblate 3.2.2\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\", de %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } de %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(vazio)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
+#, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Logar na sua conta Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "%{ count } em %{ total } selecionado"
 msgstr[1] "%{ count } em %{ total } selecionados"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } pista"
 msgstr[1] "%{ count } pistas"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+#, fuzzy
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } tema em %{ albumsCount } álbuns"
 msgstr[1] "%{ count } temas em %{ albumsCount } álbuns"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } pista corresponde aos filtros selecionados"
 msgstr[1] "%{ count } pistas correspondem aos filtros selecionados"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "%{ count } pista foi adicionada à sua fila"
-msgstr[1] "%{ count } pistas foram adicionadas à sua fila"
-
 #: front/src/components/playlists/Card.vue:18
+#, fuzzy
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} pista"
 msgstr[1] "%{ count } pistas"
 
 #: front/src/views/content/libraries/Quota.vue:11
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ current } utilizado em %{ max } permitido"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } h %{ minutes } min"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } min"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
 msgstr "%{ username } aceitou seu seguimento na biblioteca \"%{ library }\""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr "%{ username } seguiu a sua biblioteca \"%{ library }\""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr "%{ username } seguiu a sua biblioteca \"%{ library }\""
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "%{ username } perfil"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
-"<translate :translate-params=\"{instanceName: instanceHostname}\">Sobre "
-"%{instanceName}</translate>"
 
 #: front/src/components/audio/artist/Card.vue:41
+#, fuzzy
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 álbum"
 msgstr[1] "%{ count } álbums"
 
 #: front/src/components/favorites/List.vue:10
+#, fuzzy
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 preferida"
 msgstr[1] "%{ count } preferidas"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+#, fuzzy
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Biblioteca limpa"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "Ocorreu um erro durante o upload deste ficheiro"
 
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "Ocorreu um erro ao salvar suas mudanças"
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "Sobre %{ instance }"
 
 #: front/src/components/Footer.vue:6
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "Sobre %{instanceName}"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "Sobre Funkwhale"
 
 #: front/src/components/Footer.vue:10
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Sobre a página"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "Sobre esta instância"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Aceitar"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Aceitado"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Acesso desativado"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Selecione um filtro"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Acesso desativado"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Adicionar aos favoritos"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
 msgstr ""
-"Aceda à sua música a partir de uma interface limpa que se concentra no que "
-"realmente importa"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Suas notificações"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Adicionar à Playlist…"
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Acesso desativado"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
+msgstr "Aceda à sua música a partir de uma interface limpa que se concentra no que realmente importa"
+
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr "Data de acesso"
+msgstr "Acesso desativado"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Contas"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Contas"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Dados da conta"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Configurações da conta"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Configurações da Conta"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Status da conta"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Email da conta"
 
 #: front/src/views/admin/moderation/AccountsList.vue:3
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
+#, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Contas"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Açao"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "A ação %{ action } foi lançada com sucesso em %{ count } item"
 msgstr[1] "A ação %{ action } foi lançada com sucesso em %{ count } itens"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Ações"
 
 #: front/src/components/manage/users/UsersTable.vue:53
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Ativo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Atividade"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Visibilidade da atividade"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr "Adicionar"
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr "Adicionar um domínio"
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+#, fuzzy
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr "Criar uma nova regra de moderação"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
 msgstr "Criar uma nova regra de moderação"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Adicionar e gerenciar conteúdo"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Adicionar conteúdo"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Adicionar um filtro"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Adicione filtros para personalizar seu rádio"
 
-#: front/src/components/audio/PlayButton.vue:64
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Adicionar à fila atual"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Adicionar aos favoritos"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Adicionar à Playlist…"
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Adicionar à fila"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Adicionar a esta playlist"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Adicionar música"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Admin"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Administração"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Álbum"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Álbum contendo %{ count } pista, por %{ artist }"
-msgstr[1] "Álbum contendo %{ count } pistas, por %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Álbum"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Álbuns deste artista"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "Nome do álbum"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Página do álbum"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Nome do álbum"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Álbuns"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Álbuns deste artista"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Tudo"
 
+#: front/src/components/common/ActionTable.vue:59
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "%{ count } em %{ total } selecionado"
+msgstr[1] "%{ count } em %{ total } selecionados"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "Ocorreu um erro ao salvar suas mudanças"
 
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "Ocorreu um erro ao salvar suas mudanças"
+
+#: front/src/components/federation/FetchButton.vue:41
+#, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "Ocorreu um erro ao salvar suas mudanças"
+
 #: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Um erro desconhecido aconteceu, isso pode significar que o servidor está inoperante ou não pode ser alcançado"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Açao"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr "Aprovar"
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+#, fuzzy
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr "Aprovar"
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Tem certeza que deseja sair?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Artista"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Artista"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Nome do artista"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Página do artista"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Nome do artista"
 
 #: front/src/components/audio/Search.vue:65
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Artista, álbum, música…"
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Artistas"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Artistas"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "Ascendente"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Peça uma redefinição de senha"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Conteúdo áudio"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr "Atalhos do leitor de áudio"
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Playlists disponíveis"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Avatar"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Volte ao login"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Atualizar configurações"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Bitrate"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr "Bloquear tudo"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
-msgstr ""
-"Bloquear tudo a partir desta conta ou domínio. Isso evitará qualquer "
-"interação com a entidade e eliminará conteúdo relacionado (uploads, "
-"bibliotecas, segue, etc.)"
+msgstr "Bloquear tudo a partir desta conta ou domínio. Isso evitará qualquer interação com a entidade e eliminará conteúdo relacionado (uploads, bibliotecas, segue, etc.)"
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Procurar"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Navegar pela biblioteca"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Procure radios"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Procurando artistas"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Procure playlists"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Procure radios"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Construtor"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "Por %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
-msgstr ""
-"Ao deixar de seguir esta biblioteca, você perderá o acesso ao seu conteúdo."
-
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+msgstr "Ao deixar de seguir esta biblioteca, você perderá o acesso ao seu conteúdo."
+
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr "Tamanho em cache"
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Cancelar"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Candidatos"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Não é possível alterar sua senha"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
-msgstr ""
-"Não é possível carregar este arquivo, assegure-se de que não é muito grande"
+msgstr "Não é possível carregar este arquivo, assegure-se de que não é muito grande"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Mudar idioma"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Mudar minha senha"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Mudar senha"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Mude sua senha"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Mude sua senha?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Modificações sincronizadas com o servidor"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Mudar sua senha também muda sua senha da API Subsonic se você tiver solicitado uma."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "Alterar sua senha terá as seguintes consequências"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr "Sala de bate-papo"
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Escolha sua instância"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Biblioteca limpa"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Claro"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Claro"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Limpar playlist"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Limpar sua fila"
 
 #: front/src/components/Home.vue:44
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Clique uma vez, ouça por horas usando rádios"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Clique para selecionar arquivos para carregar ou arrastar e soltar arquivos ou diretórios"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr "Fechar"
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+#, fuzzy
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr "Fechar"
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Código"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Colapso"
 
-#: front/src/components/library/radios/Builder.vue:62
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Configuração"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Confirme"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Confirme seu email"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Código de confirmação"
 
-#: front/src/components/common/ActionTable.vue:7
-msgid "Content have been updated, click refresh to see up-to-date content"
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Selecione um filtro"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Selecione um filtro"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
 msgstr ""
-"O conteúdo foi atualizado, clique em atualizar para ver o conteúdo atualizado"
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
+msgid "Content have been updated, click refresh to see up-to-date content"
+msgstr "O conteúdo foi atualizado, clique em atualizar para ver o conteúdo atualizado"
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr "Contribuir"
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Cópia"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
 msgstr "Copiar músicas da fila atual para a playlist"
 
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
+
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr "Copie/colar este código no seu website HTML"
 
-#: front/src/components/library/Track.vue:91
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Direitos Autorais"
 
 #: front/src/views/auth/EmailConfirm.vue:7
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Não foi possível confirmar o seu e-mail"
 
 #: front/src/views/content/remote/ScanForm.vue:3
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Não foi possível buscar a biblioteca remota"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr ""
-"Não foi possível processar esta pista, certifique-se de que está "
-"correctamente etiquetada"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Capas, letras, nosso objetivo é tê-los todos ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Criar"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Crie uma conta funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Crie uma nova playlist"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Crie uma nova playlist"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Criar uma nova biblioteca"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Crie uma nova playlist"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Crie a sua conta"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Crie uma playlist"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Criar biblioteca"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Criar a minha conta"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Crie uma playlist"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Crie seu próprio rádio"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Data de criação"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Avatar atual"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Biblioteca atual"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Música atual"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Uso atual"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Data"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Informação da música"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr "Diminuir o volume"
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Suprimir"
 
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Suprimir Playlist"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Excluir biblioteca"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Eliminar regra de moderação"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Suprimir Playlist"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Suprimir radio"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Excluir esta biblioteca?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Excluir esta biblioteca?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Excluir esta biblioteca?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Eliminar esta regra de moderação?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
-#: front/src/components/manage/moderation/AccountsTable.vue:22
-#: front/src/components/manage/moderation/DomainsTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Eliminar esta regra de moderação?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Excluir esta biblioteca?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
+#: front/src/components/manage/moderation/AccountsTable.vue:22
+#: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "Descendente"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Descrição"
 
-#: front/src/views/content/libraries/Card.vue:47
-msgid "Detail"
-msgstr "Detalhe"
+#: front/src/views/admin/library/LibraryDetail.vue:123
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Descrição"
 
-#: front/src/views/content/remote/Card.vue:50
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Detalhes"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Determine quanto conteúdo o usuário pode enviar. Deixe em branco para usar o valor padrão da instância."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Determinar o nível de visibilidade de sua atividade"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Desativar acesso"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Desativar o acesso a Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Desativar o acesso o API Subsonic?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Desativado"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Descubra como usar o Funkwhale em outros aplicativos"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Mostrar nome"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Exibir publicamente"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
-msgstr ""
-"Não faça o download de nenhum arquivo de mídia (áudio, capa do álbum, avatar "
-"da conta ...) dessa conta ou domínio. Isso também limpará o conteúdo "
-"existente."
+msgstr "Não faça o download de nenhum arquivo de mídia (áudio, capa do álbum, avatar da conta ...) dessa conta ou domínio. Isso também limpará o conteúdo existente."
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Você quer limpar a playlist \"%{ playlist }\"?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Você quer confirmar esta ação?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Você deseja excluir a playlist \"%{ playlist }\"?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Você deseja excluir a radio \"%{ radio }\"?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Você deseja excluir a radio \"%{ radio }\"?"
+
+#: front/src/components/common/ActionTable.vue:37
+#, fuzzy
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Deseja lançar %{ action } no %{ count } elemento?"
 msgstr[1] "Deseja lançar %{ action } nos %{ count } elementos?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Você quer restaurar sua fila anterior?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Documentação"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr "Dominio"
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+#, fuzzy
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr "Domínios"
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Descarregar"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Arraste e solte as linhas para reordenar as músicas da playlist"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Duração"
 
 #: front/src/views/auth/EmailConfirm.vue:23
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "E-mail confirmado"
 
-#: front/src/components/Home.vue:93
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Fácil de usar"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
+msgid "Edit"
+msgstr "Editar"
+
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
 msgid "Edit"
 msgstr "Editar"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Erro ao aplicar a ação"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Editar informações da instância"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
-msgid "Edit…"
-msgstr "Modificar…"
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Atualizar a regra de moderação"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Jogar esta pista"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Jogar esta pista"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Jogar esta pista"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Editar"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
+msgstr "Editar"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Email"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Endereço de e-mail"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr "Incorporar"
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr "Código de incorporação"
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr "Incorpore este álbum no seu website"
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+#, fuzzy
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr "Incorpore esta pista no seu website"
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr "Incorpore esta pista no seu website"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr "A biblioteca emitida segue"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr "Mensagens emitidas"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+msgctxt "*/*/*"
 msgid "Enabled"
 msgstr "Ativado"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Finalizar edição"
 
 #: front/src/views/content/remote/ScanForm.vue:50
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Insira um URL de biblioteca"
 
-#: front/src/components/library/Radios.vue:140
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Indicar um nome de rádio …"
 
-#: front/src/components/library/Artists.vue:118
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Indicar um nome de artista …"
 
 #: front/src/views/playlists/List.vue:107
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Indicar um nome de playlist…"
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+#, fuzzy
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr "Insira o endereço de e-mail associado à sua conta"
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Insira seu email"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Indicar seu código de convite (não diferencia maiúsculas de minúsculas)"
 
 #: front/src/components/metadata/Search.vue:114
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Insira sua consulta de pesquisa …"
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Indicar seu nome de usuário"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Indicar seu nome de usuário ou email"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Erro"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Relatório de erros"
+
 #: front/src/views/admin/Settings.vue:87
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
 msgstr "Relatório de erros"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Errado"
+
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Erro ao aplicar a ação"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Erro ao solicitar uma redefinição de senha"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Erro ao aplicar a ação"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Erro ao alterar sua senha"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Erro na criação do domínio"
 
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Erro na criação da regra"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Erro ao criar convite"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Erro na criação da regra"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Erro ao criar convite"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Erro ao buscar informações do nó"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Erro ao salvar configurações"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Erro ao salvar configurações"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
+#, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Erro ao salvar configurações"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Errado"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Arquivos errados"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Todo o mundo"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Todos nessa instância"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
+#, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Todos, em todas as instâncias"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Excluir"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Data de vencimento"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Expirado"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Expirado / usados"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
-msgstr ""
-"Explique porque está a aplicar esta política. Dependendo da configuração da "
-"sua instância, isso o ajudará a lembrar por que você agiu nessa conta ou "
-"domínio e poderá ser exibido publicamente para ajudar os usuários a entender "
-"quais regras de moderação estão em vigor."
+msgstr "Explique porque está a aplicar esta política. Dependendo da configuração da sua instância, isso o ajudará a lembrar por que você agiu nessa conta ou domínio e poderá ser exibido publicamente para ajudar os usuários a entender quais regras de moderação estão em vigor."
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
 msgstr "Falhou"
 
-#: front/src/views/content/remote/Card.vue:58
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Pistas falhadas:"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Pistas falhadas:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Favoritas"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Favoritas"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Federação"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Federação"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Nome do ficheiro"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Ficheiros"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Nome do filtro"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Acabado"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
 msgstr "Visto pela primeira vez"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Data da primeira vista"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Segue"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Siga as bibliotecas remotas"
 
-#: front/src/views/content/remote/Card.vue:88
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Solicitação de seguir pendente"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Seguidores"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Seguidores"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
 msgstr "Seguir"
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Do álbum %{ album } por %{ artist }"
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Segue"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Desativar acesso"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "O Funkwhale é compatível com outros players de música que suportam a API Subsonic."
 
-#: front/src/components/Home.vue:95
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale é muito simples de usar."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "O Funkwhale foi projetado para facilitar a escuta da música que você gosta ou descobrir novos artistas."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "O Funkwhale é gratuito e permite controlar sua música."
 
 #: front/src/components/Home.vue:66
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale cuida da sua música"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr "Atalhos gerais"
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Receba um novo convite"
 
 #: front/src/components/Home.vue:13
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Me leve para a biblioteca"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "Obtenha metadados de qualidade sobre sua música graças ao <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Começar"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Obter ajuda"
+
 #: front/src/components/Footer.vue:37
+#, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "Obter ajuda"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr "Vá"
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Vá para a página inicial"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Procurando artistas"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr "Ocultar conta ou conteúdo de domínio, exceto de seguidores."
 
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Adicionar conteúdo"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr ""
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Casa"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Horas de música"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "No entanto, acessar o Funkwhale desses clientes requer uma senha separada que você pode definir abaixo."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Se o endereço de e-mail fornecido na etapa anterior for válido e vinculado a uma conta de usuário, você deverá receber um e-mail com instruções de redefinição nos próximos minutos."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Data de importação"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Importe músicas de várias plataformas, como o YouTube ou o SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Status de Importação"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr "Referência de importação"
 
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Import status"
+msgstr "Status de Importação"
+
+#: front/src/components/manage/library/UploadsTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/views/content/libraries/FilesTable.vue:59
+#, fuzzy
+msgctxt "Content/Library/*/Noun"
 msgid "Import status"
 msgstr "Status de Importação"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Importado"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Data de importação"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
+#, fuzzy
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Adicionado recentemente"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "Nos favoritos"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Inativo"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr "Aumentar o volume"
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr "Insira o endereço de e-mail associado à sua conta"
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Inserir da fila (%{ count } música)"
 msgstr[1] "Inserir da fila (%{ count } músicas)"
 
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Dados da instância"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Dados da instância"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Informação da instância"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Rádios da instância"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Configurações da instância"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Dados da instância"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
+msgstr "Tipo de ficheiro inválido, certifique-se de que está a carregar um ficheiro de áudio. As extensões de arquivo suportadas são %{ extensions }"
+
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
 msgstr ""
-"Tipo de ficheiro inválido, certifique-se de que está a carregar um ficheiro "
-"de áudio. As extensões de arquivo suportadas são %{ extensions }"
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Código de Convite"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Código de convite (opcional)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Convites"
 
 #: front/src/components/Footer.vue:41
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Rastreador de problemas"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr "Guardar suas músicas favoritas"
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr "Atalhos do teclado"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Contas conhecidas"
 
 #: front/src/views/content/remote/Home.vue:14
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Bibliotecas conhecidas"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Ultima atividade"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
 msgstr "Última verificação"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Última modificação"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
 msgstr "Visto pela última vez"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Data da última vista"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Última atualização:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Lançamento"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Saiba mais sobre esta instância"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Deixar vazio para um código aleatório"
 
 #: front/src/components/audio/EmbedWizard.vue:7
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Deixe vazio para um widget responsivo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Libraries"
+msgstr "Bibliotecas"
+
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Libraries"
 msgstr "Bibliotecas"
 
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Biblioteca atualizada"
+
 #: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
 msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
 msgstr "As bibliotecas ajudam você a organizar e compartilhar suas coleções de músicas. Você pode enviar sua própria coleção de músicas para o Funkwhale e compartilhá-la com seus amigos e familiares."
 
-#: front/src/components/instance/Stats.vue:30
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Biblioteca"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Biblioteca criada"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Biblioteca atualizada"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Biblioteca suprimida"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "Ficheiros da biblioteca"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Biblioteca atualizada"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr "Licença"
 
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
+#, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Carregando seguidores…"
+
 #: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Carregando seguidores…"
 
 #: front/src/views/content/libraries/Home.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Carregando bibliotecas…"
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Carregando dados da biblioteca…"
 
-#: front/src/views/Notifications.vue:4
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Carregando notificações…"
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
 msgstr "Carregando bibliotecas remotas..."
 
 #: front/src/views/content/libraries/Quota.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Carregando dados de uso…"
 
 #: front/src/components/favorites/List.vue:5
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Carregando seus favoritos …"
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
+#, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Conta local"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Autenticação"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Logar na sua conta Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Sair"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Conectado como %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Entrar"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Status do login"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Sair"
 
 #: front/src/views/content/libraries/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
 msgstr "Parece que você ainda não tem biblioteca, é hora de criar uma."
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Looping desativado. Clique para alternar para um loop de musica única."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
 msgstr "Looping em uma única música. Clique para alternar para todo o loop da fila."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
 msgstr "Looping na fila inteira. Clique para desativar o loop."
 
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Letras"
-
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr "Menu principal"
 
-#: front/src/views/admin/library/Base.vue:16
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Gerenciar biblioteca"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Gerenciar playlists"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Gerenciar usuários"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Gerenciar suas playlists"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Marque tudo como lido"
 
-#: front/src/components/notifications/NotificationRow.vue:44
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Marcar como lido"
 
-#: front/src/components/notifications/NotificationRow.vue:45
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Marcar como não lido"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "MB"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr "Leitor de mídia"
 
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Registrado desde %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr "Aplicativos móveis e de computador"
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
+#, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Moderação"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
-msgstr ""
-"As políticas de moderação ajudam a controlar como sua instância interage com "
-"um determinado domínio ou conta."
+msgstr "As políticas de moderação ajudam a controlar como sua instância interage com um determinado domínio ou conta."
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Data de modificação"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Data de modificação"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Música"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Mudo"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Ultima atividade"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Suas notificações"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Minha conta"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Minha descrição incrível"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Minha biblioteca incrível"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "Minha playlist incrível"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Meu rádio incrível"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Minhas bibliotecas"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr ""
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Nome"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Nome"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Nova senha"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Novas músicas serão adicionadas automaticamente aqui."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Música seguinte"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Não"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr "Sem add-ons, sem plugins: você só precisa de uma biblioteca da Web"
 
 #: front/src/components/audio/Search.vue:25
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Nenhum álbum correspondeu à sua consulta"
 
 #: front/src/components/audio/Search.vue:16
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Nenhum artista correspondeu à sua consulta"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "Nenhuma letra disponível para esta música."
 
+#: front/src/components/library/TrackDetail.vue:25
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "Não temos nenhuma informação de licença para esta pista"
+
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Nenhuma biblioteca correspondente."
 
-#: front/src/views/Notifications.vue:26
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
 msgstr "Ainda não há notificações."
 
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr ""
+
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Ninguém, exceto eu"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Ninguém está seguindo esta biblioteca"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Não usado"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Notificações"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Notificações"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Website oficial"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Senha Antiga"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Aberto"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Atualizar a regra de moderação"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr "Abrir o perfil"
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Ver no MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr "Abrir o perfil"
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr "Abrir o perfil"
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Abrir o website"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "Ou personalize sua regra"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Ordenar"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Ordenar"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Direção de ordenar"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Proprietário"
 
 #: front/src/components/PageNotFound.vue:33
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Página não encontrada"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Página não encontrada!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr "Paginação"
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Palavra-passe"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Senha atualizada"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Senha atualizada com sucesso"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Parar música"
 
 #: front/src/components/ShortcutsModal.vue:59
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
 msgstr "Pausa/leitura da pista actual"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr "Pausa"
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "Pendente"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Aprovação pendente"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Ficheiros pendentes"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
 msgstr "Solicitações pendentes"
 
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Ficheiros pendentes"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Ficheiros pendentes"
+
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Permissões"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Permissões"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
 msgstr "Jogar"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Jogar tudo"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Jogar todos os álbuns"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Jogar seguinte"
 
 #: front/src/components/ShortcutsModal.vue:67
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Jogar pista seguinte"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Jogue agora"
 
 #: front/src/components/ShortcutsModal.vue:63
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Jogar pista anterior"
 
-#: front/src/components/Sidebar.vue:211
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Jogar esta pista"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Jogar mũsica"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr "Jogar"
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Playlist"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Playlist contendo%{ count } música, por %{ username }"
 msgstr[1] "Playlist contendo %{ count } músicas, por %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Playlist criada"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Editor de playlist"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Nome da playlist"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Playlist atualizada"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Visibilidade da playlist"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Playlists"
+msgstr "Playlists"
+
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Playlists"
 msgstr "Playlists"
 
 #: front/src/components/Home.vue:56
+#, fuzzy
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
-msgstr ""
+msgstr "Playlist criada"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Por favor, verifique novamente se sua senha está correta"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Por favor, verifique se o seu nome de usuário e senha estão corretos"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF ou JPG. No máximo 2MB. Será reduzido para 400x400px."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Paginação"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
-msgstr ""
-"Evite que uma conta ou domínio acione notificações, exceto de seguidores."
+msgstr "Evite que uma conta ou domínio acione notificações, exceto de seguidores."
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr "Pré-visualização"
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Música anterior"
 
-#: front/src/views/content/remote/Card.vue:39
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Erro durante a análise"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Prosseguir"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
 msgstr "Continuar com o login"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Em tratamento"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr "Abrir o perfil"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1896,1096 +3274,1975 @@ msgstr "Em tratamento"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Purga"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Limpar arquivos com erros?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Remover arquivos pendentes?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Limpar arquivos ignorados?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Fila"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "Fila embaralhada!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Rádio"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Construtor de rádio"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Rádio criado"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Nome do rádio"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Rádio atualizado"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Rádios"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Rádios"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr "Motivo"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
-msgstr ""
+msgstr "A biblioteca emitida segue"
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+#, fuzzy
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr "Mensagens recebidas"
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Adicionado recentemente"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Adicionado recentemente"
 
 #: front/src/components/library/Home.vue:11
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Recentemente adicionado aos favoritos"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Escutado recentemente"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Atualizar"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Atualizar"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr "Atualizar informações do nó"
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "Atualizar informações do nó"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr "Atualizar o conteúdo da tabela"
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Registrado desde %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "As inscrições estão fechadas nesta instância, você precisará de um código de convite para inscrição."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "usuário regular"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Rejeitar"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Rejeitar mídia"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Rejeitado"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Reinicie a importação"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Data da última vista"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Bibliotecas Remotas"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Bibliotecas remotas são de propriedade de outros usuários na rede. Você pode acessá-los desde que sejam públicos ou tenha acesso."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Remover"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Remover avatar"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Remover avatar"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Remover dos favoritos"
 
 #: front/src/views/content/libraries/Quota.vue:38
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
-"Remove as pistas carregadas mas ainda a serem processadas completamente, "
-"adicionando os dados correspondentes à sua quota."
+msgstr "Remove as pistas carregadas mas ainda a serem processadas completamente, adicionando os dados correspondentes à sua quota."
 
 #: front/src/views/content/libraries/Quota.vue:64
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
-"Remove as pistas carregadas ignoradas durante os processos de importação "
-"completamente, adicionando os dados correspondentes à sua quota."
+msgstr "Remove as pistas carregadas ignoradas durante os processos de importação completamente, adicionando os dados correspondentes à sua quota."
 
 #: front/src/views/content/libraries/Quota.vue:90
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
-msgstr ""
-"Remove as pistas carregadas que não puderam ser processadas completamente "
-"pelo servidor, adicionando os dados correspondentes à sua quota."
+msgstr "Remove as pistas carregadas que não puderam ser processadas completamente pelo servidor, adicionando os dados correspondentes à sua quota."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Solicite uma nova senha"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Solicitar uma nova senha da Subsonic API?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Solicite uma senha"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Redefinir sua senha"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Reinicie a importação"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Resultados por página"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Voltar ao login"
 
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Ver ficheiros"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr "Regra"
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Salvar"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Análise iniciada"
 
-#: front/src/views/content/remote/Card.vue:63
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Scanar agora"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "Ascendente"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Análise ignorada (a análise anterior é muito recente)"
 
-#: front/src/views/content/remote/Card.vue:31
-msgid "Scan waiting"
-msgstr "Scan em espera"
-
-#: front/src/views/content/remote/Card.vue:43
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Analisado"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Analisado com erros"
 
-#: front/src/views/content/remote/Card.vue:35
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr ""
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Buscar"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Pesquisar uma biblioteca remota"
 
+#: front/src/components/manage/library/EditsCardList.vue:211
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Pesquisa por título, artista, domínio…"
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
+msgstr "Pesquisa por domínio, nome de utilizador, biografia..."
+
+#: front/src/components/manage/library/UploadsTable.vue:241
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Pesquisa por domínio, nome de utilizador, biografia..."
+
+#: front/src/components/manage/library/ArtistsTable.vue:164
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Pesquisa por domínio, nome de utilizador, biografia..."
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
+msgstr "Pesquisa por título, artista, álbum…"
+
+#: front/src/components/manage/library/AlbumsTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Pesquisa por título, artista, álbum…"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:171
-msgid "Search by domain, username, bio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
 msgstr "Pesquisa por domínio, nome de utilizador, biografia..."
 
 #: front/src/components/manage/moderation/DomainsTable.vue:151
-msgid "Search by name..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
 msgstr "Pesquisar por nome..."
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Search by title, artist, album…"
 msgstr "Pesquisa por título, artista, álbum…"
 
-#: front/src/components/manage/library/FilesTable.vue:176
-msgid "Search by title, artist, domain…"
-msgstr "Pesquisa por título, artista, domínio…"
-
 #: front/src/components/manage/users/InvitationsTable.vue:153
+#, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Pesquisa por nome de utilizador, endereço de e-mail, código…"
 
 #: front/src/components/manage/users/UsersTable.vue:163
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Pesquisa por nome de utilizador, endereço de e-mail, nome…"
 
 #: front/src/components/audio/SearchBar.vue:20
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Procure por artistas, álbuns, pistas…"
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Procure alguma música"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Procurar em lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Procurar em Wikipedia"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr "Menu secundário"
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Secções"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Selecione um filtro"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{ count } em %{ total } selecionado"
+msgstr[1] "%{ count } em %{ total } selecionados"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Selecione apenas a página atual"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Configurações"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Configurações atualizadas"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Configurações atualizadas com sucesso."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Compartilhe o link"
 
 #: front/src/views/content/libraries/Detail.vue:15
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
-msgstr ""
-"Compartilhe este link com outros usuários para que eles possam solicitar "
-"acesso à sua biblioteca."
+msgstr "Compartilhe este link com outros usuários para que eles possam solicitar acesso à sua biblioteca."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
 msgstr "Link de compartilhamento"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
 #, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "%{ count } tema"
 msgstr[1] "%{ count } temas"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Mostrar mais 1 álbum"
 msgstr[1] "Mostrar mais %{ count } albums"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr "Mostrar atalhos de teclado disponíveis"
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Mostrar notificações antigas"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Mostrar/ocultar senha"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Mostrando resultados %{ start }-%{ end } em %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Fila de embaralhamento"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Embaralhe sua fila"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Inscrever-se"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Inscrever-se"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Data de inscrição"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
 #, fuzzy
-msgid "Silence activity"
-msgstr "Atividade do usuário"
-
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
-msgid "Silence notifications"
-msgstr "Notificações silenciosas"
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Tamanho"
 
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Tamanho"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Ignorado"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Arquivos ignorados"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr "Software"
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Desculpe, a página que você pediu não existe:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr ""
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+#, fuzzy
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr "Membro da equipe"
 
-#: front/src/components/radios/Button.vue:4
-msgid "Start"
-msgstr "Iniciar"
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Pare o rádio"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Estatisticas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
-msgstr ""
-"As estatísticas são calculadas a partir de atividade e conteúdo conhecidos "
-"em sua instância, e não refletem a atividade geral para esta conta"
+msgstr "As estatísticas são calculadas a partir de atividade e conteúdo conhecidos em sua instância, e não refletem a atividade geral para esta conta"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
-msgstr ""
-"As estatísticas são calculadas a partir da actividade e conteúdo conhecidos "
-"na sua instância e não reflectem a actividade geral para este domínio"
+msgstr "As estatísticas são calculadas a partir da actividade e conteúdo conhecidos na sua instância e não reflectem a actividade geral para este domínio"
 
-#: front/src/components/library/FileUpload.vue:86
-#: front/src/components/manage/users/InvitationsTable.vue:17
-#: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+#, fuzzy
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr "As estatísticas são calculadas a partir de atividade e conteúdo conhecidos em sua instância, e não refletem a atividade geral para esta conta"
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Estado"
+
+#: front/src/components/manage/users/InvitationsTable.vue:17
+#: front/src/components/manage/users/InvitationsTable.vue:39
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Estado"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Pare"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Estado"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Pare o rádio"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Enviar"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Senha da API Subsonic"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Não podemos carregar esta pista"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Não podemos carregar esta pista"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Não podemos carregar esta pista"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Escolhas sugeridas"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr "Sumário"
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr "Fórum de apoio"
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr "Extensões suportadas: %{ extensions }"
 
 #: front/src/components/playlists/Editor.vue:9
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Sincronizar mudanças no servidor…"
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Texto copiado para a área de transferência!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "Isso é simples: nós amamos o Grooveshark e queremos construir algo ainda melhor."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "O logótipo funkwhale foi gentilmente projetado e fornecido por Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
+msgstr "A biblioteca e todas as suas pistas serão removidas. Isto não pode ser desfeito."
+
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
 msgstr ""
-"A biblioteca e todas as suas pistas serão removidas. Isto não pode ser "
-"desfeito."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+#, fuzzy
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr "Os arquivos de música que você está enviando são marcados corretamente:"
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
 msgstr "A próxima pista será jogada automaticamente em poucos segundos..."
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr "A plataforma é gratuita e open-source, você pode instalá-lo e modificá-lo sem preocupações"
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Playlist criada"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+#, fuzzy
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr "Esta acção é irreversível."
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "A API Subsonic não está disponível nesta instância do Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Não podemos adicionar a música a uma playlist"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+#, fuzzy
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr "Esta acção é irreversível."
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Os arquivos de música enviados estão no formato OGG, Flac ou MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
-msgstr ""
-"Existem várias maneiras de obter novos conteúdos e torná-los disponíveis "
-"aqui."
+msgstr "Existem várias maneiras de obter novos conteúdos e torná-los disponíveis aqui."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr "Esta acção é irreversível."
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Este álbum está presente nas seguintes bibliotecas:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Este artista está presente nas seguintes bibliotecas:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr "Este domínio está sujeito a regras de moderação específicas"
 
 #: front/src/views/content/Home.vue:9
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
+msgstr "Esta instância oferece até %{quota} de espaço de memória para cada usuário."
+
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
 msgstr ""
-"Esta instância oferece até %{quota} de espaço de memória para cada usuário."
 
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "É você!"
 
-#: front/src/views/content/libraries/Form.vue:71
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Esta biblioteca contém minha música pessoal, espero que você goste."
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
-msgstr ""
-"Esta biblioteca é privada e sua aprovação do proprietário é necessária para "
-"acessar seu conteúdo"
+msgstr "Esta biblioteca é privada e sua aprovação do proprietário é necessária para acessar seu conteúdo"
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
 msgstr "Esta biblioteca é pública e você pode acessar seu conteúdo livremente"
 
-#: front/src/components/common/ActionTable.vue:45
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
+msgstr "Isso pode afetar muitos elementos ou ter consequências irreversíveis, por favor, verifique se isso é realmente o que você quer."
+
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
 msgstr ""
-"Isso pode afetar muitos elementos ou ter consequências irreversíveis, por "
-"favor, verifique se isso é realmente o que você quer."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr "Esta referência será usada para agrupar arquivos importados."
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Não foi possível processar esta pista, certifique-se de que está correctamente etiquetada"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "Pista carregada, mas ainda não tratada pelo servidor"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "Pista já disponível em uma de suas bibliotecas"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
 msgstr "Esta pista não está disponível em nenhuma biblioteca a que tenha acesso"
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Esta música está presente nas seguintes bibliotecas:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Isso excluirá completamente essa playlist e não poderá ser desfeito."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Isto irá remover completamente o rádio e não pode ser cancelado."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Isso desativará completamente o acesso à API do Subsonic usando a conta."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr "Isso removerá seus dados locais e o desconectará, você quer continuar?"
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Isto irá desconectá-lo a partir de dispositivos existentes que usam a senha atual."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Isso excluirá completamente essa playlist e não poderá ser desfeito."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Isso removerá todas as músicas dessa playlist e não poderá ser desfeito."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Title"
+msgstr "Título"
+
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
 msgid "Title"
 msgstr "Título"
 
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr "Alternar looping de filas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
 msgstr "Tamanho total"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Tamanho total dos arquivos nesta biblioteca"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Usuários totais"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Música"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
-msgid "Track already present in one of your libraries"
-msgstr "Pista já disponível em uma de suas bibliotecas"
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Música"
 
-#: front/src/components/library/Track.vue:85
-msgid "Track information"
-msgstr "Informação da música"
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
 
-#: front/src/components/library/radios/Filter.vue:44
+#: front/src/views/admin/library/TrackDetail.vue:91
 #, fuzzy
-msgid "Track matching filter"
-msgstr "Filtro de correspondência de músicas"
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Título da música"
 
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
+msgid "Track information"
+msgstr "Informação da música"
+
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Título da música"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "Pista carregada, mas ainda não tratada pelo servidor"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Músicas"
 
 #: front/src/components/instance/Stats.vue:54
-msgid "tracks"
-msgstr "músicas"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Músicas"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Musicas deste artista"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Músicas favoritas"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "músicas escutadas"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Filtro de correspondência de músicas"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Tipo"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Tipo"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr ""
+msgstr "Atualizar a regra de moderação"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Deixar de seguir"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Deixar de seguir esta biblioteca?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "Infelizmente, os proprietários desta instância não ainda ter o tempo para preencher esta página."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Música ilimitada"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr "Cancelar mudo"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Atualizar"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Atualizar playlist"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Atualizar avatar"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Atualizar biblioteca"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr "Atualizar a regra de moderação"
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Atualizar playlist"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Atualizar configurações"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Atualize sua senha"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Carregar"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Carregar um novo avatar"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Carregar conteúdo de áudio"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Data de upload"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Data de upload"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
+msgstr "Carregamento recusado, garantir que o arquivo não é muito grande e que você não atingiu sua cota"
+
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
 msgstr ""
-"Carregamento recusado, garantir que o arquivo não é muito grande e que você "
-"não atingiu sua cota"
 
 #: front/src/views/content/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
-msgstr ""
-"Carregue arquivos de música (mp3, ogg, flac, etc.) da sua biblioteca pessoal "
-"diretamente de seu navegador para apreciá-los aqui."
+msgstr "Carregue arquivos de música (mp3, ogg, flac, etc.) da sua biblioteca pessoal diretamente de seu navegador para apreciá-los aqui."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Carregar novas músicas"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Carregar quota"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr "Tempo limite de upload, por favor, tente novamente"
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Carregado"
 
 #: front/src/components/library/FileUpload.vue:5
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Carregamento"
 
-#: front/src/components/library/FileUpload.vue:103
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Carregando…"
 
+#: front/src/components/manage/library/LibrariesTable.vue:52
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Envios"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Envios"
+
 #: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "Envios"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Use outra instância"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Use este formulário para solicitar uma redefinição de senha. Enviaremos um email para o endereço fornecido com instruções para redefinir sua senha."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
-msgstr ""
-"Use esta configuração para ativar/desativar temporariamente a política sem "
-"removê-la completamente."
+msgstr "Use esta configuração para ativar/desativar temporariamente a política sem removê-la completamente."
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Usado"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Usuário"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Atividade do usuário"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Bibliotecas do usuário"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Rádios do usuário"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Nome de usuário"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Nome de usuário ou email"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "usuários"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Usuários"
 
 #: front/src/components/Footer.vue:29
+#, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "Usando Funkwhale"
 
 #: front/src/components/Footer.vue:13
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Versão %{version}"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Ver ficheiros"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Ver no MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Visibilidade"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Visibilidade: todos nesta instância"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Visibilidade: todos, incluindo outras instâncias"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Visibilidade: ninguém exceto eu"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Visibilidade"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr "Volume %{ number }"
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Não podemos adicionar a música a uma playlist"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Não podemos criar a playlist"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Não podemos criar sua conta"
-
-#: front/src/components/audio/Player.vue:64
-msgid "We cannot load this track"
-msgstr "Não podemos carregar esta pista"
+#: front/src/components/federation/FetchButton.vue:69
+#, fuzzy
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Carregando seus favoritos …"
 
 #: front/src/components/auth/Login.vue:7
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
 msgstr "Nós não podemos te logar"
 
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Não podemos salvar seu avatar"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
-msgstr "Não podemos salvar suas configurações"
+#: front/src/components/auth/ApplicationForm.vue:3
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Não podemos criar sua conta"
 
-#: front/src/components/Home.vue:127
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
 msgid "We do not track you or bother you with ads"
 msgstr "Nós não rastreamos ou incomodamos você com anúncios"
 
-#: front/src/components/library/Track.vue:95
-msgid "We don't have any copyright information for this track"
-msgstr "Nós não temos nenhuma informação de copyright para esta pista"
-
-#: front/src/components/library/Track.vue:106
-msgid "We don't have any licensing information for this track"
-msgstr "Não temos nenhuma informação de licença para esta pista"
-
-#: front/src/components/library/FileUpload.vue:40
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "Recomendamos usar o Picard para esse fim."
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Nós achamos que ouvir música deveria ser simples."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Desculpe, a página que você pediu não existe:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Bem-vindo"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Bem-vindo ao Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Por que o funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr "Altura do widget"
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr "Largura do widget"
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Sim"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr "Sim, me desconecte!"
 
 #: front/src/views/content/libraries/Form.vue:19
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
-msgstr ""
-"Você pode compartilhar sua biblioteca com outras pessoas, independentemente "
-"de sua visibilidade."
+msgstr "Você pode compartilhar sua biblioteca com outras pessoas, independentemente de sua visibilidade."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Você está prestes a fazer o upload de músicas para sua biblioteca. Antes de prosseguir, certifique-se de que:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Você está logado como %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Você pode seguir bibliotecas de outros usuários para obter acesso a novas músicas. Bibliotecas públicas podem ser seguidas imediatamente, enquanto seguir uma biblioteca privada requer aprovação de seu proprietário."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Você pode convidar amigos e familia para sua instância para que eles possam curtir sua música"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Agora você pode usar o serviço sem limitações."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Você pode usar essa interface para construir a sua própria rádio que vai jogar músicas de acordo com seus critérios."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Você pode usá-los para curtir sua playlist e música no modo off-line, em seu smartphone ou tablet, por exemplo."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "Não tem nenhuma regra em vigor para esta conta."
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "Não tem nenhuma regra em vigor para esta conta."
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
 msgstr "Não tem nenhuma regra em vigor para esta conta."
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
 msgstr "Você não tem nenhuma regra em vigor para este domínio."
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
+msgstr ""
+
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "Você tem um rádio tocando"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr "Você pode ter um problema de conectividade."
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Você precisa selecionar uma instância para continuar"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr "Você será desconectado desta sessão e precisará fazer login com o novo"
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Você terá que atualizar sua senha em seus clientes que usam essa senha."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Playlist criada"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Suas notificações"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Seus favoritos"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr "Sua música, seu jeito"
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Suas notificações"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Sua senha foi atualizada com sucesso."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Configurações atualizadas"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "Sua senha do Subsonic será alterada para uma nova, aleatória, efetuando o logout de dispositivos que usaram a senha antiga do Subsonic"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Paginação"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Direitos Autorais"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Álbum contendo %{ count } pista, por %{ artist }"
+msgstr[1] "Álbum contendo %{ count } pistas, por %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } pista foi adicionada à sua fila"
+msgstr[1] "%{ count } pistas foram adicionadas à sua fila"
diff --git a/front/locales/ru/LC_MESSAGES/app.po b/front/locales/ru/LC_MESSAGES/app.po
index c45d8ba5a7e06776b2a75cdc863c7e50c32ea8df..11dbede454beab7efaef8f5e3b837d4bb85f0119 100644
--- a/front/locales/ru/LC_MESSAGES/app.po
+++ b/front/locales/ru/LC_MESSAGES/app.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: front 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-01-11 16:04+0100\n"
+"POT-Creation-Date: 2019-05-02 14:06+0200\n"
 "PO-Revision-Date: 2018-10-20 14:22+0000\n"
 "Last-Translator: noname <noname@inventati.org>\n"
 "Language-Team: none\n"
@@ -19,57 +19,67 @@ msgstr ""
 "X-Generator: Weblate 2.20\n"
 
 #: front/src/components/playlists/PlaylistModal.vue:9
+msgctxt "Popup/Playlist/Paragraph"
 msgid "\"%{ title }\", by %{ artist }"
 msgstr "\"%{ title }\" от %{ artist }"
 
 #: front/src/components/Sidebar.vue:24
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(%{ index } of %{ length })"
 msgstr "(%{ index } из %{ length })"
 
 #: front/src/components/Sidebar.vue:22
+msgctxt "Sidebar/Queue/Tab.Title"
 msgid "(empty)"
 msgstr "(пусто)"
 
-#: front/src/components/common/ActionTable.vue:57
-#: front/src/components/common/ActionTable.vue:66
+#: front/src/components/auth/Authorize.vue:16
 #, fuzzy
+msgctxt "Content/Auth/Title"
+msgid "%{ app } wants to access your Funkwhale account"
+msgstr "Войти в ваш аккаунт Funkwhale"
+
+#: front/src/components/common/ActionTable.vue:68
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "%{ count } on %{ total } selected"
 msgid_plural "%{ count } on %{ total } selected"
 msgstr[0] "выбран %{ count } из %{ total }"
 msgstr[1] "выбрано %{ count } из %{ total }"
 msgstr[2] "выбрано %{ count } из %{ total }"
 
-#: front/src/components/Sidebar.vue:110 src/components/audio/album/Card.vue:54
-#: front/src/views/content/libraries/Card.vue:39
-#: src/views/content/remote/Card.vue:26
+#: front/src/components/Sidebar.vue:121 src/components/audio/album/Card.vue:52
+#: front/src/views/content/libraries/Card.vue:40
+#: src/views/content/remote/Card.vue:30
+#, fuzzy
+msgctxt "*/*/*"
 msgid "%{ count } track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count } трек"
 msgstr[1] "%{ count } трека"
 msgstr[2] "%{ count } треков"
 
-#: front/src/components/library/Artist.vue:13
+#: front/src/components/library/ArtistBase.vue:13
+#, fuzzy
+msgctxt "Content/Artist/Paragraph"
 msgid "%{ count } track in %{ albumsCount } albums"
 msgid_plural "%{ count } tracks in %{ albumsCount } albums"
 msgstr[0] "%{ count } трек из %{ albumsCount } альбомов"
 msgstr[1] "%{ count } трека из %{ albumsCount } альбомов"
 msgstr[2] "%{ count } треков из %{ albumsCount } альбомов"
 
-#: front/src/components/library/radios/Builder.vue:80
+#: front/src/components/library/radios/Builder.vue:81
+#, fuzzy
+msgctxt "Content/Radio/Table.Paragraph/Short"
 msgid "%{ count } track matching combined filters"
 msgid_plural "%{ count } tracks matching combined filters"
 msgstr[0] "%{ count } подходящий трек"
 msgstr[1] "%{ count } подходящих трека"
 msgstr[2] "%{ count } подходящих треков"
 
-#: front/src/components/audio/PlayButton.vue:180
-msgid "%{ count } track was added to your queue"
-msgid_plural "%{ count } tracks were added to your queue"
-msgstr[0] "%{ count } трек добавлен в вашу очередь"
-msgstr[1] "%{ count } трека добавлено в вашу очередь"
-msgstr[2] "%{ count } треков добавлено в вашу очередь"
-
 #: front/src/components/playlists/Card.vue:18
+#, fuzzy
+msgctxt "Content/*/Card/List item"
 msgid "%{ count} track"
 msgid_plural "%{ count } tracks"
 msgstr[0] "%{ count} трек"
@@ -77,35 +87,48 @@ msgstr[1] "%{ count } трека"
 msgstr[2] "%{ count } треков"
 
 #: front/src/views/content/libraries/Quota.vue:11
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "%{ current } used on %{ max } allowed"
 msgstr "%{ current } использовано из доступных %{ max }"
 
 #: front/src/components/common/Duration.vue:2
+msgctxt "Content/*/Paragraph"
 msgid "%{ hours } h %{ minutes } min"
 msgstr "%{ hours } ч %{ minutes } мин"
 
 #: front/src/components/common/Duration.vue:5
+msgctxt "Content/*/Paragraph"
 msgid "%{ minutes } min"
 msgstr "%{ minutes } мин"
 
 #: front/src/components/notifications/NotificationRow.vue:40
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } accepted your follow on library \"%{ library }\""
 msgstr ""
 
 #: front/src/components/notifications/NotificationRow.vue:39
+msgctxt "Content/Notifications/Paragraph"
 msgid "%{ username } followed your library \"%{ library }\""
 msgstr ""
 
+#: front/src/components/notifications/NotificationRow.vue:41
+msgctxt "Content/Notifications/Paragraph"
+msgid "%{ username } wants to follow your library \"%{ library }\""
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:46
+msgctxt "Head/Profile/Title"
 msgid "%{ username }'s profile"
 msgstr "Профиль %{ username }"
 
-#: front/src/components/Footer.vue:5
-msgid "<translate :translate-params=\"{instanceName: instanceHostname}\">About %{instanceName}</translate>"
+#: front/src/components/playlists/PlaylistModal.vue:21
+msgctxt "Popup/Playlist/Paragraph"
+msgid "<strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>."
 msgstr ""
 
 #: front/src/components/audio/artist/Card.vue:41
+#, fuzzy
+msgctxt "Content/Artist/Card"
 msgid "1 album"
 msgid_plural "%{ count } albums"
 msgstr[0] "1 альбом"
@@ -113,78 +136,190 @@ msgstr[1] "%{ count } альбома"
 msgstr[2] "%{ count } альбомов"
 
 #: front/src/components/favorites/List.vue:10
+#, fuzzy
+msgctxt "Content/Favorites/Title"
 msgid "1 favorite"
 msgid_plural "%{ count } favorites"
 msgstr[0] "1 избранный"
 msgstr[1] "%{ count } избранных"
 msgstr[2] "%{ count } избранных"
 
-#: front/src/components/library/FileUpload.vue:225
-#: front/src/components/library/FileUpload.vue:226
+#: front/src/components/Home.vue:64
+#, fuzzy
+msgctxt "Content/Home/Title"
+msgid "A clean library"
+msgstr "Очистить библиотеку"
+
+#: front/src/components/library/FileUpload.vue:264
+msgctxt "Content/Library/Help text"
 msgid "A network error occured while uploading this file"
 msgstr "При загрузке этого файла произошла сетевая ошибка"
 
+#: front/src/components/library/EditForm.vue:145
+#, fuzzy
+msgctxt "*/*/Placeholder"
+msgid "A short summary describing your changes."
+msgstr "При сохранении ваших изменений произошла ошибка"
+
 #: front/src/components/About.vue:5
+msgctxt "Content/About/Title/Short, Noun"
 msgid "About %{ instance }"
 msgstr "О %{ instance }"
 
 #: front/src/components/Footer.vue:6
-#, fuzzy
+msgctxt "Footer/About/Title"
 msgid "About %{instanceName}"
 msgstr "О %{ instance }"
 
 #: front/src/components/Footer.vue:45
+#, fuzzy
+msgctxt "Footer/*/Title/Short"
 msgid "About Funkwhale"
 msgstr "О Funkwhale"
 
 #: front/src/components/Footer.vue:10
-#, fuzzy
+msgctxt "Footer/About/List item.Link"
 msgid "About page"
 msgstr "Страница альбома"
 
-#: front/src/components/About.vue:8 src/components/About.vue:64
+#: front/src/components/About.vue:8 src/components/About.vue:67
+#, fuzzy
+msgctxt "Content/About/Title"
 msgid "About this instance"
 msgstr "Об этом узле"
 
 #: front/src/views/content/libraries/Detail.vue:48
+msgctxt "Content/Library/Button.Label"
 msgid "Accept"
 msgstr "Принять"
 
 #: front/src/views/content/libraries/Detail.vue:40
+msgctxt "Content/Library/Table/Short"
 msgid "Accepted"
 msgstr "Подтверждено"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:111
+#: front/src/components/auth/SubsonicTokenForm.vue:110
+msgctxt "Content/Settings/Message"
 msgid "Access disabled"
 msgstr "Доступ отключен"
 
-#: front/src/components/Home.vue:106
-msgid "Access your music from a clean interface that focus on what really matters"
+#: front/src/components/mixins/Translations.vue:73
+#: front/src/components/mixins/Translations.vue:74
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to audio files, libraries, artists, albums and tracks"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:97
+#: front/src/components/mixins/Translations.vue:98
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to content filters"
+msgstr "Выберите фильтр"
+
+#: front/src/components/mixins/Translations.vue:105
+#: front/src/components/mixins/Translations.vue:106
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to edits"
+msgstr "Доступ отключен"
+
+#: front/src/components/mixins/Translations.vue:69
+#: front/src/components/mixins/Translations.vue:70
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to email, username, and profile information"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:77
+#: front/src/components/mixins/Translations.vue:78
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to favorites"
+msgstr "Добавить в избранное"
+
+#: front/src/components/mixins/Translations.vue:85
+#: front/src/components/mixins/Translations.vue:86
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to follows"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:81
+#: front/src/components/mixins/Translations.vue:82
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to listening history"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:101
+#: front/src/components/mixins/Translations.vue:102
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to notifications"
+msgstr "Ваши уведомления"
+
+#: front/src/components/mixins/Translations.vue:89
+#: front/src/components/mixins/Translations.vue:90
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to playlists"
+msgstr "Добавить в список воспроизведения..."
+
+#: front/src/components/mixins/Translations.vue:93
+#: front/src/components/mixins/Translations.vue:94
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Paragraph"
+msgid "Access to radios"
+msgstr "Доступ отключен"
+
+#: front/src/components/Home.vue:101
+#, fuzzy
+msgctxt "Content/Home/List item"
+msgid "Access your music from a clean interface that focuses on what really matters"
 msgstr "Получайте доступ к вашей музыке из простого интерфейса который сфокусирован на том что действительно важно"
 
-#: front/src/components/mixins/Translations.vue:19
-#: front/src/components/mixins/Translations.vue:20
+#: front/src/components/manage/library/UploadsTable.vue:67
+#: front/src/components/mixins/Translations.vue:45
+#: front/src/views/admin/library/UploadDetail.vue:175
+#: front/src/components/mixins/Translations.vue:46
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Accessed date"
-msgstr ""
+msgstr "Доступ отключен"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:78
+#: front/src/views/admin/library/LibraryDetail.vue:104
+#: front/src/views/admin/library/UploadDetail.vue:111
 #, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Account"
+msgstr "Статус аккаунта"
+
+#: front/src/components/manage/library/LibrariesTable.vue:49
+#: front/src/components/manage/library/UploadsTable.vue:61
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Account"
+msgstr "Статус аккаунта"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:107
+msgctxt "Content/Moderation/Title"
 msgid "Account data"
 msgstr "Аккаунт активен"
 
 #: front/src/components/auth/Settings.vue:5
+msgctxt "Content/Settings/Title"
 msgid "Account settings"
 msgstr "Настройки аккаунта"
 
-#: front/src/components/auth/Settings.vue:264
+#: front/src/components/auth/Settings.vue:479
+msgctxt "Head/Settings/Title"
 msgid "Account Settings"
 msgstr "Настройки аккаунта"
 
 #: front/src/components/manage/users/UsersTable.vue:39
+msgctxt "Content/Admin/Table.Label/Short, Noun"
 msgid "Account status"
 msgstr "Статус аккаунта"
 
 #: front/src/views/auth/PasswordReset.vue:14
+msgctxt "Content/Signup/Input.Label"
 msgid "Account's email"
 msgstr "Электронная почта аккаунта"
 
@@ -192,1697 +327,2832 @@ msgstr "Электронная почта аккаунта"
 #: front/src/views/admin/moderation/AccountsList.vue:24
 #: front/src/views/admin/moderation/Base.vue:8
 #, fuzzy
+msgctxt "*/Moderation/Title"
 msgid "Accounts"
 msgstr "Статус аккаунта"
 
 #: front/src/views/content/libraries/Detail.vue:29
+msgctxt "Content/Library/Table.Label"
 msgid "Action"
 msgstr "Действие"
 
-#: front/src/components/common/ActionTable.vue:99
+#: front/src/components/common/ActionTable.vue:101
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Action %{ action } was launched successfully on %{ count } element"
 msgid_plural "Action %{ action } was launched successfully on %{ count } elements"
 msgstr[0] "Действие %{ action } было успешно запущено на %{ count } элементе"
 msgstr[1] "Действие %{ action } было успешно запущено на %{ count } элементах"
 msgstr[2] "Действие %{ action } было успешно запущено на %{ count } элементах"
 
-#: front/src/components/common/ActionTable.vue:21
-#: front/src/components/library/radios/Builder.vue:64
+#: front/src/components/common/ActionTable.vue:22
+#: front/src/components/library/radios/Builder.vue:65
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Actions"
 msgstr "Действия"
 
 #: front/src/components/manage/users/UsersTable.vue:53
-#, fuzzy
+msgctxt "Content/Admin/Table"
 msgid "Active"
 msgstr "Активен(на)"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:199
-#: front/src/views/admin/moderation/DomainsDetail.vue:144
+#: front/src/views/admin/library/AlbumDetail.vue:134
+#: front/src/views/admin/library/ArtistDetail.vue:123
+#: front/src/views/admin/library/LibraryDetail.vue:138
+#: front/src/views/admin/library/TrackDetail.vue:186
+#: front/src/views/admin/library/UploadDetail.vue:160
+#: front/src/views/admin/moderation/AccountsDetail.vue:220
+#: front/src/views/admin/moderation/DomainsDetail.vue:136
+msgctxt "Content/Moderation/Title"
 msgid "Activity"
 msgstr "Активность"
 
 #: front/src/components/mixins/Translations.vue:7
 #: front/src/components/mixins/Translations.vue:8
+msgctxt "Content/Settings/Dropdown.Label/Noun"
 msgid "Activity visibility"
 msgstr "Видимость активности"
 
 #: front/src/views/admin/moderation/DomainsList.vue:18
+msgctxt "Content/Moderation/Button/Verb"
 msgid "Add"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsList.vue:13
+msgctxt "Content/Moderation/Form.Label/Verb"
 msgid "Add a domain"
 msgstr ""
 
+#: front/src/views/admin/moderation/AccountsDetail.vue:79
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Add a moderation policy"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:4
+#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Add a new moderation rule"
-msgstr ""
+msgstr "Удалить радио"
 
 #: front/src/views/content/Home.vue:35
+msgctxt "Content/Library/Title/Verb"
 msgid "Add and manage content"
 msgstr "Добавить или управлять содержимым"
 
+#: front/src/components/playlists/Editor.vue:28
+#: front/src/components/playlists/PlaylistModal.vue:31
+msgctxt "*/Playlist/Button.Label/Verb"
+msgid "Add anyways"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:75 src/views/content/Base.vue:18
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Add content"
 msgstr "Добавить содержимое"
 
-#: front/src/components/library/radios/Builder.vue:50
+#: front/src/components/library/radios/Builder.vue:51
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Add filter"
 msgstr "Добавить фильтр"
 
-#: front/src/components/library/radios/Builder.vue:40
+#: front/src/components/library/radios/Builder.vue:41
+msgctxt "Content/Radio/Paragraph"
 msgid "Add filters to customize your radio"
 msgstr "Добавить фильтры чтобы кастомизировать своё радио"
 
-#: front/src/components/audio/PlayButton.vue:64
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:75
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Add to current queue"
 msgstr "Добавить в очередь"
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:4
 #: front/src/components/favorites/TrackFavoriteIcon.vue:28
+#, fuzzy
+msgctxt "Content/Track/*/Verb"
 msgid "Add to favorites"
 msgstr "Добавить в избранное"
 
 #: front/src/components/playlists/TrackPlaylistIcon.vue:6
 #: front/src/components/playlists/TrackPlaylistIcon.vue:34
-#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Add to playlist…"
 msgstr "Добавить в список воспроизведения..."
 
-#: front/src/components/audio/PlayButton.vue:14
+#: front/src/components/audio/PlayButton.vue:15
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
 msgid "Add to queue"
 msgstr "Добавить в очередь"
 
-#: front/src/components/playlists/PlaylistModal.vue:116
+#: front/src/components/playlists/PlaylistModal.vue:142
+msgctxt "Popup/Playlist/Table.Button.Tooltip/Verb"
 msgid "Add to this playlist"
 msgstr "Добавить в этот список воспроизведения"
 
-#: front/src/components/playlists/PlaylistModal.vue:54
+#: front/src/components/playlists/PlaylistModal.vue:68
+msgctxt "Popup/Playlist/Table.Button.Label/Verb"
 msgid "Add track"
 msgstr "Добавить трек"
 
 #: front/src/components/manage/users/UsersTable.vue:69
+msgctxt "Content/Admin/Table.User role"
 msgid "Admin"
 msgstr "Администратор"
 
 #: front/src/components/Sidebar.vue:79
+msgctxt "Sidebar/Admin/Title/Noun"
 msgid "Administration"
 msgstr "Администрирование"
 
 #: front/src/components/audio/SearchBar.vue:26
-#: src/components/audio/track/Table.vue:8
-#: front/src/components/library/Album.vue:159
-#: front/src/components/manage/library/FilesTable.vue:39
+#: src/components/audio/track/Table.vue:9
+#: front/src/components/library/AlbumBase.vue:152
+#: front/src/components/library/ArtistBase.vue:194
+#: front/src/components/manage/library/TracksTable.vue:40
 #: front/src/components/metadata/Search.vue:134
-#: front/src/views/content/libraries/FilesTable.vue:56
+#: front/src/views/content/libraries/FilesTable.vue:57
+msgctxt "*/*/*"
 msgid "Album"
 msgstr "Альбом"
 
-#: front/src/components/library/Album.vue:12
-msgid "Album containing %{ count } track, by %{ artist }"
-msgid_plural "Album containing %{ count } tracks, by %{ artist }"
-msgstr[0] "Альбом содержит %{ count } трек от %{ artist }"
-msgstr[1] "Альбом содержит %{ count } трека от %{ artist }"
-msgstr[2] "Альбом содержит %{ count } треков от %{ artist }"
+#: front/src/views/admin/library/TrackDetail.vue:107
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album"
+msgstr "Альбом"
 
-#: front/src/components/mixins/Translations.vue:24
-#: front/src/components/mixins/Translations.vue:25
-msgid "Album name"
+#: front/src/views/admin/library/TrackDetail.vue:128
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Album artist"
+msgstr "Альбомы этого исполнителя"
+
+#: front/src/views/admin/library/AlbumDetail.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Album data"
 msgstr "Название альбома"
 
-#: front/src/components/library/Track.vue:27
-msgid "Album page"
-msgstr "Страница альбома"
+#: front/src/components/mixins/Translations.vue:51
+#: front/src/components/mixins/Translations.vue:52
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Album name"
+msgstr "Название альбома"
 
 #: front/src/components/audio/Search.vue:19
 #: src/components/instance/Stats.vue:48
-#: front/src/views/admin/moderation/AccountsDetail.vue:321
-#: front/src/views/admin/moderation/DomainsDetail.vue:257
+#: front/src/components/library/Albums.vue:120
+#: src/components/library/Library.vue:7
+#: front/src/components/manage/library/ArtistsTable.vue:41
+#: front/src/views/admin/library/AlbumsList.vue:24
+#: front/src/views/admin/library/ArtistDetail.vue:241
+#: front/src/views/admin/library/Base.vue:11
+#: front/src/views/admin/library/LibraryDetail.vue:219
+#: front/src/views/admin/moderation/AccountsDetail.vue:354
+#: front/src/views/admin/moderation/DomainsDetail.vue:264
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Albums"
 msgstr "Альбомы"
 
-#: front/src/components/library/Artist.vue:44
+#: front/src/components/library/ArtistDetail.vue:21
+msgctxt "Content/Artist/Title"
 msgid "Albums by this artist"
 msgstr "Альбомы этого исполнителя"
 
+#: front/src/components/manage/library/EditsCardList.vue:15
+#: front/src/components/manage/library/LibrariesTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:13
+#: front/src/components/manage/library/UploadsTable.vue:22
 #: front/src/components/manage/users/InvitationsTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:13
+#, fuzzy
+msgctxt "Content/*/Dropdown"
 msgid "All"
 msgstr "Все"
 
+#: front/src/components/common/ActionTable.vue:59
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "All %{ count } element selected"
+msgid_plural "All %{ count } elements selected"
+msgstr[0] "выбран %{ count } из %{ total }"
+msgstr[1] "выбрано %{ count } из %{ total }"
+msgstr[2] "выбрано %{ count } из %{ total }"
+
+#: front/src/components/auth/Authorize.vue:107
+msgctxt "Head/Authorize/Title"
+msgid "Allow application"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:17
+msgctxt "Popup/Import/Message"
+msgid "An error occured during upload processing. You will find more information below."
+msgstr ""
+
 #: front/src/components/playlists/Editor.vue:13
+msgctxt "Content/Playlist/Error message.Title"
 msgid "An error occured while saving your changes"
 msgstr "При сохранении ваших изменений произошла ошибка"
 
-#: front/src/components/auth/Login.vue:10
+#: front/src/components/federation/FetchButton.vue:21
+#, fuzzy
+msgctxt "Popup/*/Message.Content"
+msgid "An error occured while trying to refresh data:"
+msgstr "При сохранении ваших изменений произошла ошибка"
+
+#: front/src/components/federation/FetchButton.vue:41
 #, fuzzy
+msgctxt "*/*/Error"
+msgid "An HTTP error occured while contacting the remote server"
+msgstr "При сохранении ваших изменений произошла ошибка"
+
+#: front/src/components/auth/Login.vue:10
+msgctxt "Content/Login/Error message/List item"
 msgid "An unknown error happend, this can mean the server is down or cannot be reached"
 msgstr "Произошла неизвестная ошибка, возможно сервер перегружен или недоступен"
 
-#: front/src/components/notifications/NotificationRow.vue:62
+#: front/src/components/library/ImportStatusModal.vue:145
+msgctxt "Popup/Import/Error.Label"
+msgid "An unkwown error occured"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:175
+#: src/components/auth/Settings.vue:225
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Application"
+msgstr "Действие"
+
+#: front/src/components/auth/ApplicationEdit.vue:12
+msgctxt "Content/Applications/Title"
+msgid "Application details"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:21
+msgctxt "Content/Applications/Label"
+msgid "Application ID"
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:16
+msgctxt "Content/Application/Paragraph/"
+msgid "Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else."
+msgstr ""
+
+#: front/src/components/auth/ApplicationEdit.vue:25
+msgctxt "Content/Applications/Label"
+msgid "Application secret"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:81
+#: front/src/components/notifications/NotificationRow.vue:66
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Approve"
 msgstr ""
 
+#: front/src/components/library/EditCard.vue:25
+#: front/src/components/manage/library/EditsCardList.vue:21
+msgctxt "Content/*/*/Short"
+msgid "Approved"
+msgstr ""
+
+#: front/src/components/library/EditCard.vue:21
+msgctxt "Content/Library/Card/Short"
+msgid "Approved and applied"
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:5
+msgctxt "Content/Login/Title"
 msgid "Are you sure you want to log out?"
 msgstr "Вы уверены что хотите выйти?"
 
 #: front/src/components/audio/SearchBar.vue:25
-#: src/components/audio/track/Table.vue:7
-#: front/src/components/library/Artist.vue:137
-#: front/src/components/manage/library/FilesTable.vue:38
+#: src/components/audio/track/Table.vue:8
 #: front/src/components/metadata/Search.vue:130
-#: front/src/views/content/libraries/FilesTable.vue:55
+#: front/src/views/admin/library/AlbumDetail.vue:108
+#: front/src/views/admin/library/TrackDetail.vue:118
+#: front/src/views/content/libraries/FilesTable.vue:56
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artist"
 msgstr "Исполнитель"
 
-#: front/src/components/mixins/Translations.vue:25
-#: front/src/components/mixins/Translations.vue:26
-msgid "Artist name"
+#: front/src/components/manage/library/AlbumsTable.vue:40
+#: front/src/components/manage/library/TracksTable.vue:41
+msgctxt "*/*/*"
+msgid "Artist"
+msgstr "Исполнитель"
+
+#: front/src/views/admin/library/ArtistDetail.vue:91
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Artist data"
 msgstr "Имя исполнителя"
 
-#: front/src/components/library/Album.vue:22
-#: src/components/library/Track.vue:33
-msgid "Artist page"
-msgstr "Страница исполнителя"
+#: front/src/components/mixins/Translations.vue:52
+#: front/src/components/mixins/Translations.vue:53
+msgctxt "Content/*/Dropdown/Noun"
+msgid "Artist name"
+msgstr "Имя исполнителя"
 
 #: front/src/components/audio/Search.vue:65
-#, fuzzy
+msgctxt "*/Search/Input.Placeholder"
 msgid "Artist, album, track…"
 msgstr "Исполнитель, альбом, трек..."
 
+#: front/src/views/admin/library/ArtistsList.vue:24
+#: front/src/views/admin/library/Base.vue:8
+#: front/src/views/admin/library/LibraryDetail.vue:209
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Artists"
+msgstr "Исполнители"
+
 #: front/src/components/audio/Search.vue:10
 #: src/components/instance/Stats.vue:42
-#: front/src/components/library/Artists.vue:119
-#: src/components/library/Library.vue:7
-#: front/src/views/admin/moderation/AccountsDetail.vue:313
-#: front/src/views/admin/moderation/DomainsDetail.vue:249
+#: front/src/components/library/Artists.vue:117
+#: src/components/library/Library.vue:10
+#: front/src/views/admin/moderation/AccountsDetail.vue:346
+#: front/src/views/admin/moderation/DomainsDetail.vue:254
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Artists"
 msgstr "Исполнители"
 
-#: front/src/components/favorites/List.vue:33
-#: src/components/library/Artists.vue:25
-#: front/src/components/library/Radios.vue:44
-#: front/src/components/manage/library/FilesTable.vue:19
+#: front/src/components/favorites/List.vue:34
+#: src/components/library/Albums.vue:25
+#: front/src/components/library/Artists.vue:25
+#: src/components/library/Radios.vue:44
+#: front/src/components/manage/library/AlbumsTable.vue:21
+#: front/src/components/manage/library/ArtistsTable.vue:21
+#: front/src/components/manage/library/EditsCardList.vue:39
+#: front/src/components/manage/library/LibrariesTable.vue:30
+#: front/src/components/manage/library/TracksTable.vue:21
+#: front/src/components/manage/library/UploadsTable.vue:40
 #: front/src/components/manage/moderation/AccountsTable.vue:21
 #: front/src/components/manage/moderation/DomainsTable.vue:19
 #: front/src/components/manage/users/UsersTable.vue:19
 #: front/src/views/content/libraries/FilesTable.vue:31
 #: front/src/views/playlists/List.vue:27
+msgctxt "Content/Search/Dropdown"
 msgid "Ascending"
 msgstr "По возрастанию"
 
-#: front/src/views/auth/PasswordReset.vue:27
+#: front/src/views/auth/PasswordReset.vue:28
+msgctxt "Content/Signup/Button.Label/Verb"
 msgid "Ask for a password reset"
 msgstr "Сбросить пароль"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:245
+#: front/src/views/admin/library/AlbumDetail.vue:198
+#: front/src/views/admin/library/ArtistDetail.vue:187
+#: front/src/views/admin/library/LibraryDetail.vue:176
+#: front/src/views/admin/library/TrackDetail.vue:250
+#: front/src/views/admin/library/UploadDetail.vue:191
+#: front/src/views/admin/moderation/AccountsDetail.vue:274
 #: front/src/views/admin/moderation/DomainsDetail.vue:202
-#, fuzzy
+msgctxt "Content/Moderation/Title"
 msgid "Audio content"
 msgstr "Добавить содержимое"
 
 #: front/src/components/ShortcutsModal.vue:55
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "Audio player shortcuts"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/auth/Authorize.vue:47
+msgctxt "Content/Signup/Button.Label/Verb"
+msgid "Authorize %{ app }"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:4
+msgctxt "Content/Auth/Title/Verb"
+msgid "Authorize third-party app"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:162
+msgctxt "Content/Settings/Title/Noun"
+msgid "Authorized apps"
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:40
+msgctxt "Popup/Playlist/Title"
 msgid "Available playlists"
 msgstr "Доступные списки воспроизведения"
 
 #: front/src/components/auth/Settings.vue:34
+msgctxt "Content/Settings/Title"
 msgid "Avatar"
 msgstr "Аватар"
 
-#: front/src/views/auth/PasswordReset.vue:24
+#: front/src/views/auth/PasswordReset.vue:25
 #: front/src/views/auth/PasswordResetConfirm.vue:18
+msgctxt "Content/Signup/Link"
 msgid "Back to login"
 msgstr "Назад ко входу"
 
-#: front/src/components/library/Track.vue:129
-#: front/src/components/manage/library/FilesTable.vue:42
-#: front/src/components/mixins/Translations.vue:29
-#: front/src/components/mixins/Translations.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:9
+#: front/src/components/auth/ApplicationNew.vue:5
+#, fuzzy
+msgctxt "Content/Applications/Link"
+msgid "Back to settings"
+msgstr "Обновить настройки"
+
+#: front/src/components/library/TrackDetail.vue:48
+#: front/src/components/mixins/Translations.vue:55
+#: front/src/views/admin/library/UploadDetail.vue:227
+#: front/src/components/mixins/Translations.vue:56
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Bitrate"
 msgstr "Битрейт"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:19
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:34
+msgctxt "Content/Moderation/*/Verb"
 msgid "Block everything"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:112
+msgctxt "Content/Moderation/Help text"
 msgid "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"
 msgstr ""
 
 #: front/src/components/Sidebar.vue:18 src/components/library/Library.vue:4
+#, fuzzy
+msgctxt "*/Library/*/Verb"
 msgid "Browse"
 msgstr "Просмотр"
 
 #: front/src/components/Sidebar.vue:65
+msgctxt "Sidebar/Library/List item.Link/Verb"
 msgid "Browse library"
 msgstr "Просмотр библиотеки"
 
+#: front/src/components/library/Albums.vue:4
+#, fuzzy
+msgctxt "Content/Album/Title"
+msgid "Browsing albums"
+msgstr "Просмотр радио"
+
 #: front/src/components/library/Artists.vue:4
+msgctxt "Content/Artist/Title"
 msgid "Browsing artists"
 msgstr "Просмотр исполнителей"
 
 #: front/src/views/playlists/List.vue:3
+msgctxt "Content/Playlist/Title"
 msgid "Browsing playlists"
 msgstr "Просмотр списков воспроизведения"
 
 #: front/src/components/library/Radios.vue:4
+msgctxt "Content/Radio/Title"
 msgid "Browsing radios"
 msgstr "Просмотр радио"
 
 #: front/src/components/library/radios/Builder.vue:5
+msgctxt "Content/Radio/Title"
 msgid "Builder"
 msgstr "Конструктор"
 
 #: front/src/components/audio/album/Card.vue:13
+msgctxt "Content/Album/Card"
 msgid "By %{ artist }"
 msgstr "От %{ artist }"
 
-#: front/src/views/content/remote/Card.vue:103
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:107
+msgctxt "Popup/Library/Paragraph"
 msgid "By unfollowing this library, you loose access to its content."
 msgstr "Отписавшись от этой библиотеки, вы потеряете доступ к её содержимому."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:261
+#: front/src/views/admin/library/AlbumDetail.vue:214
+#: front/src/views/admin/library/ArtistDetail.vue:203
+#: front/src/views/admin/library/LibraryDetail.vue:192
+#: front/src/views/admin/library/TrackDetail.vue:266
+#: front/src/views/admin/library/UploadDetail.vue:208
+#: front/src/views/admin/moderation/AccountsDetail.vue:290
 #: front/src/views/admin/moderation/DomainsDetail.vue:217
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Cached size"
 msgstr ""
 
+#: front/src/components/SetInstanceModal.vue:37
 #: front/src/components/common/DangerousButton.vue:17
-#: front/src/components/library/Album.vue:58
-#: src/components/library/Track.vue:76
+#: front/src/components/library/AlbumBase.vue:36
+#: front/src/components/library/ArtistBase.vue:47
+#: front/src/components/library/EditForm.vue:95
+#: front/src/components/library/TrackBase.vue:55
 #: front/src/components/library/radios/Filter.vue:53
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:54
-#: front/src/components/playlists/PlaylistModal.vue:63
+#: front/src/components/moderation/FilterModal.vue:39
+#: front/src/components/playlists/PlaylistModal.vue:26
+#: front/src/components/playlists/PlaylistModal.vue:77
+msgctxt "*/*/Button.Label/Verb"
 msgid "Cancel"
 msgstr "Отмена"
 
-#: front/src/components/library/radios/Builder.vue:63
+#: front/src/components/library/radios/Builder.vue:64
+msgctxt "Content/Radio/Table.Label/Noun (Value is a number of Tracks)"
 msgid "Candidates"
 msgstr "Кандидаты"
 
-#: front/src/components/auth/Settings.vue:76
-msgid "Cannot change your password"
-msgstr "Не удалось изменить ваш пароль"
-
-#: front/src/components/library/FileUpload.vue:222
-#: front/src/components/library/FileUpload.vue:223
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:261
+msgctxt "Content/Library/Help text"
 msgid "Cannot upload this file, ensure it is not too big"
 msgstr "Невозможно загрузить файл, убедитесь что он не слишком большой"
 
 #: front/src/components/Footer.vue:21
+msgctxt "Footer/Settings/Dropdown.Label/Short, Verb"
 msgid "Change language"
 msgstr "Сменить язык"
 
-#: front/src/components/auth/Settings.vue:67
+#: front/src/components/auth/Settings.vue:68
+msgctxt "Content/Settings/Title/Verb"
 msgid "Change my password"
 msgstr "Сменить мой пароль"
 
 #: front/src/components/auth/Settings.vue:95
+msgctxt "Content/Settings/Button.Label"
 msgid "Change password"
 msgstr "Сменить пароль"
 
-#: front/src/views/auth/PasswordResetConfirm.vue:4
 #: front/src/views/auth/PasswordResetConfirm.vue:62
+#, fuzzy
+msgctxt "*/Signup/Title"
 msgid "Change your password"
 msgstr "Сменить ваш пароль"
 
 #: front/src/components/auth/Settings.vue:96
+msgctxt "Popup/Settings/Title"
 msgid "Change your password?"
 msgstr "Сменить ваш пароль?"
 
-#: front/src/components/playlists/Editor.vue:21
+#: front/src/components/playlists/Editor.vue:31
+msgctxt "Content/Playlist/Paragraph"
 msgid "Changes synced with server"
 msgstr "Изменения синхронизированы с сервером"
 
-#: front/src/components/auth/Settings.vue:70
+#: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph'"
 msgid "Changing your password will also change your Subsonic API password if you have requested one."
 msgstr "Изменение вашего пароля также изменит ваш пароль Subsonic API если вы запрашивали его."
 
 #: front/src/components/auth/Settings.vue:98
-msgid "Changing your password will have the following consequences"
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "Changing your password will have the following consequences:"
 msgstr "Изменение вашего пароля приведёт к следующим последствиям"
 
 #: front/src/components/Footer.vue:40
+msgctxt "Footer/*/List item.Link"
 msgid "Chat room"
 msgstr ""
 
-#: front/src/App.vue:13
+#: front/src/components/auth/ApplicationForm.vue:24
+msgctxt "Content/Applications/Paragraph/"
+msgid "Checking the parent \"Read\" or \"Write\" scopes implies access to all the corresponding children scopes."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:2
+msgctxt "Popup/Instance/Title"
 msgid "Choose your instance"
 msgstr "Выберите свой узел"
 
-#: front/src/components/Home.vue:64
-msgid "Clean library"
-msgstr "Очистить библиотеку"
+#: front/src/components/library/EditForm.vue:75
+#, fuzzy
+msgctxt "Content/Library/Button.Label"
+msgid "Clear"
+msgstr "Очистить"
 
 #: front/src/components/manage/users/InvitationForm.vue:37
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Clear"
 msgstr "Очистить"
 
-#: front/src/components/playlists/Editor.vue:40
-#: front/src/components/playlists/Editor.vue:45
+#: front/src/components/playlists/Editor.vue:50
+#: front/src/components/playlists/Editor.vue:55
+#, fuzzy
+msgctxt "*/Playlist/Button.Label/Verb"
 msgid "Clear playlist"
 msgstr "Очистить список воспроизведения"
 
-#: front/src/components/audio/Player.vue:363
+#: front/src/components/audio/Player.vue:614
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Clear your queue"
 msgstr "Очистить вашу очередь"
 
 #: front/src/components/Home.vue:44
-#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Click once, listen for hours using built-in radios"
 msgstr "Нажмите один раз, слушайте часами с помощью встроенного радио"
 
-#: front/src/components/library/FileUpload.vue:75
+#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/mixins/Translations.vue:22
+msgctxt "Content/Library/Link.Title"
+msgid "Click to display more information about the import process for this upload"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:82
+msgctxt "Content/Library/Paragraph/Call to action"
 msgid "Click to select files to upload or drag and drop files or directories"
 msgstr "Нажмите чтобы выбрать файлы для загрузки или перетащите файлы или директории"
 
 #: front/src/components/ShortcutsModal.vue:20
+msgctxt "Popup/Keyboard shortcuts/Button.Label/Verb"
+msgid "Close"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:85
+#: front/src/components/library/ImportStatusModal.vue:79
+msgctxt "*/*/Button.Label/Verb"
 msgid "Close"
 msgstr ""
 
+#: front/src/components/federation/FetchButton.vue:88
+msgctxt "*/*/Button.Label/Verb"
+msgid "Close and reload page"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationForm.vue:26
 #: front/src/components/manage/users/InvitationsTable.vue:42
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Code"
 msgstr "Код"
 
-#: front/src/components/audio/album/Card.vue:43
+#: front/src/components/audio/album/Card.vue:41
 #: front/src/components/audio/artist/Card.vue:33
+#, fuzzy
+msgctxt "Content/*/Card.Link/Verb"
 msgid "Collapse"
 msgstr "Свернуть"
 
-#: front/src/components/library/radios/Builder.vue:62
-#, fuzzy
+#: front/src/components/library/radios/Builder.vue:63
+msgctxt "Content/Radio/Table.Label/Verb (Value is a List of Parameters)"
 msgid "Config"
 msgstr "Конфигурация"
 
 #: front/src/components/common/DangerousButton.vue:21
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Confirm"
 msgstr "Подтвердить"
 
-#: front/src/views/auth/EmailConfirm.vue:4 src/views/auth/EmailConfirm.vue:20
 #: front/src/views/auth/EmailConfirm.vue:51
-#, fuzzy
+msgctxt "Head/Signup/Title"
 msgid "Confirm your e-mail address"
 msgstr "Подтвердить ваш адрес электронной почты"
 
 #: front/src/views/auth/EmailConfirm.vue:13
+msgctxt "Content/Signup/Form.Label"
 msgid "Confirmation code"
 msgstr "Код подтверждения"
 
-#: front/src/components/common/ActionTable.vue:7
+#: front/src/components/moderation/FilterModal.vue:90
+msgctxt "*/Moderation/Message"
+msgid "Content filter successfully added"
+msgstr ""
+
+#: front/src/components/mixins/Translations.vue:96
+#: front/src/components/mixins/Translations.vue:97
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Content filters"
+msgstr "Выберите фильтр"
+
+#: front/src/components/auth/Settings.vue:116
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Content filters"
+msgstr "Выберите фильтр"
+
+#: front/src/components/auth/Settings.vue:119
+msgctxt "Content/Settings/Paragraph"
+msgid "Content filters help you hide content you don't want to see on the service."
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:8
+msgctxt "Content/*/Button.Help text.Paragraph"
 msgid "Content have been updated, click refresh to see up-to-date content"
 msgstr ""
 
 #: front/src/components/Footer.vue:48
+msgctxt "Footer/*/List item.Link"
 msgid "Contribute"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:19
 #: front/src/components/common/CopyInput.vue:8
+#, fuzzy
+msgctxt "*/*/Button.Label/Short, Verb"
 msgid "Copy"
 msgstr "Копировать"
 
-#: front/src/components/playlists/Editor.vue:163
-msgid "Copy tracks from current queue to playlist"
+#: front/src/components/playlists/Editor.vue:194
+msgctxt "Content/Playlist/Button.Tooltip/Verb"
+msgid "Copy queued tracks to playlist"
 msgstr "Копировать треки из текущей очереди в список воспроизведения"
 
+#: front/src/components/auth/Authorize.vue:55
+msgctxt "Content/Auth/Paragraph"
+msgid "Copy-paste the following code in the application:"
+msgstr ""
+
 #: front/src/components/audio/EmbedWizard.vue:21
+msgctxt "Popup/Embed/Paragraph"
 msgid "Copy/paste this code in your website HTML"
 msgstr ""
 
-#: front/src/components/library/Track.vue:91
-#, fuzzy
+#: front/src/components/library/TrackDetail.vue:10
+#: front/src/views/admin/library/TrackDetail.vue:153
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Copyright"
 msgstr "Копировать"
 
 #: front/src/views/auth/EmailConfirm.vue:7
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "Could not confirm your e-mail address"
 msgstr "Подтвердить ваш адрес электронной почты"
 
 #: front/src/views/content/remote/ScanForm.vue:3
-#, fuzzy
+msgctxt "Content/Library/Error message.Title"
 msgid "Could not fetch remote library"
 msgstr "Ошибка во время загрузки удалённой библиотеки"
 
-#: front/src/views/content/libraries/FilesTable.vue:213
-#, fuzzy
-msgid "Could not process this track, ensure it is tagged correctly"
-msgstr "Произошла ошибка во время обработки этого трека, убедитесь что у него корректные теги"
-
-#: front/src/components/Home.vue:85
+#: front/src/components/Home.vue:80
+msgctxt "Content/Home/List item"
 msgid "Covers, lyrics, our goal is to have them all ;)"
 msgstr "Обложки, тексты, наша цель собрать их все ;)"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:58
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Create"
 msgstr "Создать импорт"
 
 #: front/src/components/auth/Signup.vue:4
+#, fuzzy
+msgctxt "Content/Signup/Title"
 msgid "Create a funkwhale account"
 msgstr "Создать аккаунт funkwhale"
 
+#: front/src/components/auth/ApplicationNew.vue:8
+#: front/src/components/auth/ApplicationNew.vue:34
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Create a new application"
+msgstr "Создать новый список воспроизведения"
+
+#: front/src/components/auth/Settings.vue:220
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Create a new application"
+msgstr "Создать новый список воспроизведения"
+
 #: front/src/views/content/libraries/Home.vue:14
+msgctxt "Content/Library/Link/Verb"
 msgid "Create a new library"
 msgstr "Создать новую библиотеку"
 
 #: front/src/components/playlists/Form.vue:2
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Create a new playlist"
 msgstr "Создать новый список воспроизведения"
 
 #: front/src/components/Sidebar.vue:57 src/components/auth/Login.vue:17
+#, fuzzy
+msgctxt "*/Signup/Link/Verb"
 msgid "Create an account"
 msgstr "Создать новый аккаунт"
 
+#: front/src/components/auth/ApplicationForm.vue:65
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Create application"
+msgstr "Создать список воспроизведения"
+
 #: front/src/views/content/libraries/Form.vue:26
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Create library"
 msgstr "Создать библиотеку"
 
-#: front/src/components/auth/Signup.vue:51
+#: front/src/components/auth/Signup.vue:53
+#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Create my account"
 msgstr "Создать мой аккаунт"
 
+#: front/src/components/auth/Settings.vue:264
+msgctxt "Content/Applications/Paragraph"
+msgid "Create one to integrate Funkwhale with third-party applications."
+msgstr ""
+
 #: front/src/components/playlists/Form.vue:34
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Create playlist"
 msgstr "Создать список воспроизведения"
 
 #: front/src/components/library/Radios.vue:23
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Create your own radio"
 msgstr "Создать ваше собственное радио"
 
+#: front/src/components/auth/Settings.vue:134
+#: src/components/auth/Settings.vue:227
+#: front/src/components/manage/library/AlbumsTable.vue:44
+#: front/src/components/manage/library/ArtistsTable.vue:43
+#: front/src/components/manage/library/LibrariesTable.vue:54
+#: front/src/components/manage/library/TracksTable.vue:44
+#: front/src/components/manage/library/UploadsTable.vue:66
 #: front/src/components/manage/users/InvitationsTable.vue:40
-#: front/src/components/mixins/Translations.vue:16
-#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:43
+#: front/src/components/mixins/Translations.vue:44
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Creation date"
 msgstr "Дата создания"
 
 #: front/src/components/auth/Settings.vue:54
+msgctxt "Content/Settings/Title/Noun"
 msgid "Current avatar"
 msgstr "Текущий аватар"
 
 #: front/src/views/content/libraries/DetailArea.vue:4
+msgctxt "Content/Library/Title"
 msgid "Current library"
 msgstr "Текущая библиотека"
 
 #: front/src/components/playlists/PlaylistModal.vue:8
+msgctxt "Popup/Playlist/Title"
 msgid "Current track"
 msgstr "Текущий трек"
 
 #: front/src/views/content/libraries/Quota.vue:2
+msgctxt "Content/Library/Title"
 msgid "Current usage"
 msgstr "Текущее использование"
 
+#: front/src/components/federation/FetchButton.vue:53
+msgctxt "*/*/Error"
+msgid "Data returned by the remote server had invalid or missing attributes"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:17
+msgctxt "Popup/*/Message.Content"
+msgid "Data was refreshed successfully from remote server."
+msgstr ""
+
 #: front/src/views/content/libraries/Detail.vue:27
+msgctxt "Content/Library/Table.Label"
 msgid "Date"
 msgstr "Дата"
 
+#: front/src/components/library/ImportStatusModal.vue:64
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Debug information"
+msgstr "Информация о треке"
+
 #: front/src/components/ShortcutsModal.vue:75
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Decrease volume"
 msgstr ""
 
-#: front/src/components/manage/library/FilesTable.vue:190
+#: front/src/components/auth/Settings.vue:150
+#: src/components/auth/Settings.vue:251
+#: front/src/components/library/EditCard.vue:93
+#: front/src/components/library/EditCard.vue:98
+#: front/src/components/manage/library/AlbumsTable.vue:188
+#: front/src/components/manage/library/ArtistsTable.vue:178
+#: front/src/components/manage/library/LibrariesTable.vue:205
+#: front/src/components/manage/library/TracksTable.vue:188
+#: front/src/components/manage/library/UploadsTable.vue:255
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:61
 #: front/src/components/manage/users/InvitationsTable.vue:167
-#: front/src/views/content/libraries/FilesTable.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:72
+#: front/src/views/admin/library/AlbumDetail.vue:77
+#: front/src/views/admin/library/ArtistDetail.vue:71
+#: front/src/views/admin/library/ArtistDetail.vue:76
+#: front/src/views/admin/library/LibraryDetail.vue:58
+#: front/src/views/admin/library/LibraryDetail.vue:63
+#: front/src/views/admin/library/TrackDetail.vue:71
+#: front/src/views/admin/library/TrackDetail.vue:76
+#: front/src/views/admin/library/UploadDetail.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:70
+#: front/src/views/content/libraries/FilesTable.vue:222
 #: front/src/views/content/libraries/Form.vue:29
-#: src/views/playlists/Detail.vue:33
+#: src/views/playlists/Detail.vue:34
+msgctxt "*/*/*/Verb"
 msgid "Delete"
 msgstr "Удалить"
 
+#: front/src/components/auth/Settings.vue:254
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Delete application"
+msgstr "Удалить список воспроизведения"
+
+#: front/src/components/auth/Settings.vue:252
+msgctxt "Popup/Settings/Title"
+msgid "Delete application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:39
+msgctxt "Popup/Library/Button.Label/Verb"
 msgid "Delete library"
 msgstr "Удалить библиотеку"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:69
-#, fuzzy
+msgctxt "Popup/Moderation/Button.Label/Verb"
 msgid "Delete moderation rule"
 msgstr "Удалить радио"
 
-#: front/src/views/playlists/Detail.vue:38
+#: front/src/views/playlists/Detail.vue:39
+msgctxt "Popup/Playlist/Button.Label/Verb"
 msgid "Delete playlist"
 msgstr "Удалить список воспроизведения"
 
 #: front/src/views/radios/Detail.vue:28
+msgctxt "Popup/Radio/Button.Label/Verb"
 msgid "Delete radio"
 msgstr "Удалить радио"
 
+#: front/src/views/admin/library/AlbumDetail.vue:73
+#: front/src/views/admin/library/TrackDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this album?"
+msgstr "Удалить эту библиотеку?"
+
+#: front/src/views/admin/library/ArtistDetail.vue:72
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this artist?"
+msgstr "Удалить эту библиотеку?"
+
+#: front/src/views/admin/library/LibraryDetail.vue:59
 #: front/src/views/content/libraries/Form.vue:31
+msgctxt "Popup/Library/Title"
 msgid "Delete this library?"
 msgstr "Удалить эту библиотеку?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:63
-#, fuzzy
+msgctxt "Popup/Moderation/Title"
 msgid "Delete this moderation rule?"
 msgstr "Удалить эту библиотеку?"
 
-#: front/src/components/favorites/List.vue:34
-#: src/components/library/Artists.vue:26
-#: front/src/components/library/Radios.vue:47
-#: front/src/components/manage/library/FilesTable.vue:20
+#: front/src/components/library/EditCard.vue:94
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this suggestion?"
+msgstr "Удалить эту библиотеку?"
+
+#: front/src/views/admin/library/UploadDetail.vue:66
+#, fuzzy
+msgctxt "Popup/Library/Title"
+msgid "Delete this upload?"
+msgstr "Удалить эту библиотеку?"
+
+#: front/src/components/favorites/List.vue:35
+#: src/components/library/Albums.vue:26
+#: front/src/components/library/Artists.vue:26
+#: src/components/library/Radios.vue:47
+#: front/src/components/manage/library/AlbumsTable.vue:22
+#: front/src/components/manage/library/ArtistsTable.vue:22
+#: front/src/components/manage/library/EditsCardList.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:31
+#: front/src/components/manage/library/TracksTable.vue:22
+#: front/src/components/manage/library/UploadsTable.vue:41
 #: front/src/components/manage/moderation/AccountsTable.vue:22
 #: front/src/components/manage/moderation/DomainsTable.vue:20
 #: front/src/components/manage/users/UsersTable.vue:20
 #: front/src/views/content/libraries/FilesTable.vue:32
 #: front/src/views/playlists/List.vue:28
+msgctxt "Content/Search/Dropdown"
 msgid "Descending"
 msgstr "По убыванию"
 
 #: front/src/components/library/radios/Builder.vue:25
 #: front/src/views/content/libraries/Form.vue:14
+#, fuzzy
+msgctxt "Content/*/Input.Label/Noun"
 msgid "Description"
 msgstr "Описание"
 
-#: front/src/views/content/libraries/Card.vue:47
+#: front/src/views/admin/library/LibraryDetail.vue:123
 #, fuzzy
-msgid "Detail"
-msgstr "Подробность"
+msgctxt "*/*/*/Noun"
+msgid "Description"
+msgstr "Описание"
 
-#: front/src/views/content/remote/Card.vue:50
-#, fuzzy
+#: front/src/views/content/libraries/Card.vue:48
+#: src/views/content/remote/Card.vue:54
+msgctxt "Content/Library/Card.Button.Label/Noun"
 msgid "Details"
 msgstr "Подробности"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:455
+#: front/src/views/admin/moderation/AccountsDetail.vue:491
+msgctxt "Content/Moderation/Help text"
 msgid "Determine how much content the user can upload. Leave empty to use the default value of the instance."
 msgstr "Выберите как много содержимого пользователь может загрузить. Оставьте пустым чтобы использовать значение по умолчанию для данного узла."
 
 #: front/src/components/mixins/Translations.vue:8
 #: front/src/components/mixins/Translations.vue:9
+msgctxt "Content/Settings/Dropdown.Help text"
 msgid "Determine the visibility level of your activity"
 msgstr "Определить уровень видимости вашей активности"
 
 #: front/src/components/auth/Settings.vue:104
-#: front/src/components/auth/SubsonicTokenForm.vue:52
+#: front/src/components/auth/SubsonicTokenForm.vue:51
+msgctxt "Popup/Settings/Button.Label"
 msgid "Disable access"
 msgstr "Отключить доступ"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:49
+#: front/src/components/auth/SubsonicTokenForm.vue:48
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Disable Subsonic access"
 msgstr "Отключить доступ Subsonic"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:50
+#: front/src/components/auth/SubsonicTokenForm.vue:49
+msgctxt "Popup/Settings/Title"
 msgid "Disable Subsonic API access?"
 msgstr "Отключить доступ Subsonic API?"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:18
-#: front/src/views/admin/moderation/AccountsDetail.vue:128
-#: front/src/views/admin/moderation/AccountsDetail.vue:132
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:157
+#: front/src/views/admin/moderation/AccountsDetail.vue:161
+msgctxt "*/*/*"
 msgid "Disabled"
 msgstr "Отключить доступ"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:14
+#: front/src/views/admin/library/TrackDetail.vue:145
+msgctxt "*/*/*/Noun"
+msgid "Disc number"
+msgstr ""
+
+#: front/src/components/auth/SubsonicTokenForm.vue:13
+msgctxt "Content/Settings/Link"
 msgid "Discover how to use Funkwhale from other apps"
 msgstr "Узнайте как использовать Funkwhale из других приложений"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:103
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:132
+msgctxt "'Content/*/*/Noun'"
 msgid "Display name"
 msgstr "Имя файла"
 
 #: front/src/components/library/radios/Builder.vue:30
+msgctxt "Content/Radio/Checkbox.Label/Verb"
 msgid "Display publicly"
 msgstr "Публично отображать"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:122
+msgctxt "Content/Moderation/Help text"
 msgid "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."
 msgstr ""
 
-#: front/src/components/playlists/Editor.vue:42
+#: front/src/components/playlists/Editor.vue:51
+msgctxt "Popup/Playlist/Title"
 msgid "Do you want to clear the playlist \"%{ playlist }\"?"
 msgstr "Вы хотите очистить список воспроизведения \"%{ playlist }\"?"
 
 #: front/src/components/common/DangerousButton.vue:7
+msgctxt "Modal/*/Title"
 msgid "Do you want to confirm this action?"
 msgstr "Вы хотите подтвердить это действие?"
 
 #: front/src/views/playlists/Detail.vue:35
+msgctxt "Popup/Playlist/Title/Call to action"
 msgid "Do you want to delete the playlist \"%{ playlist }\"?"
 msgstr "Вы хотите удалить список воспроизведения \"%{ playlist }\"?"
 
 #: front/src/views/radios/Detail.vue:26
+msgctxt "Popup/Radio/Title"
 msgid "Do you want to delete the radio \"%{ radio }\"?"
 msgstr "Вы хотите удалить радио \"%{ radio }\"?"
 
-#: front/src/components/common/ActionTable.vue:36
+#: front/src/components/moderation/FilterModal.vue:3
+#, fuzzy
+msgctxt "Popup/Moderation/Title/Verb"
+msgid "Do you want to hide content from artist \"%{ name }\"?"
+msgstr "Вы хотите удалить радио \"%{ radio }\"?"
+
+#: front/src/components/common/ActionTable.vue:37
+#, fuzzy
+msgctxt "Modal/*/Title"
 msgid "Do you want to launch %{ action } on %{ count } element?"
 msgid_plural "Do you want to launch %{ action } on %{ count } elements?"
 msgstr[0] "Вы хотите запустить %{ action } на %{ count } элементе?"
 msgstr[1] "Вы хотите запустить %{ action } на %{ count } элементах?"
 msgstr[2] "Вы хотите запустить %{ action } на %{ count } элементах?"
 
-#: front/src/components/Sidebar.vue:107
+#: front/src/components/Sidebar.vue:118
+msgctxt "Sidebar/Queue/Message"
 msgid "Do you want to restore your previous queue?"
 msgstr "Вы хотите восстановить вашу предыдущую очередь?"
 
 #: front/src/components/Footer.vue:31
+msgctxt "Footer/*/List item.Link/Short, Noun"
 msgid "Documentation"
 msgstr "Документация"
 
+#: front/src/components/manage/library/AlbumsTable.vue:41
+#: front/src/components/manage/library/ArtistsTable.vue:40
+#: front/src/components/manage/library/LibrariesTable.vue:50
+#: front/src/components/manage/library/TracksTable.vue:42
+#: front/src/components/manage/library/UploadsTable.vue:62
 #: front/src/components/manage/moderation/AccountsTable.vue:40
-#: front/src/components/mixins/Translations.vue:34
-#: front/src/views/admin/moderation/AccountsDetail.vue:93
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:60
+#: front/src/views/admin/library/AlbumDetail.vue:118
+#: front/src/views/admin/library/ArtistDetail.vue:107
+#: front/src/views/admin/library/LibraryDetail.vue:114
+#: front/src/views/admin/library/TrackDetail.vue:170
+#: front/src/views/admin/library/UploadDetail.vue:121
+#: front/src/views/admin/moderation/AccountsDetail.vue:123
+#: front/src/components/mixins/Translations.vue:61
+msgctxt "Content/Moderation/*/Noun"
 msgid "Domain"
 msgstr ""
 
 #: front/src/views/admin/moderation/Base.vue:5
 #: front/src/views/admin/moderation/DomainsList.vue:3
 #: front/src/views/admin/moderation/DomainsList.vue:48
+msgctxt "*/Moderation/*/Noun"
 msgid "Domains"
 msgstr ""
 
-#: front/src/components/library/Track.vue:55
+#: front/src/components/library/TrackBase.vue:39
+#: front/src/views/admin/library/UploadDetail.vue:58
+msgctxt "Content/Track/Link/Verb"
 msgid "Download"
 msgstr "Скачать"
 
-#: front/src/components/playlists/Editor.vue:49
+#: front/src/components/playlists/Editor.vue:59
+msgctxt "Content/Playlist/Paragraph/Call to action"
 msgid "Drag and drop rows to reorder tracks in the playlist"
 msgstr "Перетаскивайте строки чтобы упорядочить треки в списке воспроизведения"
 
-#: front/src/components/audio/track/Table.vue:9
-#: src/components/library/Track.vue:111
-#: front/src/components/manage/library/FilesTable.vue:43
-#: front/src/components/mixins/Translations.vue:30
-#: front/src/views/content/libraries/FilesTable.vue:59
-#: front/src/components/mixins/Translations.vue:31
+#: front/src/components/audio/track/Table.vue:10
+#: front/src/components/library/TrackDetail.vue:30
+#: front/src/components/mixins/Translations.vue:56
+#: front/src/views/admin/library/UploadDetail.vue:238
+#: front/src/views/content/libraries/FilesTable.vue:60
+#: front/src/components/mixins/Translations.vue:57
+msgctxt "Content/*/*"
 msgid "Duration"
 msgstr "Длительность"
 
 #: front/src/views/auth/EmailConfirm.vue:23
-#, fuzzy
+msgctxt "Content/Signup/Message"
 msgid "E-mail address confirmed"
 msgstr "Адрес электронной почты подтверждён"
 
-#: front/src/components/Home.vue:93
-#, fuzzy
+#: front/src/components/Home.vue:88
+msgctxt "Content/Home/Title"
 msgid "Easy to use"
 msgstr "Легко в использовании"
 
+#: front/src/components/library/AlbumBase.vue:68
+#: front/src/components/library/ArtistBase.vue:79
+#: front/src/components/library/TrackBase.vue:87
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
+#: front/src/components/radios/Card.vue:23
+#: src/views/admin/library/AlbumDetail.vue:65
+#: front/src/views/admin/library/ArtistDetail.vue:64
+#: front/src/views/admin/library/TrackDetail.vue:64
 #: front/src/views/content/libraries/Detail.vue:9
+#: src/views/playlists/Detail.vue:31
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Edit"
 msgstr "Редактировать"
 
-#: front/src/components/About.vue:21
+#: front/src/components/auth/Settings.vue:246
+#, fuzzy
+msgctxt "Content/Settings/Button.Label"
+msgid "Edit"
+msgstr "Редактировать"
+
+#: front/src/components/auth/ApplicationEdit.vue:30
+#: front/src/components/auth/ApplicationEdit.vue:75
+#, fuzzy
+msgctxt "Content/Applications/Title"
+msgid "Edit application"
+msgstr "Ошибка во время применения действия"
+
+#: front/src/components/About.vue:22
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Edit instance info"
 msgstr "Редактировать информацию об узле"
 
-#: front/src/components/radios/Card.vue:22 src/views/playlists/Detail.vue:30
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title/Verb"
+msgid "Edit moderation rule"
+msgstr "Удалить радио"
+
+#: front/src/components/library/AlbumEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this album"
+msgstr "Проиграть трек"
+
+#: front/src/components/library/ArtistEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this artist"
+msgstr "Проиграть трек"
+
+#: front/src/components/library/TrackEdit.vue:4
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Edit this track"
+msgstr "Проиграть трек"
+
+#: front/src/views/admin/library/AlbumDetail.vue:182
+#: front/src/views/admin/library/ArtistDetail.vue:171
+#: front/src/views/admin/library/Base.vue:5
+#: src/views/admin/library/EditsList.vue:24
+#: front/src/views/admin/library/TrackDetail.vue:234
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
+msgid "Edits"
+msgstr "Редактировать"
+
+#: front/src/components/mixins/Translations.vue:104
+#: front/src/components/mixins/Translations.vue:105
 #, fuzzy
-msgid "Edit…"
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Edits"
 msgstr "Редактировать"
 
-#: front/src/components/auth/Signup.vue:29
+#: front/src/components/auth/Signup.vue:30
 #: front/src/components/manage/users/UsersTable.vue:38
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Email"
 msgstr "Электронная почта"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:111
+#: front/src/views/admin/moderation/AccountsDetail.vue:140
+msgctxt "Content/*/*"
 msgid "Email address"
 msgstr "Адрес электронной почты"
 
-#: front/src/components/library/Album.vue:44
-#: src/components/library/Track.vue:62
+#: front/src/components/library/AlbumBase.vue:53
+#: front/src/components/library/ArtistBase.vue:64
+#: front/src/components/library/TrackBase.vue:72
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Embed"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:20
+msgctxt "Popup/Embed/Input.Label/Noun"
 msgid "Embed code"
 msgstr ""
 
-#: front/src/components/library/Album.vue:48
+#: front/src/components/library/AlbumBase.vue:26
+msgctxt "Popup/Album/Title/Verb"
 msgid "Embed this album on your website"
 msgstr ""
 
-#: front/src/components/library/Track.vue:66
+#: front/src/components/library/ArtistBase.vue:37
+msgctxt "Popup/Artist/Title/Verb"
+msgid "Embed this artist work on your website"
+msgstr ""
+
+#: front/src/components/library/TrackBase.vue:45
+msgctxt "Popup/Track/Title"
 msgid "Embed this track on your website"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:230
+#: front/src/views/admin/moderation/AccountsDetail.vue:259
 #: front/src/views/admin/moderation/DomainsDetail.vue:187
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted library follows"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:214
+#: front/src/views/admin/moderation/AccountsDetail.vue:243
 #: front/src/views/admin/moderation/DomainsDetail.vue:171
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Emitted messages"
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:8
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:17
-#: front/src/views/admin/moderation/AccountsDetail.vue:127
-#: front/src/views/admin/moderation/AccountsDetail.vue:131
+#: front/src/views/admin/moderation/AccountsDetail.vue:156
+#: front/src/views/admin/moderation/AccountsDetail.vue:160
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Enabled"
-msgstr ""
+msgstr "Отключить доступ"
 
-#: front/src/views/playlists/Detail.vue:29
+#: front/src/views/playlists/Detail.vue:30
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "End edition"
 msgstr "Закончить редактирование"
 
 #: front/src/views/content/remote/ScanForm.vue:50
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder"
 msgid "Enter a library URL"
 msgstr "Очистить библиотеку"
 
-#: front/src/components/library/Radios.vue:140
-#, fuzzy
+#: front/src/components/library/Radios.vue:141
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter a radio name…"
 msgstr "Введите название радио..."
 
-#: front/src/components/library/Artists.vue:118
-#, fuzzy
+#: front/src/components/library/Albums.vue:119
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Enter album title..."
+msgstr ""
+
+#: front/src/components/library/Artists.vue:116
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Enter artist name…"
 msgstr "Введите имя исполнителя..."
 
 #: front/src/views/playlists/List.vue:107
-#, fuzzy
+msgctxt "Content/Playlist/Placeholder/Call to action"
 msgid "Enter playlist name…"
 msgstr "Введите название списка воспроизведения..."
 
-#: front/src/components/auth/Signup.vue:100
+#: front/src/views/auth/PasswordReset.vue:54
+msgctxt "Content/Signup/Input.Placeholder"
+msgid "Enter the email address binded to your account"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:103
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your email"
 msgstr "Введите ваш адрес электронной почты"
 
-#: front/src/components/auth/Signup.vue:96 src/components/auth/Signup.vue:97
+#: front/src/components/auth/Signup.vue:98 src/components/auth/Signup.vue:100
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your invitation code (case insensitive)"
 msgstr "Введите ваш код приглашения (нечувствительно к регистру)"
 
 #: front/src/components/metadata/Search.vue:114
-#, fuzzy
+msgctxt "Content/Library/Input.Placeholder/Verb"
 msgid "Enter your search query…"
 msgstr "Введите ваш поисковый запрос..."
 
-#: front/src/components/auth/Signup.vue:99
+#: front/src/components/auth/Signup.vue:102
+msgctxt "Content/Signup/Form/Placeholder"
 msgid "Enter your username"
 msgstr "Введите ваше имя пользователя"
 
-#: front/src/components/auth/Login.vue:77
+#: front/src/components/auth/Login.vue:83
+msgctxt "Content/Login/Input.Placeholder"
 msgid "Enter your username or email"
 msgstr "Введите ваше имя пользователя или адрес электронной почты"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:20
+#: front/src/components/auth/SubsonicTokenForm.vue:19
 #: front/src/views/content/libraries/Form.vue:4
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error"
 msgstr "Ошибка"
 
+#: front/src/components/federation/FetchButton.vue:34
+#: front/src/components/library/ImportStatusModal.vue:32
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error detail"
+msgstr "Ошибка во время создания приглашения"
+
 #: front/src/views/admin/Settings.vue:87
+#, fuzzy
+msgctxt "Content/Admin/Menu"
 msgid "Error reporting"
-msgstr ""
+msgstr "Ошибка во время создания приглашения"
+
+#: front/src/components/federation/FetchButton.vue:26
+#: front/src/components/library/ImportStatusModal.vue:24
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Error type"
+msgstr "Ошибочно"
 
-#: front/src/components/common/ActionTable.vue:92
+#: front/src/components/common/ActionTable.vue:94
+msgctxt "Content/*/Error message/Header"
 msgid "Error while applying action"
 msgstr "Ошибка во время применения действия"
 
 #: front/src/views/auth/PasswordReset.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while asking for a password reset"
 msgstr "Ошибка во время запроса сброса пароля"
 
+#: front/src/components/auth/Authorize.vue:6
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while authorizing application"
+msgstr "Ошибка во время применения действия"
+
 #: front/src/views/auth/PasswordResetConfirm.vue:7
+msgctxt "Content/Signup/Card.Title"
 msgid "Error while changing your password"
 msgstr "Ошибка во время изменения вашего пароля"
 
 #: front/src/views/admin/moderation/DomainsList.vue:6
-#, fuzzy
+msgctxt "Content/Moderation/Message.Title"
 msgid "Error while creating domain"
 msgstr "Ошибка во время создания приглашения"
 
+#: front/src/components/moderation/FilterModal.vue:13
+#, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while creating filter"
+msgstr "Ошибка во время создания приглашения"
+
 #: front/src/components/manage/users/InvitationForm.vue:4
+msgctxt "Content/Admin/Error message.Title"
 msgid "Error while creating invitation"
 msgstr "Ошибка во время создания приглашения"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:7
-#, fuzzy
+msgctxt "Content/Moderation/Error message.Title"
 msgid "Error while creating rule"
 msgstr "Ошибка во время создания приглашения"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:126
+#: front/src/components/auth/Authorize.vue:7
 #, fuzzy
+msgctxt "Popup/Moderation/Error message"
+msgid "Error while fetching application data"
+msgstr "Ошибка во время создания приглашения"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:118
+msgctxt "Content/Moderation/Table"
 msgid "Error while fetching node info"
 msgstr "Ошибка во время загрузки удалённой библиотеки"
 
 #: front/src/components/admin/SettingsGroup.vue:5
+msgctxt "Content/Settings/Error message.Title"
+msgid "Error while saving settings"
+msgstr "Ошибка во время сохранения настроек"
+
+#: front/src/components/federation/FetchButton.vue:73
+#, fuzzy
+msgctxt "Content/*/Error message.Title"
 msgid "Error while saving settings"
 msgstr "Ошибка во время сохранения настроек"
 
-#: front/src/views/content/libraries/FilesTable.vue:212
+#: front/src/components/library/EditForm.vue:46
 #, fuzzy
+msgctxt "Content/Library/Error message.Title"
+msgid "Error while submitting edit"
+msgstr "Ошибка во время сохранения настроек"
+
+#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:33
+msgctxt "Content/Library/Table/Short"
 msgid "Errored"
 msgstr "Ошибочно"
 
 #: front/src/views/content/libraries/Quota.vue:75
+msgctxt "Content/Library/Label"
 msgid "Errored files"
 msgstr "Ошибочные файлы"
 
-#: front/src/components/playlists/Form.vue:89
+#: front/src/components/mixins/Translations.vue:17
+#: front/src/components/mixins/Translations.vue:18
+#, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
 msgid "Everyone"
 msgstr "Все"
 
 #: front/src/components/mixins/Translations.vue:11
-#: front/src/components/playlists/Form.vue:85
-#: src/views/content/libraries/Form.vue:73
 #: front/src/components/mixins/Translations.vue:12
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone on this instance"
 msgstr "Все на этом узле"
 
-#: front/src/views/content/libraries/Form.vue:74
+#: front/src/components/mixins/Translations.vue:12
+#: front/src/components/mixins/Translations.vue:13
 #, fuzzy
+msgctxt "Content/Settings/Dropdown"
 msgid "Everyone, across all instances"
 msgstr "Все на этом узле"
 
-#: front/src/components/library/radios/Builder.vue:61
+#: front/src/components/library/radios/Builder.vue:62
+msgctxt "Content/Radio/Table.Label/Verb"
 msgid "Exclude"
 msgstr "Исключить"
 
 #: front/src/components/manage/users/InvitationsTable.vue:41
-#: front/src/components/mixins/Translations.vue:22
-#: front/src/components/mixins/Translations.vue:23
+#: front/src/components/mixins/Translations.vue:49
+#: front/src/components/mixins/Translations.vue:50
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Expiration date"
 msgstr "Дата истечения"
 
 #: front/src/components/manage/users/InvitationsTable.vue:50
+msgctxt "Content/Admin/Table"
 msgid "Expired"
 msgstr "Истёк"
 
 #: front/src/components/manage/users/InvitationsTable.vue:21
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Expired/used"
 msgstr "Истёк/использован"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:110
+msgctxt "Content/Moderation/Help text"
 msgid "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."
 msgstr ""
 
+#: front/src/components/manage/library/UploadsTable.vue:25
 #: front/src/views/content/libraries/FilesTable.vue:16
+#, fuzzy
+msgctxt "Content/Library/Dropdown"
 msgid "Failed"
-msgstr ""
+msgstr "Ошибочные треки:"
 
-#: front/src/views/content/remote/Card.vue:58
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:62
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Failed tracks:"
 msgstr "Ошибочные треки:"
 
+#: front/src/views/admin/library/AlbumDetail.vue:165
+#: front/src/views/admin/library/ArtistDetail.vue:154
+#: front/src/views/admin/library/TrackDetail.vue:217
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Favorited tracks"
+msgstr "Ошибочные треки:"
+
+#: front/src/components/mixins/Translations.vue:76
+#: front/src/components/mixins/Translations.vue:77
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Favorites"
+msgstr "Избранное"
+
 #: front/src/components/Sidebar.vue:66
+msgctxt "Sidebar/Favorites/List item.Link/Noun"
 msgid "Favorites"
 msgstr "Избранное"
 
 #: front/src/views/admin/Settings.vue:84
+msgctxt "Content/Admin/Menu"
 msgid "Federation"
 msgstr "Федерация"
 
-#: front/src/components/library/FileUpload.vue:84
+#: front/src/components/library/TrackDetail.vue:66
 #, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Federation ID"
+msgstr "Федерация"
+
+#: front/src/components/library/EditCard.vue:45
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Field"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:93
+msgctxt "Content/Library/Table.Label"
 msgid "Filename"
 msgstr "Имя файла"
 
-#: front/src/views/admin/library/Base.vue:5
-#: src/views/admin/library/FilesList.vue:21
-msgid "Files"
-msgstr "Файлы"
-
-#: front/src/components/library/radios/Builder.vue:60
+#: front/src/components/library/radios/Builder.vue:61
+msgctxt "Content/Radio/Table.Label/Noun"
 msgid "Filter name"
 msgstr "Имя фильтра"
 
+#: front/src/components/manage/library/UploadsTable.vue:26
+#: front/src/components/mixins/Translations.vue:36
 #: front/src/views/content/libraries/FilesTable.vue:17
-#: front/src/views/content/libraries/FilesTable.vue:216
+#: front/src/components/mixins/Translations.vue:37
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Finished"
 msgstr "Завершено"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:42
 #: front/src/components/manage/moderation/DomainsTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:159
-#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#: front/src/views/admin/library/AlbumDetail.vue:149
+#: front/src/views/admin/library/ArtistDetail.vue:138
+#: front/src/views/admin/library/LibraryDetail.vue:153
+#: front/src/views/admin/library/TrackDetail.vue:201
+#: front/src/views/admin/library/UploadDetail.vue:167
+#: front/src/views/admin/moderation/AccountsDetail.vue:235
+#: front/src/views/admin/moderation/DomainsDetail.vue:151
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short (Value is a date)"
 msgid "First seen"
-msgstr ""
+msgstr "Дата истечения"
 
-#: front/src/components/mixins/Translations.vue:17
-#: front/src/components/mixins/Translations.vue:18
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:46
+#: front/src/components/mixins/Translations.vue:47
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "First seen date"
 msgstr "Дата истечения"
 
-#: front/src/views/content/remote/Card.vue:83
+#: front/src/views/content/remote/Card.vue:87
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Follow"
 msgstr "Подписаться"
 
 #: front/src/views/content/Home.vue:16
+msgctxt "Content/Library/Title/Verb"
 msgid "Follow remote libraries"
 msgstr "Подписаться на удалённые библиотеки"
 
-#: front/src/views/content/remote/Card.vue:88
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:92
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Follow request pending approval"
 msgstr "Подписка требует подтверждения"
 
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/mixins/Translations.vue:64
+#: front/src/views/admin/library/LibraryDetail.vue:161
 #: front/src/views/content/libraries/Detail.vue:7
-#: front/src/components/mixins/Translations.vue:39
+#: front/src/components/mixins/Translations.vue:65
+msgctxt "Content/Federation/*/Noun"
+msgid "Followers"
+msgstr "Подписчики"
+
+#: front/src/components/manage/library/LibrariesTable.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Followers"
 msgstr "Подписчики"
 
-#: front/src/views/content/remote/Card.vue:93
+#: front/src/views/content/remote/Card.vue:97
+#, fuzzy
+msgctxt "Content/Library/Card.Paragraph"
 msgid "Following"
+msgstr "Подписаться"
+
+#: front/src/components/mixins/Translations.vue:84
+#: front/src/components/mixins/Translations.vue:85
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Follows"
+msgstr "Подписаться"
+
+#: front/src/components/library/TrackBase.vue:17
+msgctxt "Content/Track/Paragraph"
+msgid "From album <a class=\"internal\" href=\"%{ albumUrl }\">%{ album }</a> by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
 msgstr ""
 
-#: front/src/components/library/Track.vue:17
-msgid "From album %{ album } by %{ artist }"
-msgstr "Из альбома %{ album } от %{ artist }"
+#: front/src/components/auth/Authorize.vue:28
+#, fuzzy
+msgctxt "Content/Auth/Label/Noun"
+msgid "Full access"
+msgstr "Отключить доступ"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph'"
 msgid "Funkwhale is compatible with other music players that support the Subsonic API."
 msgstr "Funkwhale совместим с другими музыкальными плеерами которые поддерживают Subsonic API."
 
-#: front/src/components/Home.vue:95
-#, fuzzy
+#: front/src/components/Home.vue:90
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is dead simple to use."
 msgstr "Funkwhale чрезвычайно прост в использовании."
 
 #: front/src/components/Home.vue:39
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is designed to make it easy to listen to music you like, or to discover new artists."
 msgstr "Funkwhale создан чтобы упростить прослушивание любимой музыки и поиск новых исполнителей."
 
-#: front/src/components/Home.vue:116
+#: front/src/components/Home.vue:111
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale is free and gives you control on your music."
 msgstr "Funkwhale свободен и предоставляет вам контроль над вашей музыкой."
 
 #: front/src/components/Home.vue:66
-#, fuzzy
+msgctxt "Content/Home/Paragraph"
 msgid "Funkwhale takes care of handling your music"
 msgstr "Funkwhale заботится об управлении вашей музыкой"
 
 #: front/src/components/ShortcutsModal.vue:38
+msgctxt "Popup/Keyboard shortcuts/Title"
 msgid "General shortcuts"
 msgstr ""
 
 #: front/src/components/manage/users/InvitationForm.vue:16
+msgctxt "Content/Admin/Button.Label/Verb"
 msgid "Get a new invitation"
 msgstr "Получить приглашение"
 
 #: front/src/components/Home.vue:13
-#, fuzzy
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Get me to the library"
 msgstr "Перейти в библиотеку"
 
-#: front/src/components/Home.vue:76
+#: front/src/components/Home.vue:70
+#, fuzzy
+msgctxt "Content/Home/List item/Verb"
 msgid "Get quality metadata about your music thanks to <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 msgstr "Получайте качественные метаданные о вашей музыке с помощью <a href=\"%{ url }\" target=\"_blank\">MusicBrainz</a>"
 
 #: front/src/views/content/Home.vue:12 src/views/content/Home.vue:19
-#, fuzzy
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Get started"
 msgstr "Начать"
 
+#: front/src/components/library/ImportStatusModal.vue:45
+#, fuzzy
+msgctxt "Popup/Import/Table.Label/Noun"
+msgid "Getting help"
+msgstr "Настройки"
+
 #: front/src/components/Footer.vue:37
 #, fuzzy
+msgctxt "Footer/*/Link"
 msgid "Getting help"
 msgstr "Настройки"
 
-#: front/src/components/common/ActionTable.vue:34
-#: front/src/components/common/ActionTable.vue:54
+#: front/src/components/common/ActionTable.vue:35
+#: front/src/components/common/ActionTable.vue:56
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Go"
 msgstr ""
 
 #: front/src/components/PageNotFound.vue:14
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Go to home page"
 msgstr "Перейти на домашнюю страницу"
 
+#: front/src/components/auth/Settings.vue:128
+#, fuzzy
+msgctxt "Content/Settings/Title"
+msgid "Hidden artists"
+msgstr "Просмотр исполнителей"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:114
+msgctxt "Content/Moderation/Help text"
 msgid "Hide account or domain content, except from followers."
 msgstr ""
 
+#: front/src/components/moderation/FilterModal.vue:40
+#, fuzzy
+msgctxt "Popup/*/Button.Label"
+msgid "Hide content"
+msgstr "Добавить содержимое"
+
+#: front/src/components/audio/PlayButton.vue:26
+msgctxt "*/Queue/Dropdown/Button/Label/Short"
+msgid "Hide content from this artist"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:615
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
+msgid "Hide content from this artist…"
+msgstr ""
+
 #: front/src/components/library/Home.vue:65
+msgctxt "Head/Home/Title"
 msgid "Home"
 msgstr "Домой"
 
 #: front/src/components/instance/Stats.vue:36
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Hours of music"
 msgstr "Часов музыки"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:11
+#: front/src/components/auth/SubsonicTokenForm.vue:10
+msgctxt "Content/Settings/Paragraph"
 msgid "However, accessing Funkwhale from those clients require a separate password you can set below."
 msgstr "Однако, получение доступа к Freewhale из этих клиентов требует отдельного пароля который может быть установлен ниже."
 
 #: front/src/views/auth/PasswordResetConfirm.vue:24
+msgctxt "Content/Signup/Paragraph"
 msgid "If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes."
 msgstr "Если указанный на предыдущем шаге адрес электронной почты правильный и привязан к пользовательскому аккаунту, то вы должны получить письмо с инструкциями по сбросу в течение нескольких минут."
 
-#: front/src/components/manage/library/FilesTable.vue:40
-msgid "Import date"
-msgstr "Дата импорта"
+#: front/src/components/auth/Settings.vue:205
+msgctxt "Content/Applications/Paragraph"
+msgid "If you authorize third-party applications to access your data, those applications will be listed here."
+msgstr ""
 
-#: front/src/components/Home.vue:71
-msgid "Import music from various platforms, such as YouTube or SoundCloud"
-msgstr "Импортируйте музыку из разных платформ, таких как YouTube и SoundCloud"
+#: front/src/components/library/ImportStatusModal.vue:3
+#, fuzzy
+msgctxt "Popup/Import/Title"
+msgid "Import detail"
+msgstr "Статус импорта"
 
-#: front/src/components/library/FileUpload.vue:51
+#: front/src/components/library/FileUpload.vue:50
+msgctxt "Content/Library/Input.Label/Noun"
 msgid "Import reference"
 msgstr ""
 
-#: front/src/views/content/libraries/FilesTable.vue:11
-#: front/src/views/content/libraries/FilesTable.vue:58
+#: front/src/components/manage/library/UploadsTable.vue:64
+#: front/src/views/admin/library/UploadDetail.vue:131
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Import status"
 msgstr "Статус импорта"
 
-#: front/src/views/content/libraries/FilesTable.vue:217
+#: front/src/components/manage/library/UploadsTable.vue:20
+#: front/src/views/content/libraries/FilesTable.vue:11
+#: front/src/views/content/libraries/FilesTable.vue:59
 #, fuzzy
+msgctxt "Content/Library/*/Noun"
+msgid "Import status"
+msgstr "Статус импорта"
+
+#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:38
+msgctxt "Content/Library/Help text"
 msgid "Imported"
 msgstr "Дата импорта"
 
-#: front/src/components/mixins/Translations.vue:21
-#: front/src/components/mixins/Translations.vue:22
-msgid "Imported date"
-msgstr "Дата импорта"
+#: front/src/components/federation/FetchButton.vue:47
+msgctxt "*/*/Error"
+msgid "Impossible to connect to the remote server"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:26
+#, fuzzy
+msgctxt "Popup/Moderation/List item"
+msgid "In \"Recently added\" widget"
+msgstr "Недавно добавленные"
+
+#: front/src/components/moderation/FilterModal.vue:27
+msgctxt "Popup/Moderation/List item"
+msgid "In artists and album listings"
+msgstr ""
 
 #: front/src/components/favorites/TrackFavoriteIcon.vue:3
+msgctxt "Content/Track/Button.Message"
 msgid "In favorites"
 msgstr "В избранном"
 
+#: front/src/components/moderation/FilterModal.vue:25
+msgctxt "Popup/Moderation/List item"
+msgid "In other users favorites and listening history"
+msgstr ""
+
+#: front/src/components/moderation/FilterModal.vue:28
+msgctxt "Popup/Moderation/List item"
+msgid "In radio suggestions"
+msgstr ""
+
 #: front/src/components/manage/users/UsersTable.vue:54
-#, fuzzy
+msgctxt "Content/Admin/Table"
 msgid "Inactive"
 msgstr "Неактивен(на)"
 
 #: front/src/components/ShortcutsModal.vue:71
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Increase volume"
 msgstr ""
 
-#: front/src/views/auth/PasswordReset.vue:53
-msgid "Input the email address binded to your account"
-msgstr ""
-
-#: front/src/components/playlists/Editor.vue:31
+#: front/src/components/playlists/Editor.vue:41
+#, fuzzy
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Insert from queue (%{ count } track)"
 msgid_plural "Insert from queue (%{ count } tracks)"
 msgstr[0] "Вставить из очереди (%{ count } трек)"
 msgstr[1] "Вставить из очереди (%{ count } трека)"
 msgstr[2] "Вставить из очереди (%{ count } треков)"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:71
+#: front/src/components/mixins/Translations.vue:16
+#: front/src/components/mixins/Translations.vue:17
 #, fuzzy
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Instance"
+msgstr "Радио узла"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:71
+msgctxt "Content/Moderation/Title"
 msgid "Instance data"
 msgstr "Радио узла"
 
 #: front/src/views/admin/Settings.vue:80
+msgctxt "Content/Admin/Menu"
 msgid "Instance information"
 msgstr "Информация об узле"
 
 #: front/src/components/library/Radios.vue:9
+msgctxt "Content/Radio/Title"
 msgid "Instance radios"
 msgstr "Радио узла"
 
 #: front/src/views/admin/Settings.vue:75
+msgctxt "Head/Admin/Title"
 msgid "Instance settings"
 msgstr "Настройки узла"
 
-#: front/src/components/library/FileUpload.vue:229
-#: front/src/components/library/FileUpload.vue:230
+#: front/src/components/SetInstanceModal.vue:19
+#, fuzzy
+msgctxt "Popup/Instance/Input.Label/Noun"
+msgid "Instance URL"
+msgstr "Радио узла"
+
+#: front/src/components/library/FileUpload.vue:268
+msgctxt "Content/Library/Help text"
 msgid "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
 msgstr ""
 
-#: front/src/components/auth/Signup.vue:42
+#: front/src/components/library/ImportStatusModal.vue:139
+msgctxt "Popup/Import/Error.Label"
+msgid "Invalid metadata"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:44
 #: front/src/components/manage/users/InvitationForm.vue:11
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Invitation code"
 msgstr "Код приглашения"
 
-#: front/src/components/auth/Signup.vue:43
-msgid "Invitation code (optional)"
-msgstr "Код приглашения (не обязательно)"
-
 #: front/src/views/admin/users/Base.vue:8
-#: src/views/admin/users/InvitationsList.vue:3
 #: front/src/views/admin/users/InvitationsList.vue:24
+#, fuzzy
+msgctxt "*/Admin/*/Noun"
 msgid "Invitations"
 msgstr "Приглашения"
 
 #: front/src/components/Footer.vue:41
-#, fuzzy
+msgctxt "Footer/*/List item.Link"
 msgid "Issue tracker"
 msgstr "Багтрекер"
 
+#: front/src/components/SetInstanceModal.vue:5
+msgctxt "Popup/Instance/Error message.Title"
+msgid "It is not possible to connect to the given URL"
+msgstr ""
+
 #: front/src/components/Home.vue:50
+msgctxt "Content/Home/List item/Verb"
 msgid "Keep a track of your favorite songs"
 msgstr ""
 
 #: front/src/components/Footer.vue:33 src/components/ShortcutsModal.vue:3
+msgctxt "*/*/*/Noun"
 msgid "Keyboard shortcuts"
 msgstr ""
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:161
-#, fuzzy
+msgctxt "Content/Moderation/Table.Label.Link"
 msgid "Known accounts"
 msgstr "Мой аккаунт"
 
 #: front/src/views/content/remote/Home.vue:14
-#, fuzzy
+msgctxt "Content/Library/Title"
 msgid "Known libraries"
 msgstr "Известные библиотеки"
 
 #: front/src/components/manage/users/UsersTable.vue:41
-#: front/src/components/mixins/Translations.vue:32
-#: front/src/views/admin/moderation/AccountsDetail.vue:184
-#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:58
+#: front/src/views/admin/moderation/AccountsDetail.vue:205
+#: front/src/components/mixins/Translations.vue:59
+#, fuzzy
+msgctxt "Content/Profile/Table.Label/Short, Noun (Value is a date)"
 msgid "Last activity"
 msgstr "Последняя активность"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:167
-#: front/src/views/admin/moderation/DomainsDetail.vue:86
+#: front/src/views/admin/moderation/AccountsDetail.vue:188
+#: front/src/views/admin/moderation/DomainsDetail.vue:78
+#, fuzzy
+msgctxt "Content/*/Table.Label"
 msgid "Last checked"
-msgstr ""
+msgstr "Последнее обновление:"
 
-#: front/src/components/playlists/PlaylistModal.vue:32
+#: front/src/components/playlists/PlaylistModal.vue:46
+msgctxt "Popup/Playlist/Table.Label/Short"
 msgid "Last modification"
 msgstr "Последнее изменение"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:43
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Last seen"
-msgstr ""
+msgstr "Последнее обновление:"
 
-#: front/src/components/mixins/Translations.vue:18
-#: front/src/components/mixins/Translations.vue:19
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:47
+#: front/src/components/mixins/Translations.vue:48
+msgctxt "Content/Moderation/Dropdown/Noun"
 msgid "Last seen date"
 msgstr "Последнее обновление:"
 
-#: front/src/views/content/remote/Card.vue:56
+#: front/src/views/content/remote/Card.vue:60
+msgctxt "Content/Library/Card.List item/Noun"
 msgid "Last update:"
 msgstr "Последнее обновление:"
 
-#: front/src/components/common/ActionTable.vue:47
+#: front/src/components/common/ActionTable.vue:49
+msgctxt "Modal/*/Button.Label/Short, Verb"
 msgid "Launch"
 msgstr "Запустить"
 
 #: front/src/components/Home.vue:10
+msgctxt "Content/Home/Button.Label/Verb"
 msgid "Learn more about this instance"
 msgstr "Узнать больше об этом узле"
 
 #: front/src/components/manage/users/InvitationForm.vue:58
+msgctxt "Content/Admin/Input.Placeholder"
 msgid "Leave empty for a random code"
 msgstr "Оставьте пустым для случайного кода"
 
 #: front/src/components/audio/EmbedWizard.vue:7
-#, fuzzy
+msgctxt "Popup/Embed/Paragraph"
 msgid "Leave empty for a responsive widget"
 msgstr "Оставьте пустым для случайного кода"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:297
-#: front/src/views/admin/moderation/DomainsDetail.vue:233
+#: front/src/views/admin/library/AlbumDetail.vue:232
+#: front/src/views/admin/library/ArtistDetail.vue:221
+#: front/src/views/admin/library/TrackDetail.vue:284
+#: front/src/views/admin/moderation/AccountsDetail.vue:327
+#: front/src/views/admin/moderation/DomainsDetail.vue:234
 #: front/src/views/content/Base.vue:5
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Libraries"
 msgstr "Библиотеки"
 
-#: front/src/views/content/libraries/Form.vue:2
-msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
-msgstr "Библиотеки помогают организовывать ваши музыкальные коллекции и делиться ими. Вы можете загружать вашу музыку на Funkwhale и делиться ею с вашими друзьями и семьёй."
-
-#: front/src/components/instance/Stats.vue:30
+#: front/src/views/admin/library/Base.vue:17
+#: front/src/views/admin/library/LibrariesList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Libraries"
+msgstr "Библиотеки"
+
+#: front/src/components/mixins/Translations.vue:72
+#: front/src/components/mixins/Translations.vue:73
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Libraries and uploads"
+msgstr "Библиотека обновлена"
+
+#: front/src/views/content/libraries/Form.vue:2
+msgctxt "Content/Library/Paragraph"
+msgid "Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family."
+msgstr "Библиотеки помогают организовывать ваши музыкальные коллекции и делиться ими. Вы можете загружать вашу музыку на Funkwhale и делиться ею с вашими друзьями и семьёй."
+
+#: front/src/components/Sidebar.vue:85 src/components/instance/Stats.vue:30
+#: front/src/components/manage/library/UploadsTable.vue:60
 #: front/src/components/manage/users/UsersTable.vue:173
-#: front/src/views/admin/moderation/AccountsDetail.vue:464
+#: front/src/views/admin/library/UploadDetail.vue:144
+#: front/src/views/admin/moderation/AccountsDetail.vue:498
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Library"
 msgstr "Библиотека"
 
-#: front/src/views/content/libraries/Form.vue:109
+#: front/src/views/content/libraries/Form.vue:103
+msgctxt "Content/Library/Message"
 msgid "Library created"
 msgstr "Библиотека создана"
 
-#: front/src/views/content/libraries/Form.vue:129
+#: front/src/views/admin/library/LibraryDetail.vue:78
 #, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Library data"
+msgstr "Библиотека обновлена"
+
+#: front/src/views/content/libraries/Form.vue:123
+msgctxt "Content/Library/Message"
 msgid "Library deleted"
 msgstr "Библиотека обновлена"
 
-#: front/src/views/admin/library/FilesList.vue:3
-msgid "Library files"
+#: front/src/views/admin/library/EditsList.vue:4
+#, fuzzy
+msgctxt "Content/Admin/Title/Noun"
+msgid "Library edits"
 msgstr "Файлы библиотеки"
 
-#: front/src/views/content/libraries/Form.vue:106
+#: front/src/views/content/libraries/Form.vue:100
+msgctxt "Content/Library/Message"
 msgid "Library updated"
 msgstr "Библиотека обновлена"
 
-#: front/src/components/library/Track.vue:100
+#: front/src/components/library/TrackDetail.vue:19
+#: front/src/components/manage/library/TracksTable.vue:43
+#: front/src/views/admin/library/TrackDetail.vue:159 src/edits.js:61
+msgctxt "Content/*/*/Noun"
 msgid "License"
 msgstr ""
 
-#: front/src/views/content/libraries/Detail.vue:21
+#: front/src/components/mixins/Translations.vue:80
+#: front/src/components/mixins/Translations.vue:81
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:157
+#: front/src/views/admin/library/ArtistDetail.vue:146
+#: front/src/views/admin/library/TrackDetail.vue:209
+msgctxt "*/*/*/Noun"
+msgid "Listenings"
+msgstr ""
+
+#: front/src/components/audio/track/Table.vue:25
+#: front/src/components/library/ArtistDetail.vue:28
 #, fuzzy
+msgctxt "Content/*/Button.Label"
+msgid "Load more…"
+msgstr "Загружаем подписчиков..."
+
+#: front/src/views/content/libraries/Detail.vue:21
+msgctxt "Content/Library/Paragraph"
 msgid "Loading followers…"
 msgstr "Загружаем подписчиков..."
 
 #: front/src/views/content/libraries/Home.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading Libraries…"
 msgstr "Загружаем Библиотеки..."
 
 #: front/src/views/content/libraries/Detail.vue:3
 #: front/src/views/content/libraries/Upload.vue:3
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading library data…"
 msgstr "Загружаем данные библиотеки..."
 
-#: front/src/views/Notifications.vue:4
-#, fuzzy
+#: front/src/views/Notifications.vue:19
+msgctxt "Content/Notifications/Paragraph"
 msgid "Loading notifications…"
 msgstr "Загружаем уведомления..."
 
 #: front/src/views/content/remote/Home.vue:3
-msgid "Loading remote libraries..."
+msgctxt "Content/Library/Paragraph"
+msgid "Loading remote libraries…"
 msgstr "Загружаем удалённые библиотеки..."
 
 #: front/src/views/content/libraries/Quota.vue:4
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Loading usage data…"
 msgstr "Загружаем данные об использовании..."
 
 #: front/src/components/favorites/List.vue:5
-#, fuzzy
+msgctxt "Content/Favorites/Message"
 msgid "Loading your favorites…"
 msgstr "Загружаем ваше избранное..."
 
+#: front/src/components/manage/library/AlbumsTable.vue:65
+#: front/src/components/manage/library/ArtistsTable.vue:58
+#: front/src/components/manage/library/LibrariesTable.vue:75
+#: front/src/components/manage/library/TracksTable.vue:71
+#: front/src/components/manage/library/UploadsTable.vue:99
+#: front/src/views/admin/library/AlbumDetail.vue:19
+#: front/src/views/admin/library/ArtistDetail.vue:18
+#: front/src/views/admin/library/LibraryDetail.vue:18
+#: front/src/views/admin/library/TrackDetail.vue:18
+#: front/src/views/admin/library/UploadDetail.vue:19
+msgctxt "Content/Moderation/*/Short, Noun"
+msgid "Local"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:59
 #: front/src/views/admin/moderation/AccountsDetail.vue:18
 #, fuzzy
+msgctxt "Content/Moderation/*/Short, Noun"
 msgid "Local account"
 msgstr "Мой аккаунт"
 
-#: front/src/components/auth/Login.vue:78
+#: front/src/components/auth/Login.vue:84
+msgctxt "Head/Login/Title"
 msgid "Log In"
 msgstr "Вход"
 
 #: front/src/components/auth/Login.vue:4
+msgctxt "Content/Login/Title/Verb"
 msgid "Log in to your Funkwhale account"
 msgstr "Войти в ваш аккаунт Funkwhale"
 
 #: front/src/components/auth/Logout.vue:20
+msgctxt "Head/Login/Title"
 msgid "Log Out"
 msgstr "Выход"
 
 #: front/src/components/Sidebar.vue:38
+msgctxt "Sidebar/Profile/List item.Link"
 msgid "Logged in as %{ username }"
 msgstr "Вошли как %{ username }"
 
-#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:41
+#: front/src/components/Sidebar.vue:54 src/components/auth/Login.vue:42
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Login"
 msgstr "Войти"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:119
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:148
+msgctxt "Content/*/*/Noun"
 msgid "Login status"
 msgstr "Статус аккаунта"
 
 #: front/src/components/Sidebar.vue:52
+msgctxt "Sidebar/Login/List item.Link/Verb"
 msgid "Logout"
 msgstr "Выйти"
 
 #: front/src/views/content/libraries/Home.vue:9
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Looks like you don't have a library, it's time to create one."
 msgstr "Похоже у вас ещё нет ни одной библиотеки, самое время создать её!"
 
-#: front/src/components/audio/Player.vue:353
-#: src/components/audio/Player.vue:354
+#: front/src/components/audio/Player.vue:604
+#: src/components/audio/Player.vue:605
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping disabled. Click to switch to single-track looping."
 msgstr "Зацикливание отключено. Нажмите чтобы включить цикличное проигрывание трека."
 
-#: front/src/components/audio/Player.vue:356
-#: src/components/audio/Player.vue:357
+#: front/src/components/audio/Player.vue:607
+#: src/components/audio/Player.vue:608
+#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on a single track. Click to switch to whole queue looping."
-msgstr ""
+msgstr "Зацикливание отключено. Нажмите чтобы включить цикличное проигрывание трека."
 
-#: front/src/components/audio/Player.vue:359
-#: src/components/audio/Player.vue:360
+#: front/src/components/audio/Player.vue:610
+#: src/components/audio/Player.vue:611
+#, fuzzy
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Looping on whole queue. Click to disable looping."
-msgstr ""
-
-#: front/src/components/library/Track.vue:150
-msgid "Lyrics"
-msgstr "Тексты"
+msgstr "Зацикливание отключено. Нажмите чтобы включить цикличное проигрывание трека."
 
-#: front/src/components/Sidebar.vue:210
+#: front/src/components/Sidebar.vue:223
+msgctxt "Sidebar/*/Hidden text"
 msgid "Main menu"
 msgstr ""
 
-#: front/src/views/admin/library/Base.vue:16
-#, fuzzy
+#: front/src/views/admin/library/Base.vue:31
+msgctxt "Head/Admin/Title"
 msgid "Manage library"
 msgstr "Управление библиотекой"
 
 #: front/src/components/playlists/PlaylistModal.vue:3
+msgctxt "Popup/Playlist/Title/Verb"
 msgid "Manage playlists"
 msgstr "Управлять списками воспроизведения"
 
 #: front/src/views/admin/users/Base.vue:20
+msgctxt "Head/Admin/Title"
 msgid "Manage users"
 msgstr "Управлять пользователями"
 
 #: front/src/views/playlists/List.vue:8
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Manage your playlists"
 msgstr "Управлять вашими списками воспроизведения"
 
-#: front/src/views/Notifications.vue:17
+#: front/src/views/Notifications.vue:14
+msgctxt "Content/Notifications/Button.Label/Verb"
 msgid "Mark all as read"
 msgstr "Отметить все как прочитанные"
 
-#: front/src/components/notifications/NotificationRow.vue:44
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:46
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as read"
 msgstr "Отметить все как прочитанные"
 
-#: front/src/components/notifications/NotificationRow.vue:45
-#, fuzzy
+#: front/src/components/notifications/NotificationRow.vue:47
+msgctxt "Content/Notifications/Button.Tooltip/Verb"
 msgid "Mark as unread"
 msgstr "Отметить все как прочитанные"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:281
+#: front/src/views/admin/moderation/AccountsDetail.vue:310
+msgctxt "Content/*/*/Unit"
 msgid "MB"
 msgstr "МБ"
 
-#: front/src/components/audio/Player.vue:346
+#: front/src/components/audio/Player.vue:597
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Media player"
 msgstr ""
 
+#: front/src/components/auth/Profile.vue:12
+#, fuzzy
+msgctxt "Content/Profile/Paragraph"
+msgid "Member since %{ date }"
+msgstr "Зарегистрировано с %{ date }"
+
 #: front/src/components/Footer.vue:32
+msgctxt "Footer/*/List item.Link"
 msgid "Mobile and desktop apps"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:97
+#: front/src/components/Sidebar.vue:96
 #: src/components/manage/users/UsersTable.vue:177
-#: front/src/views/admin/moderation/AccountsDetail.vue:468
+#: front/src/views/admin/moderation/AccountsDetail.vue:502
 #: front/src/views/admin/moderation/Base.vue:21
 #, fuzzy
+msgctxt "*/Moderation/*"
 msgid "Moderation"
 msgstr "Федерация"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:49
+#: front/src/views/admin/moderation/AccountsDetail.vue:78
 #: front/src/views/admin/moderation/DomainsDetail.vue:42
+msgctxt "Content/Moderation/Card.Paragraph"
 msgid "Moderation policies help you control how your instance interact with a given domain or account."
 msgstr ""
 
-#: front/src/components/mixins/Translations.vue:20
-#: front/src/components/mixins/Translations.vue:21
+#: front/src/components/library/EditCard.vue:5
+#, fuzzy
+msgctxt "Content/Library/Card/Short"
+msgid "Modification %{ id }"
+msgstr "Дата последнего изменения"
+
+#: front/src/components/mixins/Translations.vue:48
+#: front/src/components/mixins/Translations.vue:49
+msgctxt "Content/Playlist/Dropdown/Noun"
 msgid "Modification date"
 msgstr "Дата последнего изменения"
 
+#: front/src/components/library/AlbumBase.vue:42
+#: front/src/components/library/ArtistBase.vue:53
+#: front/src/components/library/TrackBase.vue:61
+msgctxt "*/*/Button.Label/Noun"
+msgid "More…"
+msgstr ""
+
 #: front/src/components/Sidebar.vue:63 src/views/admin/Settings.vue:82
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Music"
 msgstr "Музыка"
 
-#: front/src/components/audio/Player.vue:352
+#: front/src/components/audio/Player.vue:603
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Mute"
 msgstr "Приглушить"
 
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute activity"
+msgstr "Последняя активность"
+
+#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
+#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#, fuzzy
+msgctxt "Content/Moderation/*/Verb"
+msgid "Mute notifications"
+msgstr "Ваши уведомления"
+
 #: front/src/components/Sidebar.vue:34
+msgctxt "Sidebar/Profile/Title"
 msgid "My account"
 msgstr "Мой аккаунт"
 
-#: front/src/components/library/radios/Builder.vue:236
+#: front/src/components/library/radios/Builder.vue:238
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome description"
 msgstr "Моё замечательное описание"
 
-#: front/src/views/content/libraries/Form.vue:70
+#: front/src/views/content/libraries/Form.vue:72
+msgctxt "Content/Library/Input.Placeholder"
 msgid "My awesome library"
 msgstr "Моя замечательная библиотека"
 
-#: front/src/components/playlists/Form.vue:74
+#: front/src/components/playlists/Form.vue:76
+msgctxt "Content/Playlist/Input.Placeholder"
 msgid "My awesome playlist"
 msgstr "Мой замечательный список воспроизведения"
 
-#: front/src/components/library/radios/Builder.vue:235
+#: front/src/components/library/radios/Builder.vue:237
+msgctxt "Content/Radio/Input.Placeholder"
 msgid "My awesome radio"
 msgstr "Моё замечательное радио"
 
 #: front/src/views/content/libraries/Home.vue:6
+msgctxt "Content/Library/Title"
 msgid "My libraries"
 msgstr "Мои библиотеки"
 
 #: front/src/components/audio/track/Row.vue:40
-#: src/components/library/Track.vue:115
-#: front/src/components/library/Track.vue:124
-#: src/components/library/Track.vue:133
-#: front/src/components/library/Track.vue:142
-#: front/src/components/manage/library/FilesTable.vue:63
-#: front/src/components/manage/library/FilesTable.vue:69
-#: front/src/components/manage/library/FilesTable.vue:75
-#: front/src/components/manage/library/FilesTable.vue:81
+#: src/components/library/EditCard.vue:60
+#: front/src/components/library/EditForm.vue:70
+#: front/src/components/library/TrackDetail.vue:34
+#: front/src/components/library/TrackDetail.vue:43
+#: front/src/components/library/TrackDetail.vue:52
+#: front/src/components/library/TrackDetail.vue:61
+#: front/src/components/manage/library/AlbumsTable.vue:73
+#: front/src/components/manage/library/TracksTable.vue:76
+#: front/src/components/manage/library/UploadsTable.vue:121
+#: front/src/components/manage/library/UploadsTable.vue:128
 #: front/src/components/manage/users/UsersTable.vue:61
-#: front/src/views/admin/moderation/AccountsDetail.vue:171
-#: front/src/views/admin/moderation/DomainsDetail.vue:90
-#: front/src/views/content/libraries/FilesTable.vue:92
-#: front/src/views/content/libraries/FilesTable.vue:98
-#: front/src/views/admin/moderation/DomainsDetail.vue:109
-#: front/src/views/admin/moderation/DomainsDetail.vue:117
+#: front/src/views/admin/library/UploadDetail.vue:179
+#: front/src/views/admin/library/UploadDetail.vue:214
+#: front/src/views/admin/library/UploadDetail.vue:233
+#: front/src/views/admin/library/UploadDetail.vue:244
+#: front/src/views/admin/library/UploadDetail.vue:257
+#: front/src/views/admin/moderation/AccountsDetail.vue:192
+#: front/src/views/admin/moderation/DomainsDetail.vue:82
+#: front/src/views/content/libraries/FilesTable.vue:95
+#: front/src/views/content/libraries/FilesTable.vue:101
+msgctxt "*/*/*"
 msgid "N/A"
 msgstr "Н/Д"
 
+#: front/src/components/manage/library/LibrariesTable.vue:48
+#: front/src/components/manage/library/UploadsTable.vue:59
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Name"
+msgstr "Имя"
+
+#: front/src/components/auth/Settings.vue:133
+#: front/src/components/manage/library/ArtistsTable.vue:39
 #: front/src/components/manage/moderation/AccountsTable.vue:39
 #: front/src/components/manage/moderation/DomainsTable.vue:38
-#: front/src/components/mixins/Translations.vue:26
-#: front/src/components/playlists/PlaylistModal.vue:31
-#: front/src/views/admin/moderation/DomainsDetail.vue:105
-#: front/src/views/content/libraries/Form.vue:10
-#: front/src/components/mixins/Translations.vue:27
+#: front/src/components/mixins/Translations.vue:53
+#: front/src/components/playlists/PlaylistModal.vue:45
+#: front/src/views/admin/library/ArtistDetail.vue:98
+#: front/src/views/admin/library/LibraryDetail.vue:85
+#: front/src/views/admin/library/UploadDetail.vue:92
+#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/content/libraries/Form.vue:10 src/edits.js:10
+#: front/src/components/mixins/Translations.vue:54
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Name"
+msgstr "Имя"
+
+#: front/src/components/auth/ApplicationForm.vue:9
+#, fuzzy
+msgctxt "Content/Applications/Input.Label/Noun"
 msgid "Name"
 msgstr "Имя"
 
 #: front/src/components/auth/Settings.vue:88
 #: front/src/views/auth/PasswordResetConfirm.vue:14
+msgctxt "Content/Settings/Input.Label"
 msgid "New password"
 msgstr "Новый пароль"
 
-#: front/src/components/Sidebar.vue:160
+#: front/src/components/Sidebar.vue:173
+msgctxt "Sidebar/Player/Paragraph"
 msgid "New tracks will be appended here automatically."
 msgstr "Новые треки будут добавлены сюда автоматически."
 
-#: front/src/components/audio/Player.vue:350
+#: front/src/components/library/EditCard.vue:47
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "New value"
+msgstr ""
+
+#: front/src/components/audio/Player.vue:601
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Next track"
 msgstr "Следующий трек"
 
-#: front/src/components/Sidebar.vue:119
+#: front/src/components/Sidebar.vue:130
+msgctxt "*/*/*"
 msgid "No"
 msgstr "Нет"
 
-#: front/src/components/Home.vue:100
+#: front/src/components/Home.vue:95
+msgctxt "Content/Home/List item"
 msgid "No add-ons, no plugins : you only need a web library"
 msgstr ""
 
 #: front/src/components/audio/Search.vue:25
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No album matched your query"
 msgstr "Извините, мы не нашли никакого альбома подходящего под ваш запрос"
 
 #: front/src/components/audio/Search.vue:16
-#, fuzzy
+msgctxt "Content/Search/Paragraph"
 msgid "No artist matched your query"
 msgstr "Извините, мы не нашли ни одного исполнителя подходящего под ваш запрос"
 
-#: front/src/components/library/Track.vue:158
-msgid "No lyrics available for this track."
+#: front/src/components/library/TrackDetail.vue:14
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No copyright information available for this track"
 msgstr "Текст недоступен для этого трека."
 
+#: front/src/components/library/TrackDetail.vue:25
+#, fuzzy
+msgctxt "Content/Track/Table.Paragraph"
+msgid "No licensing information for this track"
+msgstr "У нас нет уведомлений для показа!"
+
 #: front/src/components/federation/LibraryWidget.vue:6
+msgctxt "Content/Federation/Paragraph"
 msgid "No matching library."
 msgstr "Нет подходящей библиотеки."
 
-#: front/src/views/Notifications.vue:26
-#, fuzzy
-msgid "No notifications yet."
+#: front/src/views/Notifications.vue:28
+msgctxt "Content/Notifications/Paragraph"
+msgid "No notification to show."
 msgstr "Ваши уведомления"
 
+#: front/src/components/common/EmptyState.vue:7
+msgctxt "Content/*/Paragraph"
+msgid "No results were found."
+msgstr ""
+
 #: front/src/components/mixins/Translations.vue:10
-#: front/src/components/playlists/Form.vue:81
-#: src/views/content/libraries/Form.vue:72
 #: front/src/components/mixins/Translations.vue:11
+msgctxt "Content/Settings/Dropdown"
 msgid "Nobody except me"
 msgstr "Никто кроме меня"
 
 #: front/src/views/content/libraries/Detail.vue:57
+msgctxt "Content/Library/Paragraph"
 msgid "Nobody is following this library"
 msgstr "Никто не подписан на эту библиотеку"
 
 #: front/src/components/manage/users/InvitationsTable.vue:51
+msgctxt "Content/Admin/Table"
 msgid "Not used"
 msgstr "Не используется"
 
-#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:74
+#: front/src/components/Sidebar.vue:46 src/views/Notifications.vue:76
+#, fuzzy
+msgctxt "*/Notifications/*"
+msgid "Notifications"
+msgstr "Уведомления"
+
+#: front/src/components/mixins/Translations.vue:100
+#: front/src/components/mixins/Translations.vue:101
+#, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Notifications"
 msgstr "Уведомления"
 
 #: front/src/components/Footer.vue:47
+msgctxt "Footer/*/List item.Link"
 msgid "Official website"
 msgstr "Официальный веб-сайт"
 
 #: front/src/components/auth/Settings.vue:83
+msgctxt "Content/Settings/Input.Label"
 msgid "Old password"
 msgstr "Старый пароль"
 
+#: front/src/components/library/EditCard.vue:46
+msgctxt "Content/Library/Card.Table.Header/Short"
+msgid "Old value"
+msgstr ""
+
 #: front/src/components/manage/users/InvitationsTable.vue:20
+msgctxt "Content/Admin/Dropdown/Adjective"
 msgid "Open"
 msgstr "Открыть"
 
+#: front/src/components/library/ImportStatusModal.vue:56
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Open a support thread (include the debug information below in your message)"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:73
+#: front/src/components/library/ArtistBase.vue:84
+#: front/src/components/library/TrackBase.vue:92
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Open in moderation interface"
+msgstr "Удалить радио"
+
+#: front/src/views/admin/library/AlbumDetail.vue:31
+#: front/src/views/admin/library/ArtistDetail.vue:30
+#: front/src/views/admin/library/TrackDetail.vue:30
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open local profile"
+msgstr ""
+
+#: front/src/views/admin/library/AlbumDetail.vue:46
+#: front/src/views/admin/library/ArtistDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:45
+#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open on MusicBrainz"
+msgstr "Смотреть на MusicBrainz"
+
 #: front/src/views/admin/moderation/AccountsDetail.vue:23
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open profile"
 msgstr ""
 
+#: front/src/views/admin/library/AlbumDetail.vue:54
+#: front/src/views/admin/library/ArtistDetail.vue:53
+#: front/src/views/admin/library/LibraryDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:53
+#: front/src/views/admin/library/UploadDetail.vue:50
+#: front/src/views/admin/moderation/AccountsDetail.vue:52
+msgctxt "Content/Moderation/Link/Verb"
+msgid "Open remote profile"
+msgstr ""
+
 #: front/src/views/admin/moderation/DomainsDetail.vue:16
-#, fuzzy
+msgctxt "Content/Moderation/Link/Verb"
 msgid "Open website"
 msgstr "Официальный веб-сайт"
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:40
-#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "Or customize your rule"
 msgstr "Добавить фильтры чтобы кастомизировать своё радио"
 
-#: front/src/components/favorites/List.vue:31
+#: front/src/components/favorites/List.vue:32
 #: src/components/library/Radios.vue:41
-#: front/src/components/manage/library/FilesTable.vue:17
+#: front/src/components/manage/library/EditsCardList.vue:37
 #: front/src/components/manage/users/UsersTable.vue:17
 #: front/src/views/playlists/List.vue:25
-#, fuzzy
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Order"
 msgstr "Порядок"
 
-#: front/src/components/favorites/List.vue:23
-#: src/components/library/Artists.vue:15
-#: front/src/components/library/Radios.vue:33
-#: front/src/components/manage/library/FilesTable.vue:9
+#: front/src/components/favorites/List.vue:24
+#: src/components/library/Albums.vue:15
+#: front/src/components/library/Artists.vue:15
+#: src/components/library/Radios.vue:33
+#: front/src/components/manage/library/AlbumsTable.vue:11
+#: front/src/components/manage/library/ArtistsTable.vue:11
+#: front/src/components/manage/library/EditsCardList.vue:29
+#: front/src/components/manage/library/LibrariesTable.vue:20
+#: front/src/components/manage/library/TracksTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:30
 #: front/src/components/manage/moderation/AccountsTable.vue:11
 #: front/src/components/manage/moderation/DomainsTable.vue:9
 #: front/src/components/manage/users/InvitationsTable.vue:9
 #: front/src/components/manage/users/UsersTable.vue:9
 #: front/src/views/content/libraries/FilesTable.vue:21
 #: front/src/views/playlists/List.vue:17
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering"
 msgstr "Порядок"
 
-#: front/src/components/library/Artists.vue:23
+#: front/src/components/library/Albums.vue:23
+#: src/components/library/Artists.vue:23
+#: front/src/components/manage/library/AlbumsTable.vue:19
+#: front/src/components/manage/library/ArtistsTable.vue:19
+#: front/src/components/manage/library/LibrariesTable.vue:28
+#: front/src/components/manage/library/TracksTable.vue:19
+#: front/src/components/manage/library/UploadsTable.vue:38
 #: front/src/components/manage/moderation/AccountsTable.vue:19
 #: front/src/components/manage/moderation/DomainsTable.vue:17
 #: front/src/views/content/libraries/FilesTable.vue:29
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Ordering direction"
 msgstr "Порядок"
 
 #: front/src/components/manage/users/InvitationsTable.vue:38
+msgctxt "Content/Admin/Table.Label"
 msgid "Owner"
 msgstr "Владелец"
 
 #: front/src/components/PageNotFound.vue:33
-#, fuzzy
+msgctxt "Head/*/Title"
 msgid "Page Not Found"
 msgstr "Страница не найдена!"
 
 #: front/src/components/PageNotFound.vue:7
+msgctxt "Content/*/Title"
 msgid "Page not found!"
 msgstr "Страница не найдена!"
 
 #: front/src/components/Pagination.vue:39
+msgctxt "Content/*/Hidden text/Noun"
 msgid "Pagination"
 msgstr ""
 
-#: front/src/components/auth/Login.vue:32 src/components/auth/Signup.vue:38
+#: front/src/components/auth/Login.vue:33 src/components/auth/Signup.vue:40
+#, fuzzy
+msgctxt "Content/*/Input.Label"
 msgid "Password"
 msgstr "Пароль"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:95
+#: front/src/components/auth/SubsonicTokenForm.vue:94
+msgctxt "Content/Settings/Message"
 msgid "Password updated"
 msgstr "Пароль обновлён"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:28
+msgctxt "Content/Signup/Card.Title"
 msgid "Password updated successfully"
 msgstr "Пароль успешно обновлён"
 
-#: front/src/components/audio/Player.vue:349
+#: front/src/components/audio/Player.vue:600
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Pause track"
 msgstr "Приостановить трек"
 
 #: front/src/components/ShortcutsModal.vue:59
+#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Pause/play the current track"
-msgstr ""
+msgstr "Проиграть трек"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:12
+msgctxt "Content/Moderation/Card.List item"
 msgid "Paused"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:106
+#: front/src/components/library/FileUpload.vue:116
+#: front/src/components/manage/library/UploadsTable.vue:23
+#: front/src/components/mixins/Translations.vue:28
 #: front/src/views/content/libraries/FilesTable.vue:14
-#: front/src/views/content/libraries/FilesTable.vue:208
+#: front/src/components/mixins/Translations.vue:29
 #, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Pending"
 msgstr "Ожидает"
 
 #: front/src/views/content/libraries/Detail.vue:37
+msgctxt "Content/Library/Table/Short"
 msgid "Pending approval"
 msgstr "Ожидает подтверждения"
 
 #: front/src/views/content/libraries/Quota.vue:22
+msgctxt "Content/Library/Label"
 msgid "Pending files"
 msgstr "Ожидающие файлы"
 
-#: front/src/components/Sidebar.vue:212
+#: front/src/components/Sidebar.vue:225
+#, fuzzy
+msgctxt "Sidebar/Notifications/Hidden text"
 msgid "Pending follow requests"
-msgstr ""
+msgstr "Ожидающие файлы"
+
+#: front/src/components/library/EditCard.vue:29
+#: front/src/components/manage/library/EditsCardList.vue:18
+#, fuzzy
+msgctxt "Content/Admin/*/Noun"
+msgid "Pending review"
+msgstr "Ожидающие файлы"
+
+#: front/src/components/Sidebar.vue:226
+#, fuzzy
+msgctxt "Sidebar/Moderation/Hidden text"
+msgid "Pending review edits"
+msgstr "Ожидающие файлы"
 
 #: front/src/components/manage/users/UsersTable.vue:42
-#: front/src/views/admin/moderation/AccountsDetail.vue:137
+#: front/src/views/admin/moderation/AccountsDetail.vue:166
+msgctxt "Content/Admin/Table.Label/Noun"
+msgid "Permissions"
+msgstr "Разрешения"
+
+#: front/src/components/auth/Settings.vue:176
+#, fuzzy
+msgctxt "Content/*/*/Noun"
 msgid "Permissions"
 msgstr "Разрешения"
 
 #: front/src/components/audio/PlayButton.vue:9
-#: src/components/library/Track.vue:40
+#: front/src/components/library/TrackBase.vue:26
+#, fuzzy
+msgctxt "*/Queue/Button.Label/Short, Verb"
 msgid "Play"
-msgstr ""
+msgstr "Проиграть всё"
 
-#: front/src/components/audio/album/Card.vue:50
+#: front/src/components/audio/album/Card.vue:48
 #: front/src/components/audio/artist/Card.vue:44
-#: src/components/library/Album.vue:28
-#: front/src/components/library/Album.vue:73 src/views/playlists/Detail.vue:23
+#: front/src/components/library/AlbumBase.vue:20
+#: front/src/components/library/AlbumDetail.vue:11
+#: src/views/playlists/Detail.vue:24
+msgctxt "Content/Queue/Button.Label/Short, Verb"
 msgid "Play all"
 msgstr "Проиграть всё"
 
-#: front/src/components/library/Artist.vue:26
+#: front/src/components/library/ArtistBase.vue:31
+msgctxt "Content/Artist/Button.Label/Verb"
 msgid "Play all albums"
 msgstr "Проиграть все альбомы"
 
-#: front/src/components/audio/PlayButton.vue:15
-#: front/src/components/audio/PlayButton.vue:65
+#: front/src/components/audio/PlayButton.vue:76
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play next"
 msgstr "Проиграть следующий"
 
 #: front/src/components/ShortcutsModal.vue:67
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play next track"
 msgstr "Проиграть трек"
 
-#: front/src/components/audio/PlayButton.vue:16
-#: front/src/components/audio/PlayButton.vue:63
-#: front/src/components/audio/PlayButton.vue:70
+#: front/src/components/audio/PlayButton.vue:74
+msgctxt "*/Queue/Dropdown/Button/Title"
 msgid "Play now"
 msgstr "Сейчас проигрывается"
 
 #: front/src/components/ShortcutsModal.vue:63
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Play previous track"
 msgstr "Предыдущий трек"
 
-#: front/src/components/Sidebar.vue:211
-#, fuzzy
+#: front/src/components/audio/PlayButton.vue:77
+msgctxt "*/Queue/Dropdown/Button/Title"
+msgid "Play similar songs"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:224
+msgctxt "Sidebar/Player/Hidden text"
 msgid "Play this track"
 msgstr "Проиграть трек"
 
-#: front/src/components/audio/Player.vue:348
+#: front/src/components/audio/Player.vue:599
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Play track"
 msgstr "Проиграть трек"
 
-#: front/src/views/playlists/Detail.vue:90
+#: front/src/components/audio/PlayButton.vue:82
+msgctxt "*/Queue/Button/Title"
+msgid "Play..."
+msgstr ""
+
+#: front/src/views/playlists/Detail.vue:91
+#, fuzzy
+msgctxt "Head/Playlist/Title"
 msgid "Playlist"
 msgstr "Список воспроизведения"
 
 #: front/src/views/playlists/Detail.vue:12
+#, fuzzy
+msgctxt "Content/Playlist/Header.Subtitle"
 msgid "Playlist containing %{ count } track, by %{ username }"
 msgid_plural "Playlist containing %{ count } tracks, by %{ username }"
 msgstr[0] "Список воспроизведения содержит %{ count } трек от %{ username }"
@@ -1890,78 +3160,123 @@ msgstr[1] "Список воспроизведения содержит %{ count
 msgstr[2] "Список воспроизведения содержит %{ count } треков от %{ username }"
 
 #: front/src/components/playlists/Form.vue:9
+msgctxt "Content/Playlist/Message"
 msgid "Playlist created"
 msgstr "Список воспроизведения создан"
 
 #: front/src/components/playlists/Editor.vue:4
+msgctxt "Content/Playlist/Title"
 msgid "Playlist editor"
 msgstr "Редактор списков воспроизведения"
 
 #: front/src/components/playlists/Form.vue:21
+msgctxt "Content/Playlist/Input.Label"
 msgid "Playlist name"
 msgstr "Название списка воспроизведения"
 
 #: front/src/components/playlists/Form.vue:6
+msgctxt "Content/Playlist/Message"
 msgid "Playlist updated"
 msgstr "Список воспроизведения обновлён"
 
 #: front/src/components/playlists/Form.vue:25
+msgctxt "Content/Playlist/Dropdown.Label"
 msgid "Playlist visibility"
 msgstr "Видимость списка воспроизведения"
 
 #: front/src/components/Sidebar.vue:71 src/components/library/Home.vue:16
-#: front/src/components/library/Library.vue:13 src/views/admin/Settings.vue:83
-#: front/src/views/playlists/List.vue:106
+#: front/src/components/library/Library.vue:16 src/views/admin/Settings.vue:83
+#: front/src/views/admin/library/AlbumDetail.vue:173
+#: front/src/views/admin/library/ArtistDetail.vue:162
+#: front/src/views/admin/library/TrackDetail.vue:225
+#: src/views/playlists/List.vue:106
+#, fuzzy
+msgctxt "*/*/*"
 msgid "Playlists"
 msgstr "Списки воспроизведения"
 
-#: front/src/components/Home.vue:56
+#: front/src/components/mixins/Translations.vue:88
+#: front/src/components/mixins/Translations.vue:89
 #, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Playlists"
+msgstr "Списки воспроизведения"
+
+#: front/src/components/Home.vue:56
+msgctxt "Content/Home/List item"
 msgid "Playlists? We got them"
 msgstr "Списки воспроизведения? У нас они есть"
 
 #: front/src/components/auth/Settings.vue:79
+msgctxt "Content/Settings/Error message.List item/Call to action"
 msgid "Please double-check your password is correct"
 msgstr "Пожалуйста перепроверьте корректность вашего пароля"
 
 #: front/src/components/auth/Login.vue:9
+msgctxt "Content/Login/Error message.List item/Call to action"
 msgid "Please double-check your username/password couple is correct"
 msgstr "Пожалуйста перепроверьте что ваше имя пользователя и пароль верны"
 
 #: front/src/components/auth/Settings.vue:46
+msgctxt "Content/Settings/Paragraph"
 msgid "PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px."
 msgstr "PNG, GIF или JPG. Не больше 2MB. Будет уменьшено до 400x400px."
 
+#: front/src/views/admin/library/TrackDetail.vue:137
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Position"
+msgstr "Описание"
+
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:118
+msgctxt "Content/Moderation/Help text"
 msgid "Prevent account or domain from triggering notifications, except from followers."
 msgstr ""
 
-#: front/src/components/audio/EmbedWizard.vue:29
+#: front/src/components/audio/EmbedWizard.vue:33
+msgctxt "Popup/Embed/Title/Noun"
 msgid "Preview"
 msgstr ""
 
-#: front/src/components/audio/Player.vue:347
+#: front/src/components/audio/Player.vue:598
+msgctxt "Sidebar/Player/Icon.Tooltip"
 msgid "Previous track"
 msgstr "Предыдущий трек"
 
-#: front/src/views/content/remote/Card.vue:39
-#, fuzzy
+#: front/src/components/mixins/Translations.vue:15
+#: front/src/components/mixins/Translations.vue:16
+msgctxt "Content/Settings/Dropdown/Short"
+msgid "Private"
+msgstr ""
+
+#: front/src/views/content/remote/Card.vue:43
+msgctxt "Content/Library/Card.List item"
 msgid "Problem during scanning"
 msgstr "Ошибка во время сканирования"
 
-#: front/src/components/library/FileUpload.vue:58
+#: front/src/components/library/FileUpload.vue:57
+msgctxt "Content/Library/Button.Label"
 msgid "Proceed"
 msgstr "Продолжить"
 
 #: front/src/views/auth/EmailConfirm.vue:26
 #: front/src/views/auth/PasswordResetConfirm.vue:31
+#, fuzzy
+msgctxt "Content/Signup/Link/Verb"
 msgid "Proceed to login"
-msgstr ""
+msgstr "Назад ко входу"
 
 #: front/src/components/library/FileUpload.vue:17
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Processing"
 msgstr "Обработка"
 
+#: front/src/components/mixins/Translations.vue:68
+#: front/src/components/mixins/Translations.vue:69
+msgctxt "Content/OAuth Scopes/Label"
+msgid "Profile"
+msgstr ""
+
 #: front/src/components/manage/moderation/AccountsTable.vue:188
 #: front/src/components/manage/moderation/DomainsTable.vue:168
 #: front/src/views/content/libraries/Quota.vue:36
@@ -1970,349 +3285,607 @@ msgstr "Обработка"
 #: front/src/views/content/libraries/Quota.vue:65
 #: front/src/views/content/libraries/Quota.vue:88
 #: front/src/views/content/libraries/Quota.vue:91
+#, fuzzy
+msgctxt "*/*/*/Verb"
 msgid "Purge"
 msgstr "Очистить"
 
 #: front/src/views/content/libraries/Quota.vue:89
+msgctxt "Popup/Library/Title"
 msgid "Purge errored files?"
 msgstr "Очистить ошибочные файлы?"
 
 #: front/src/views/content/libraries/Quota.vue:37
+msgctxt "Popup/Library/Title"
 msgid "Purge pending files?"
 msgstr "Очистить ожидающие файлы?"
 
 #: front/src/views/content/libraries/Quota.vue:63
+msgctxt "Popup/Library/Title"
 msgid "Purge skipped files?"
 msgstr "Очистить пропущенные файлы?"
 
 #: front/src/components/Sidebar.vue:20
+msgctxt "Sidebar/Queue/Tab.Title/Noun"
 msgid "Queue"
 msgstr "Очередь"
 
-#: front/src/components/audio/Player.vue:282
+#: front/src/components/audio/Player.vue:310
+msgctxt "Content/Queue/Message"
 msgid "Queue shuffled!"
 msgstr "Очередь перемешана!"
 
 #: front/src/views/radios/Detail.vue:80
+msgctxt "Head/Radio/Title"
 msgid "Radio"
 msgstr "Радио"
 
-#: front/src/components/library/radios/Builder.vue:233
+#: front/src/components/library/radios/Builder.vue:235
+msgctxt "Head/Radio/Title"
 msgid "Radio Builder"
 msgstr "Конструктор радио"
 
 #: front/src/components/library/radios/Builder.vue:15
+msgctxt "Content/Radio/Message"
 msgid "Radio created"
 msgstr "Радио создано"
 
 #: front/src/components/library/radios/Builder.vue:21
+msgctxt "Content/Radio/Input.Label/Noun"
 msgid "Radio name"
 msgstr "Название радио"
 
 #: front/src/components/library/radios/Builder.vue:12
+msgctxt "Content/Radio/Message"
 msgid "Radio updated"
 msgstr "Радио обновлено"
 
-#: front/src/components/library/Library.vue:10
-#: src/components/library/Radios.vue:141
+#: front/src/components/library/Library.vue:13
+#: src/components/library/Radios.vue:142
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Radios"
+msgstr "Радио"
+
+#: front/src/components/mixins/Translations.vue:92
+#: front/src/components/mixins/Translations.vue:93
 #, fuzzy
+msgctxt "Content/OAuth Scopes/Label"
 msgid "Radios"
 msgstr "Радио"
 
+#: front/src/components/auth/ApplicationForm.vue:149
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Read"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:51
+msgctxt "Popup/Import/Table.Label/Value"
+msgid "Read our documentation for this error"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:24
+msgctxt "Content/Auth/Label/Noun"
+msgid "Read-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:150
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Read-only access to user data"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:39
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:25
+msgctxt "Content/Moderation/*/Noun"
 msgid "Reason"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:222
+#: front/src/views/admin/moderation/AccountsDetail.vue:251
 #: front/src/views/admin/moderation/DomainsDetail.vue:179
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Received library follows"
 msgstr ""
 
 #: front/src/components/manage/moderation/DomainsTable.vue:40
-#: front/src/components/mixins/Translations.vue:36
-#: front/src/components/mixins/Translations.vue:37
+#: front/src/components/mixins/Translations.vue:62
+#: front/src/components/mixins/Translations.vue:63
+msgctxt "Content/Moderation/*/Noun"
 msgid "Received messages"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:27
+#, fuzzy
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits"
+msgstr "Недавно добавленные"
+
+#: front/src/components/library/EditForm.vue:17
+msgctxt "Content/Library/Paragraph"
+msgid "Recent edits awaiting review"
+msgstr ""
+
 #: front/src/components/library/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Recently added"
 msgstr "Недавно добавленные"
 
 #: front/src/components/library/Home.vue:11
-#, fuzzy
+msgctxt "Content/Home/Title"
 msgid "Recently favorited"
 msgstr "Недавно добавленные в избранное"
 
 #: front/src/components/library/Home.vue:6
+msgctxt "Content/Home/Title"
 msgid "Recently listened"
 msgstr "Недавно прослушанные"
 
-#: front/src/views/content/remote/Home.vue:15
+#: front/src/components/auth/ApplicationForm.vue:13
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Redirect URI"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:125
+#: src/components/auth/Settings.vue:170
+#: front/src/components/common/EmptyState.vue:16
+#: src/views/content/remote/Home.vue:15
+msgctxt "Content/*/Button.Label/Short, Verb"
 msgid "Refresh"
 msgstr "Обновить"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:135
+#: front/src/components/federation/FetchButton.vue:20
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh error"
+msgstr "Обновить"
+
+#: front/src/views/admin/library/AlbumDetail.vue:50
+#: front/src/views/admin/library/ArtistDetail.vue:49
+#: front/src/views/admin/library/TrackDetail.vue:49
+msgctxt "Content/Moderation/Button/Verb"
+msgid "Refresh from remote server"
+msgstr ""
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:127
+msgctxt "Content/Moderation/Button.Label/Verb"
 msgid "Refresh node info"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:272
+#: front/src/components/federation/FetchButton.vue:79
+#, fuzzy
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh pending"
+msgstr "По убыванию"
+
+#: front/src/components/federation/FetchButton.vue:80
+msgctxt "Popup/*/Message.Content"
+msgid "Refresh request wasn't proceed in time by our server. It will be processed later."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:16
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh successful"
+msgstr ""
+
+#: front/src/components/common/ActionTable.vue:275
+msgctxt "Content/*/Button.Tooltip/Verb"
 msgid "Refresh table content"
 msgstr ""
 
-#: front/src/components/auth/Profile.vue:12
-msgid "Registered since %{ date }"
-msgstr "Зарегистрировано с %{ date }"
+#: front/src/components/federation/FetchButton.vue:12
+msgctxt "Popup/*/Message.Title"
+msgid "Refresh was skipped"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:7
+msgctxt "Popup/*/Title"
+msgid "Refreshing object from remote…"
+msgstr ""
 
 #: front/src/components/auth/Signup.vue:9
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
 msgid "Registration are closed on this instance, you will need an invitation code to signup."
 msgstr "Регистрация на этом узле закрыта, вам понадобится код приглашения чтобы зарегистрироваться."
 
 #: front/src/components/manage/users/UsersTable.vue:71
-msgid "regular user"
+#, fuzzy
+msgctxt "Content/Admin/Table, User role"
+msgid "Regular user"
 msgstr "обычный пользователь"
 
+#: front/src/components/library/EditCard.vue:87
 #: front/src/views/content/libraries/Detail.vue:51
+msgctxt "Content/Library/Button.Label"
 msgid "Reject"
 msgstr "Отклонить"
 
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:32
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:123
 #, fuzzy
+msgctxt "Content/Moderation/*/Verb"
 msgid "Reject media"
 msgstr "Отклонено"
 
+#: front/src/components/library/EditCard.vue:33
+#: front/src/components/manage/library/EditsCardList.vue:24
 #: front/src/views/content/libraries/Detail.vue:43
+#, fuzzy
+msgctxt "Content/Library/*/Short"
 msgid "Rejected"
 msgstr "Отклонено"
 
-#: front/src/views/content/libraries/FilesTable.vue:234
-msgid "Relaunch import"
-msgstr "Перезапустить импорт"
+#: front/src/components/manage/library/AlbumsTable.vue:43
+#: front/src/components/mixins/Translations.vue:44 src/edits.js:28
+#: front/src/components/mixins/Translations.vue:45
+#, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Release date"
+msgstr "Последнее обновление:"
+
+#: front/src/components/library/FileUpload.vue:63
+msgctxt "Content/Library/Paragraph"
+msgid "Remaining storage space"
+msgstr ""
 
 #: front/src/views/content/remote/Home.vue:6
+msgctxt "Content/Library/Title/Noun"
 msgid "Remote libraries"
 msgstr "Удалённые библиотеки"
 
 #: front/src/views/content/remote/Home.vue:7
+msgctxt "Content/Library/Paragraph"
 msgid "Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access."
 msgstr "Удалёнными библиотеками владеют другие пользователи в сети. Вы можете получить к ним доступ если они публичны или вам предоставлен доступ."
 
 #: front/src/components/library/radios/Filter.vue:59
+msgctxt "Content/Radio/Button.Label/Verb"
 msgid "Remove"
 msgstr "Удалить"
 
 #: front/src/components/auth/Settings.vue:58
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Remove avatar"
 msgstr "Удалить аватар"
 
+#: front/src/components/library/ArtistDetail.vue:12
+#, fuzzy
+msgctxt "Content/Moderation/Button.Label"
+msgid "Remove filter"
+msgstr "Удалить аватар"
+
 #: front/src/components/favorites/TrackFavoriteIcon.vue:26
+#, fuzzy
+msgctxt "Content/Track/Icon.Tooltip/Verb"
 msgid "Remove from favorites"
 msgstr "Удалить из избранного"
 
 #: front/src/views/content/libraries/Quota.vue:38
+#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Это удалит треки которые были загружены но ещё не обработаны. Файлы будут полностью удалены и вы получите соответствующую квоту."
 
 #: front/src/views/content/libraries/Quota.vue:64
+#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota."
-msgstr ""
+msgstr "Это удалит треки которые были загружены но ещё не обработаны. Файлы будут полностью удалены и вы получите соответствующую квоту."
 
 #: front/src/views/content/libraries/Quota.vue:90
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota."
 msgstr "Это удалит треки которые были загружены но ещё не обработаны. Файлы будут полностью удалены и вы получите соответствующую квоту."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:34
-#: front/src/components/auth/SubsonicTokenForm.vue:37
+#: front/src/components/auth/SubsonicTokenForm.vue:33
+#: front/src/components/auth/SubsonicTokenForm.vue:36
+#, fuzzy
+msgctxt "*/Settings/Button.Label/Verb"
 msgid "Request a new password"
 msgstr "Запросить новый пароль"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:35
+#: front/src/components/auth/SubsonicTokenForm.vue:34
+msgctxt "Popup/Settings/Title"
 msgid "Request a new Subsonic API password?"
 msgstr "Запросить новый пароль Subsonic API?"
 
-#: front/src/components/auth/SubsonicTokenForm.vue:43
+#: front/src/components/auth/SubsonicTokenForm.vue:42
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Request a password"
 msgstr "Запросить пароль"
 
-#: front/src/components/auth/Login.vue:34 src/views/auth/PasswordReset.vue:4
-#: front/src/views/auth/PasswordReset.vue:52
+#: front/src/components/federation/FetchButton.vue:64
+msgctxt "Popup/*/Loading.Title"
+msgid "Requesting a fetch…"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:82
+msgctxt "Content/Library/Button.Label"
+msgid "Reset to initial value: %{ value }"
+msgstr ""
+
+#: front/src/components/auth/Login.vue:35 src/views/auth/PasswordReset.vue:4
+#: front/src/views/auth/PasswordReset.vue:53
+#, fuzzy
+msgctxt "*/Login/*/Verb"
 msgid "Reset your password"
 msgstr "Сбросить ваш пароль"
 
-#: front/src/components/favorites/List.vue:38
-#: src/components/library/Artists.vue:30
-#: front/src/components/library/Radios.vue:52 src/views/playlists/List.vue:32
+#: front/src/views/content/libraries/FilesTable.vue:223
+#, fuzzy
+msgctxt "Content/Library/Dropdown/Verb"
+msgid "Restart import"
+msgstr "Перезапустить импорт"
+
+#: front/src/components/favorites/List.vue:39
+#: src/components/library/Albums.vue:30
+#: front/src/components/library/Artists.vue:30
+#: src/components/library/Radios.vue:52 front/src/views/playlists/List.vue:32
+msgctxt "Content/Search/Dropdown.Label/Noun"
 msgid "Results per page"
 msgstr "Результатов на страницу"
 
+#: front/src/components/library/EditForm.vue:31
+msgctxt "Content/Library/Button.Label"
+msgid "Retrict to unreviewed edits"
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:17
-#, fuzzy
+msgctxt "Content/Signup/Link/Verb"
 msgid "Return to login"
 msgstr "Назад ко входу"
 
+#: front/src/components/library/ArtistDetail.vue:9
+#, fuzzy
+msgctxt "Content/Moderation/Link"
+msgid "Review my filters"
+msgstr "Просмотреть файлы"
+
+#: front/src/components/auth/Settings.vue:192
+msgctxt "*/*/*/Verb"
+msgid "Revoke"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:195
+msgctxt "*/Settings/Button.Label/Verb"
+msgid "Revoke access"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:193
+msgctxt "Popup/Settings/Title"
+msgid "Revoke access for application \"%{ application }\"?"
+msgstr ""
+
 #: front/src/components/manage/moderation/InstancePolicyCard.vue:16
+msgctxt "Content/Moderation/Card.Title/Noun"
 msgid "Rule"
 msgstr ""
 
-#: front/src/components/admin/SettingsGroup.vue:63
-#: front/src/components/library/radios/Builder.vue:33
+#: front/src/components/admin/SettingsGroup.vue:67
+#: front/src/components/library/radios/Builder.vue:34
+#, fuzzy
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Save"
 msgstr "Сохранить"
 
-#: front/src/views/content/remote/Card.vue:165
+#: front/src/views/content/remote/Card.vue:169
+msgctxt "Content/Library/Message"
 msgid "Scan launched"
 msgstr "Сканирование запущено"
 
-#: front/src/views/content/remote/Card.vue:63
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:67
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Scan now"
 msgstr "Сейчас проигрывается"
 
-#: front/src/views/content/remote/Card.vue:166
+#: front/src/views/content/remote/Card.vue:35
+#, fuzzy
+msgctxt "Content/Library/Card.List item"
+msgid "Scan pending"
+msgstr "По возрастанию"
+
+#: front/src/views/content/remote/Card.vue:170
+msgctxt "Content/Library/Message"
 msgid "Scan skipped (previous scan is too recent)"
 msgstr "Сканирование пропущено (предыдущее сканирование было совсем недавно)"
 
-#: front/src/views/content/remote/Card.vue:31
-#, fuzzy
-msgid "Scan waiting"
-msgstr "Ожидается сканирование"
-
-#: front/src/views/content/remote/Card.vue:43
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:47
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned"
 msgstr "Сканирование запущено"
 
-#: front/src/views/content/remote/Card.vue:47
+#: front/src/views/content/remote/Card.vue:51
+msgctxt "Content/Library/Card.List item"
 msgid "Scanned with errors"
 msgstr "Просканировано с ошибками"
 
-#: front/src/views/content/remote/Card.vue:35
-#, fuzzy
+#: front/src/views/content/remote/Card.vue:39
+msgctxt "Content/Library/Card.List item"
 msgid "Scanning… (%{ progress }%)"
 msgstr "Сканирование... (%{ progress }%)"
 
-#: front/src/components/library/Artists.vue:10
-#: src/components/library/Radios.vue:29
-#: front/src/components/manage/library/FilesTable.vue:5
+#: front/src/components/auth/ApplicationForm.vue:22
+msgctxt "Content/Applications/Input.Label/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:226
+msgctxt "Content/*/*/Noun"
+msgid "Scopes"
+msgstr ""
+
+#: front/src/components/library/Albums.vue:10
+#: src/components/library/Artists.vue:10
+#: front/src/components/library/Radios.vue:29
+#: front/src/components/manage/library/AlbumsTable.vue:5
+#: front/src/components/manage/library/ArtistsTable.vue:5
+#: front/src/components/manage/library/EditsCardList.vue:6
+#: front/src/components/manage/library/LibrariesTable.vue:5
+#: front/src/components/manage/library/TracksTable.vue:5
+#: front/src/components/manage/library/UploadsTable.vue:5
 #: front/src/components/manage/moderation/AccountsTable.vue:5
 #: front/src/components/manage/moderation/DomainsTable.vue:5
 #: front/src/components/manage/users/InvitationsTable.vue:5
 #: front/src/components/manage/users/UsersTable.vue:5
 #: front/src/views/content/libraries/FilesTable.vue:5
 #: src/views/playlists/List.vue:13
+msgctxt "Content/Search/Input.Label/Noun"
 msgid "Search"
 msgstr "Поиск"
 
 #: front/src/views/content/remote/ScanForm.vue:9
+msgctxt "Content/Library/Input.Label/Verb"
 msgid "Search a remote library"
 msgstr "Искать в удалённой библиотеке"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:171
+#: front/src/components/manage/library/EditsCardList.vue:211
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by account, summary, domain…"
+msgstr "Искать по названию, исполнителю, домену..."
+
+#: front/src/components/manage/library/LibrariesTable.vue:191
 #, fuzzy
-msgid "Search by domain, username, bio..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, description…"
 msgstr "Искать по пользователю, адресу электронной почты, коду..."
 
-#: front/src/components/manage/moderation/DomainsTable.vue:151
+#: front/src/components/manage/library/UploadsTable.vue:241
 #, fuzzy
-msgid "Search by name..."
-msgstr "Искать по имени пользователя, адресу электронной почты, имени..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, actor, name, reference, source…"
+msgstr "Искать по пользователю, адресу электронной почты, коду..."
 
-#: front/src/views/content/libraries/FilesTable.vue:201
+#: front/src/components/manage/library/ArtistsTable.vue:164
 #, fuzzy
-msgid "Search by title, artist, album…"
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, name, MusicBrainz ID…"
+msgstr "Искать по пользователю, адресу электронной почты, коду..."
+
+#: front/src/components/manage/library/TracksTable.vue:174
+#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, album, MusicBrainz ID…"
 msgstr "Искать по названию, исполнителю, альбому..."
 
-#: front/src/components/manage/library/FilesTable.vue:176
+#: front/src/components/manage/library/AlbumsTable.vue:174
 #, fuzzy
-msgid "Search by title, artist, domain…"
-msgstr "Искать по названию, исполнителю, домену..."
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, title, artist, MusicBrainz ID…"
+msgstr "Искать по названию, исполнителю, альбому..."
+
+#: front/src/components/manage/moderation/AccountsTable.vue:171
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by domain, username, bio…"
+msgstr "Искать по пользователю, адресу электронной почты, коду..."
+
+#: front/src/components/manage/moderation/DomainsTable.vue:151
+msgctxt "Content/Search/Input.Placeholder"
+msgid "Search by name…"
+msgstr "Искать по имени пользователя, адресу электронной почты, имени..."
+
+#: front/src/views/content/libraries/FilesTable.vue:208
+msgctxt "Content/Library/Input.Placeholder"
+msgid "Search by title, artist, album…"
+msgstr "Искать по названию, исполнителю, альбому..."
 
 #: front/src/components/manage/users/InvitationsTable.vue:153
 #, fuzzy
+msgctxt "Content/Admin/Input.Placeholder/Verb"
 msgid "Search by username, e-mail address, code…"
 msgstr "Искать по пользователю, адресу электронной почты, коду..."
 
 #: front/src/components/manage/users/UsersTable.vue:163
-#, fuzzy
+msgctxt "Content/Search/Input.Placeholder"
 msgid "Search by username, e-mail address, name…"
 msgstr "Искать по имени пользователя, адресу электронной почты, имени..."
 
 #: front/src/components/audio/SearchBar.vue:20
-#, fuzzy
+msgctxt "Sidebar/Search/Input.Placeholder"
 msgid "Search for artists, albums, tracks…"
 msgstr "Искать исполнителей, альбомы, треки..."
 
 #: front/src/components/audio/Search.vue:2
+msgctxt "Content/Search/Title"
 msgid "Search for some music"
 msgstr "Поискать музыку"
 
-#: front/src/components/library/Track.vue:162
-msgid "Search on lyrics.wikia.com"
-msgstr "Искать на lyrics.wikia.com"
-
-#: front/src/components/library/Album.vue:33
-#: src/components/library/Artist.vue:31
-#: front/src/components/library/Track.vue:47
+#: front/src/components/library/AlbumBase.vue:57
+#: front/src/components/library/ArtistBase.vue:68
+#: front/src/components/library/TrackBase.vue:76
+msgctxt "Content/*/Button.Label/Verb"
 msgid "Search on Wikipedia"
 msgstr "Искать на Википедии"
 
-#: front/src/components/library/Library.vue:32
-#: src/views/admin/library/Base.vue:17
+#: front/src/components/library/Library.vue:35
+#: src/views/admin/library/Base.vue:32
 #: front/src/views/admin/moderation/Base.vue:22
 #: src/views/admin/users/Base.vue:21 front/src/views/content/Base.vue:19
+msgctxt "Menu/*/Hidden text"
 msgid "Secondary menu"
 msgstr ""
 
 #: front/src/views/admin/Settings.vue:15
+msgctxt "Content/Admin/Menu.Title"
 msgid "Sections"
 msgstr "Разделы"
 
-#: front/src/components/library/radios/Builder.vue:45
+#: front/src/components/library/radios/Builder.vue:46
+msgctxt "Content/Radio/Dropdown.Placeholder/Verb"
 msgid "Select a filter"
 msgstr "Выберите фильтр"
 
-#: front/src/components/common/ActionTable.vue:77
+#: front/src/components/common/ActionTable.vue:79
+#, fuzzy
+msgctxt "Content/*/Link/Verb"
 msgid "Select all %{ total } elements"
 msgid_plural "Select all %{ total } elements"
 msgstr[0] "Выделить %{ total } элемент"
 msgstr[1] "Выделить все %{ total } элемента"
 msgstr[2] "Выделить все %{ total } элементов"
 
-#: front/src/components/common/ActionTable.vue:86
+#: front/src/components/common/ActionTable.vue:88
+msgctxt "Content/*/Link/Verb"
 msgid "Select only current page"
 msgstr "Выбрать только текущую страницу"
 
-#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:85
+#: front/src/components/Sidebar.vue:43 src/components/Sidebar.vue:108
 #: front/src/components/manage/users/UsersTable.vue:181
-#: front/src/views/admin/moderation/AccountsDetail.vue:472
+#: front/src/views/admin/moderation/AccountsDetail.vue:506
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Settings"
 msgstr "Настройки"
 
 #: front/src/components/auth/Settings.vue:10
+msgctxt "Content/Settings/Message"
 msgid "Settings updated"
 msgstr "Настройки обновлены"
 
 #: front/src/components/admin/SettingsGroup.vue:11
+msgctxt "Content/Settings/Paragraph"
 msgid "Settings updated successfully."
 msgstr "Настройки успешно обновлены."
 
 #: front/src/components/manage/users/InvitationForm.vue:27
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Share link"
 msgstr "Поделиться ссылкой"
 
 #: front/src/views/content/libraries/Detail.vue:15
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Share this link with other users so they can request access to your library."
 msgstr "Поделитесь этой ссылкой с другими пользователями чтобы они могли запросить доступ к вашей библиотеке."
 
 #: front/src/views/content/libraries/Detail.vue:14
-#: front/src/views/content/remote/Card.vue:73
+#: front/src/views/content/remote/Card.vue:77
+#, fuzzy
+msgctxt "Content/Library/Title"
 msgid "Sharing link"
-msgstr ""
+msgstr "Поделиться ссылкой"
 
-#: front/src/components/audio/album/Card.vue:40
+#: front/src/components/audio/album/Card.vue:38
+#, fuzzy
+msgctxt "Content/Album/Card.Link/Verb"
 msgid "Show %{ count } more track"
 msgid_plural "Show %{ count } more tracks"
 msgstr[0] "Показать больше на %{ count } трек"
@@ -2320,765 +3893,1371 @@ msgstr[1] "Показать больше на %{ count } трека"
 msgstr[2] "Показать больше на %{ count } треков"
 
 #: front/src/components/audio/artist/Card.vue:30
+#, fuzzy
+msgctxt "Content/Artist/Card.Link"
 msgid "Show 1 more album"
 msgid_plural "Show %{ count } more albums"
 msgstr[0] "Показать больше на %{ count } альбом"
 msgstr[1] "Показать больше на %{ count } альбома"
 msgstr[2] "Показать больше на %{ count } альбомов"
 
+#: front/src/components/library/EditForm.vue:21
+msgctxt "Content/Library/Button.Label"
+msgid "Show all edits"
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:42
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Show available keyboard shortcuts"
 msgstr ""
 
-#: front/src/views/Notifications.vue:10
+#: front/src/views/Notifications.vue:7
+msgctxt "Content/Notifications/Form.Label/Verb"
 msgid "Show read notifications"
 msgstr "Показывать прочитанные уведомления"
 
-#: front/src/components/forms/PasswordInput.vue:25
+#: front/src/components/forms/PasswordInput.vue:26
+msgctxt "Content/Settings/Button.Tooltip/Verb"
 msgid "Show/hide password"
 msgstr "Показать/скрыть пароль"
 
-#: front/src/components/manage/library/FilesTable.vue:97
+#: front/src/components/manage/library/AlbumsTable.vue:93
+#: front/src/components/manage/library/ArtistsTable.vue:84
+#: front/src/components/manage/library/EditsCardList.vue:72
+#: front/src/components/manage/library/LibrariesTable.vue:110
+#: front/src/components/manage/library/TracksTable.vue:95
+#: front/src/components/manage/library/UploadsTable.vue:144
 #: front/src/components/manage/moderation/AccountsTable.vue:88
 #: front/src/components/manage/moderation/DomainsTable.vue:74
 #: front/src/components/manage/users/InvitationsTable.vue:76
 #: front/src/components/manage/users/UsersTable.vue:87
-#: front/src/views/content/libraries/FilesTable.vue:114
+#: front/src/views/content/libraries/FilesTable.vue:117
+#, fuzzy
+msgctxt "Content/*/Paragraph"
 msgid "Showing results %{ start }-%{ end } on %{ total }"
 msgstr "Показаны результаты %{ start }-%{ end } из %{ total }"
 
 #: front/src/components/ShortcutsModal.vue:83
-#, fuzzy
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Shuffle queue"
 msgstr "Перемешать вашу очередь"
 
-#: front/src/components/audio/Player.vue:362
+#: front/src/components/audio/Player.vue:613
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Shuffle your queue"
 msgstr "Перемешать вашу очередь"
 
-#: front/src/components/auth/Signup.vue:95
+#: front/src/components/auth/Signup.vue:97
+msgctxt "*/Signup/Title"
 msgid "Sign Up"
 msgstr "Регистрация"
 
 #: front/src/components/manage/users/UsersTable.vue:40
+msgctxt "Content/Admin/Table.Label/Short, Noun (Value is a date)"
 msgid "Sign-up"
 msgstr "Регистрация"
 
-#: front/src/components/mixins/Translations.vue:31
-#: front/src/views/admin/moderation/AccountsDetail.vue:176
-#: front/src/components/mixins/Translations.vue:32
+#: front/src/components/mixins/Translations.vue:57
+#: front/src/views/admin/moderation/AccountsDetail.vue:197
+#: front/src/components/mixins/Translations.vue:58
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun"
 msgid "Sign-up date"
 msgstr "Дата регистрации"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:24
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:115
+#: front/src/components/library/FileUpload.vue:94
+#: front/src/components/library/TrackDetail.vue:39
+#: front/src/components/mixins/Translations.vue:54
+#: front/src/views/content/libraries/FilesTable.vue:61
+#: front/src/components/mixins/Translations.vue:55
 #, fuzzy
-msgid "Silence activity"
-msgstr "Пользовательская активность"
+msgctxt "Content/Library/*/in MB"
+msgid "Size"
+msgstr "Размер"
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:28
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:119
+#: front/src/components/manage/library/UploadsTable.vue:65
+#: front/src/views/admin/library/UploadDetail.vue:219
 #, fuzzy
-msgid "Silence notifications"
-msgstr "Показывать прочитанные уведомления"
-
-#: front/src/components/library/FileUpload.vue:85
-#: front/src/components/library/Track.vue:120
-#: front/src/components/manage/library/FilesTable.vue:44
-#: front/src/components/mixins/Translations.vue:28
-#: front/src/views/content/libraries/FilesTable.vue:60
-#: front/src/components/mixins/Translations.vue:29
+msgctxt "Content/*/*/Noun"
 msgid "Size"
 msgstr "Размер"
 
+#: front/src/components/manage/library/UploadsTable.vue:24
+#: front/src/components/mixins/Translations.vue:24
 #: front/src/views/content/libraries/FilesTable.vue:15
-#: front/src/views/content/libraries/FilesTable.vue:204
+#: front/src/components/mixins/Translations.vue:25
+#, fuzzy
+msgctxt "Content/Library/*"
 msgid "Skipped"
 msgstr "Пропущено"
 
 #: front/src/views/content/libraries/Quota.vue:49
+msgctxt "Content/Library/Label"
 msgid "Skipped files"
 msgstr "Пропущенные файлы"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:97
+#: front/src/views/admin/moderation/DomainsDetail.vue:89
+msgctxt "Content/Moderation/Table.Label"
 msgid "Software"
 msgstr ""
 
+#: front/src/components/playlists/Editor.vue:21
+msgctxt "Content/Playlist/Paragraph"
+msgid "Some tracks in your queue are already in this playlist:"
+msgstr ""
+
+#: front/src/components/PageNotFound.vue:10
+#, fuzzy
+msgctxt "Content/*/Paragraph"
+msgid "Sorry, the page you asked for does not exist:"
+msgstr "Извините, страницы которую вы запрашивали не существует:"
+
 #: front/src/components/Footer.vue:49
+msgctxt "Footer/*/List item.Link"
 msgid "Source code"
 msgstr "Исходный код"
 
 #: front/src/components/auth/Profile.vue:23
 #: front/src/components/manage/users/UsersTable.vue:70
+msgctxt "Content/Profile/User role"
 msgid "Staff member"
 msgstr ""
 
-#: front/src/components/radios/Button.vue:4
+#: front/src/components/audio/PlayButton.vue:23
+#: src/components/radios/Button.vue:4
 #, fuzzy
-msgid "Start"
-msgstr "Начать"
+msgctxt "*/Queue/Button.Label/Short, Verb"
+msgid "Start radio"
+msgstr "Остановить радио"
 
 #: front/src/views/admin/Settings.vue:86
+msgctxt "Content/Admin/Menu"
 msgid "Statistics"
 msgstr "Статистика"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:454
+#: front/src/views/admin/moderation/AccountsDetail.vue:490
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"
 msgstr ""
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:358
+#: front/src/views/admin/moderation/DomainsDetail.vue:371
+msgctxt "Content/Moderation/Help text"
 msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:86
+#: front/src/views/admin/library/AlbumDetail.vue:329
+#: front/src/views/admin/library/ArtistDetail.vue:328
+#: front/src/views/admin/library/LibraryDetail.vue:316
+#: front/src/views/admin/library/TrackDetail.vue:371
+#: front/src/views/admin/library/UploadDetail.vue:335
+msgctxt "Content/Moderation/Help text"
+msgid "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object"
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:95
+#, fuzzy
+msgctxt "Content/Library/Table.Label (Value is Uploading/Uploaded/Error)"
+msgid "Status"
+msgstr "Статус"
+
+#: front/src/views/admin/moderation/DomainsDetail.vue:115
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label (Value is Error message)"
+msgid "Status"
+msgstr "Статус"
+
+#: front/src/components/manage/library/EditsCardList.vue:12
+#, fuzzy
+msgctxt "Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)"
+msgid "Status"
+msgstr "Статус"
+
+#: front/src/components/manage/users/UsersTable.vue:43
+#, fuzzy
+msgctxt "Content/Admin/Table.Label/Noun (Value is Regular user/Admin)"
+msgid "Status"
+msgstr "Статус"
+
 #: front/src/components/manage/users/InvitationsTable.vue:17
 #: front/src/components/manage/users/InvitationsTable.vue:39
-#: front/src/components/manage/users/UsersTable.vue:43
-#: front/src/views/admin/moderation/DomainsDetail.vue:123
-#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Admin/*/Noun (Value is Used/Not used)"
 msgid "Status"
 msgstr "Статус"
 
-#: front/src/components/radios/Button.vue:3
-msgid "Stop"
-msgstr "Остановить"
+#: front/src/views/content/libraries/Detail.vue:28
+#, fuzzy
+msgctxt "Content/Library.Federation/Table.Label (Value is Approved/Rejected)"
+msgid "Status"
+msgstr "Статус"
 
-#: front/src/components/Sidebar.vue:161
+#: front/src/components/Sidebar.vue:174 src/components/radios/Button.vue:3
+#, fuzzy
+msgctxt "*/Player/Button.Label/Short, Verb"
 msgid "Stop radio"
 msgstr "Остановить радио"
 
-#: front/src/App.vue:22
+#: front/src/components/SetInstanceModal.vue:23
+msgctxt "*/*/Button.Label/Verb"
 msgid "Submit"
 msgstr "Отправить"
 
+#: front/src/components/library/EditForm.vue:98
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit and apply edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:7
+msgctxt "Content/Library/Button.Label"
+msgid "Submit another edit"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:99
+msgctxt "Content/Library/Button.Label/Verb"
+msgid "Submit suggestion"
+msgstr ""
+
 #: front/src/views/admin/Settings.vue:85
+msgctxt "Content/Admin/Menu"
 msgid "Subsonic"
 msgstr "Subsonic"
 
 #: front/src/components/auth/SubsonicTokenForm.vue:2
+msgctxt "Content/Settings/Title"
 msgid "Subsonic API password"
 msgstr "Пароль Subsonic API"
 
-#: front/src/App.vue:26
+#: front/src/components/library/EditForm.vue:38
+msgctxt "Content/Library/Paragraph"
+msgid "Suggest a change using the form below."
+msgstr ""
+
+#: front/src/components/library/AlbumEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this album"
+msgstr "Нам не удалось добавить трек в список воспроизведения"
+
+#: front/src/components/library/ArtistEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this artist"
+msgstr "Нам не удалось добавить трек в список воспроизведения"
+
+#: front/src/components/library/TrackEdit.vue:5
+#, fuzzy
+msgctxt "Content/*/Title"
+msgid "Suggest an edit on this track"
+msgstr "Нам не удалось добавить трек в список воспроизведения"
+
+#: front/src/components/SetInstanceModal.vue:31
+msgctxt "Popup/Instance/List.Label"
 msgid "Suggested choices"
 msgstr "Предложенные изменения"
 
 #: front/src/components/library/FileUpload.vue:3
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Summary"
 msgstr ""
 
+#: front/src/components/library/EditForm.vue:87
+msgctxt "*/*/*"
+msgid "Summary (optional)"
+msgstr ""
+
 #: front/src/components/Footer.vue:39
+msgctxt "Footer/*/Listitem.Link"
 msgid "Support forum"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:78
+#: front/src/components/library/FileUpload.vue:85
+msgctxt "Content/Library/Paragraph"
 msgid "Supported extensions: %{ extensions }"
 msgstr ""
 
 #: front/src/components/playlists/Editor.vue:9
-#, fuzzy
+msgctxt "Content/Playlist/Paragraph"
 msgid "Syncing changes to server…"
 msgstr "Синхронизируем изменения с сервером..."
 
+#: front/src/components/audio/EmbedWizard.vue:25
 #: front/src/components/common/CopyInput.vue:3
+msgctxt "Content/*/Paragraph"
 msgid "Text copied to clipboard!"
 msgstr "Текст скопирован в буфер обмена!"
 
 #: front/src/components/Home.vue:26
+msgctxt "Content/Home/Paragraph"
 msgid "That's simple: we loved Grooveshark and we want to build something even better."
 msgstr "Это просто: нам нравился Grooveshark и мы хотели создать что-то ещё лучшее."
 
+#: front/src/views/admin/library/AlbumDetail.vue:75
+msgctxt "Content/Moderation/Paragraph"
+msgid "The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:39
+msgctxt "Content/Auth/Paragraph"
+msgid "The application is also requesting the following unknown permissions:"
+msgstr ""
+
+#: front/src/views/admin/library/ArtistDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
 #: front/src/components/Footer.vue:53
+msgctxt "Footer/*/List item.Link"
 msgid "The funkwhale logo was kindly designed and provided by Francis Gading."
 msgstr "Логотип funkwhale был любезно предоставлен Francis Gading."
 
+#: front/src/components/SetInstanceModal.vue:8
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The given address is not a Funkwhale server"
+msgstr ""
+
 #: front/src/views/content/libraries/Form.vue:34
-#, fuzzy
+msgctxt "Popup/Library/Paragraph"
 msgid "The library and all its tracks will be deleted. This can not be undone."
 msgstr "Библиотека и все треки в ней будут удалены. Это действие необратимо."
 
-#: front/src/components/library/FileUpload.vue:39
-msgid "The music files you are uploading are tagged properly:"
+#: front/src/views/admin/library/LibraryDetail.vue:61
+msgctxt "Content/Moderation/Paragraph"
+msgid "The library will be removed, as well as associated uploads, and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:140
+msgctxt "Popup/Import/Error.Label"
+msgid "The metadata included in the file is invalid or some mandatory fields are missing."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:38
+msgctxt "Content/Library/List item"
+msgid "The music files you are uploading are tagged properly."
 msgstr ""
 
-#: front/src/components/audio/Player.vue:67
-msgid "The next track will play automatically in a few seconds..."
+#: front/src/components/audio/Player.vue:65
+msgctxt "Sidebar/Player/Error message.Paragraph"
+msgid "The next track will play automatically in a few seconds…"
 msgstr ""
 
-#: front/src/components/Home.vue:121
+#: front/src/components/Home.vue:116
+msgctxt "Content/Home/List item"
 msgid "The plaform is free and open-source, you can install it and modify it without worries"
 msgstr ""
 
+#: front/src/components/playlists/Form.vue:14
+#, fuzzy
+msgctxt "Content/Playlist/Error message.Title"
+msgid "The playlist could not be created"
+msgstr "Список воспроизведения создан"
+
+#: front/src/components/federation/FetchButton.vue:37
+msgctxt "*/*/Error"
+msgid "The remote server answered with HTTP %{ status }"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:13
+msgctxt "Popup/*/Message.Content"
+msgid "The remote server answered, but returned data was unsupported by Funkwhale."
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:44
+msgctxt "*/*/Error"
+msgid "The remote server didn't answered fast enough"
+msgstr ""
+
+#: front/src/components/federation/FetchButton.vue:50
+msgctxt "*/*/Error"
+msgid "The return server returned invalid JSON or JSON-LD data"
+msgstr ""
+
+#: front/src/components/manage/library/AlbumsTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/ArtistsTable.vue:179
+msgctxt "Popup/*/Paragraph"
+msgid "The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/LibrariesTable.vue:206
+msgctxt "Popup/*/Paragraph"
+msgid "The selected library will be removed, as well as associated uploads and follows. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/TracksTable.vue:189
+msgctxt "Popup/*/Paragraph"
+msgid "The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/components/manage/library/UploadsTable.vue:256
+msgctxt "Popup/*/Paragraph"
+msgid "The selected upload will be removed. This action is irreversible."
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:7
+msgctxt "Popup/Instance/Error message.List item"
+msgid "The server might be down"
+msgstr ""
+
 #: front/src/components/auth/SubsonicTokenForm.vue:4
+msgctxt "Content/Settings/Paragraph"
 msgid "The Subsonic API is not available on this Funkwhale instance."
 msgstr "Subsonic API недоступен на этом узле Funkwhale."
 
-#: front/src/components/library/FileUpload.vue:43
+#: front/src/components/library/EditCard.vue:96
+msgctxt "Popup/Library/Paragraph"
+msgid "The suggestion will be completely removed, this action is irreversible."
+msgstr ""
+
+#: front/src/components/playlists/PlaylistModal.vue:34
+#, fuzzy
+msgctxt "Popup/Playlist/Error message.Title"
+msgid "The track can't be added to a playlist"
+msgstr "Нам не удалось добавить трек в список воспроизведения"
+
+#: front/src/components/audio/Player.vue:62
+msgctxt "Sidebar/Player/Error message.Title"
+msgid "The track cannot be loaded"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:74
+msgctxt "Content/Moderation/Paragraph"
+msgid "The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible."
+msgstr ""
+
+#: front/src/views/admin/library/UploadDetail.vue:68
+msgctxt "Content/Moderation/Paragraph"
+msgid "The upload will be removed. This action is irreversible."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:42
+msgctxt "Content/Library/List item"
 msgid "The uploaded music files are in OGG, Flac or MP3 format"
 msgstr "Загружаемые музыкальные файлы в форматах OGG, Flac и MP3"
 
 #: front/src/views/content/Home.vue:4
+msgctxt "Content/Library/Paragraph"
 msgid "There are various ways to grab new content and make it available here."
 msgstr ""
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:66
+msgctxt "Popup/Moderation/Paragraph"
 msgid "This action is irreversible."
 msgstr ""
 
-#: front/src/components/library/Album.vue:91
+#: front/src/components/library/AlbumDetail.vue:29
+msgctxt "Content/Album/Paragraph"
 msgid "This album is present in the following libraries:"
 msgstr "Альбом представлен в следующих библиотеках:"
 
-#: front/src/components/library/Artist.vue:63
+#: front/src/components/library/ArtistDetail.vue:42
+msgctxt "Content/Artist/Paragraph"
 msgid "This artist is present in the following libraries:"
 msgstr "Исполнитель представлен в следующих библиотеках:"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:55
+#: front/src/views/admin/moderation/AccountsDetail.vue:84
 #: front/src/views/admin/moderation/DomainsDetail.vue:48
+msgctxt "Content/Moderation/Card.Title"
 msgid "This domain is subject to specific moderation rules"
 msgstr ""
 
 #: front/src/views/content/Home.vue:9
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "This instance offers up to %{quota} of storage space for every user."
 msgstr "Этот узел предоставляет до %{quota} дискового пространства каждому пользователю."
 
+#: front/src/components/auth/Settings.vue:165
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that have access to your account data."
+msgstr ""
+
+#: front/src/components/auth/Settings.vue:218
+msgctxt "Content/Settings/Paragraph"
+msgid "This is the list of applications that you have created."
+msgstr ""
+
 #: front/src/components/auth/Profile.vue:16
+msgctxt "Content/Profile/Button.Paragraph"
 msgid "This is you!"
 msgstr "Это вы!"
 
-#: front/src/views/content/libraries/Form.vue:71
-#, fuzzy
+#: front/src/views/content/libraries/Form.vue:73
+msgctxt "Content/Library/Input.Placeholder"
 msgid "This library contains my personal music, I hope you like it."
 msgstr "Эта библиотека содержит мою музыку, надеюсь она вам понравится!"
 
-#: front/src/views/content/remote/Card.vue:131
+#: front/src/views/content/remote/Card.vue:135
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is private and your approval from its owner is needed to access its content"
 msgstr ""
 
-#: front/src/views/content/remote/Card.vue:132
+#: front/src/views/content/remote/Card.vue:136
+msgctxt "Content/Library/Card.Help text"
 msgid "This library is public and you can access its content freely"
 msgstr ""
 
-#: front/src/components/common/ActionTable.vue:45
-#, fuzzy
+#: front/src/components/common/ActionTable.vue:47
+msgctxt "Modal/*/Paragraph"
 msgid "This may affect a lot of elements or have irreversible consequences, please double check this is really what you want."
 msgstr "Это может повлиять на многие элементы, пожалуйста перепроверьте что вы действительно хотите этого."
 
-#: front/src/components/library/FileUpload.vue:52
+#: front/src/components/library/AlbumEdit.vue:8
+#: front/src/components/library/ArtistEdit.vue:8
+#: front/src/components/library/TrackEdit.vue:8
+msgctxt "Content/*/Message"
+msgid "This object is managed by another server, you cannot edit it."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:51
+msgctxt "Content/Library/Paragraph"
 msgid "This reference will be used to group imported files together."
 msgstr ""
 
-#: front/src/components/audio/PlayButton.vue:73
+#: front/src/components/mixins/Translations.vue:33
+#: front/src/components/mixins/Translations.vue:34
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track could not be processed, please it is tagged correctly"
+msgstr "Произошла ошибка во время обработки этого трека, убедитесь что у него корректные теги"
+
+#: front/src/components/mixins/Translations.vue:29
+#: front/src/components/mixins/Translations.vue:30
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track has been uploaded, but hasn't been processed by the server yet"
+msgstr "Трек загружен но ещё не обработан сервером"
+
+#: front/src/components/mixins/Translations.vue:25
+#: front/src/components/mixins/Translations.vue:26
+#, fuzzy
+msgctxt "Content/Library/Help text"
+msgid "This track is already present in one of your libraries"
+msgstr "Трек уже был представлен в одной из ваших библиотек"
+
+#: front/src/components/audio/PlayButton.vue:85
+msgctxt "*/Queue/Button/Title"
 msgid "This track is not available in any library you have access to"
 msgstr ""
 
-#: front/src/components/library/Track.vue:171
+#: front/src/components/library/TrackDetail.vue:82
+msgctxt "Content/Track/Paragraph"
 msgid "This track is present in the following libraries:"
 msgstr "Этот трек представлен в следующих библиотеках:"
 
-#: front/src/views/playlists/Detail.vue:37
+#: front/src/views/playlists/Detail.vue:38
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will completely delete this playlist and cannot be undone."
 msgstr "Это необратимо удалит список воспроизведения."
 
 #: front/src/views/radios/Detail.vue:27
+msgctxt "Popup/Radio/Paragraph"
 msgid "This will completely delete this radio and cannot be undone."
 msgstr "Это радио будет необратимо удалено."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:51
+#: front/src/components/auth/SubsonicTokenForm.vue:50
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will completely disable access to the Subsonic API using from account."
 msgstr "Это полностью отключит доступ к Subsonic API для этого аккаунта."
 
-#: front/src/App.vue:129 src/components/Footer.vue:72
-msgid "This will erase your local data and disconnect you, do you want to continue?"
-msgstr ""
-
-#: front/src/components/auth/SubsonicTokenForm.vue:36
+#: front/src/components/auth/SubsonicTokenForm.vue:35
+msgctxt "Popup/Settings/Paragraph"
 msgid "This will log you out from existing devices that use the current password."
 msgstr "Это приведёт к отключению устройств которые используют текущий пароль."
 
-#: front/src/components/playlists/Editor.vue:44
+#: front/src/components/auth/Settings.vue:253
+#, fuzzy
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will permanently delete the application and all the associated tokens."
+msgstr "Это необратимо удалит список воспроизведения."
+
+#: front/src/components/auth/Settings.vue:194
+msgctxt "Popup/Settings/Paragraph"
+msgid "This will prevent this application from accessing the service on your behalf."
+msgstr ""
+
+#: front/src/components/playlists/Editor.vue:54
+msgctxt "Popup/Playlist/Paragraph"
 msgid "This will remove all tracks from this playlist and cannot be undone."
 msgstr "Это необратимо удалит все треки из этого списка воспроизведения."
 
-#: front/src/components/audio/track/Table.vue:6
-#: front/src/components/manage/library/FilesTable.vue:37
-#: front/src/components/mixins/Translations.vue:27
-#: front/src/views/content/libraries/FilesTable.vue:54
-#: front/src/components/mixins/Translations.vue:28
+#: front/src/views/admin/library/AlbumDetail.vue:99
+#: front/src/views/admin/library/TrackDetail.vue:98 src/edits.js:21
+#: src/edits.js:39
+#, fuzzy
+msgctxt "*/*/*/Noun"
+msgid "Title"
+msgstr "Название"
+
+#: front/src/components/audio/track/Table.vue:7
+#: front/src/views/content/libraries/FilesTable.vue:55
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
 msgid "Title"
 msgstr "Название"
 
+#: front/src/components/manage/library/AlbumsTable.vue:39
+#: front/src/components/manage/library/TracksTable.vue:39
+msgctxt "*/*/*"
+msgid "Title"
+msgstr "Название"
+
+#: front/src/components/SetInstanceModal.vue:16
+msgctxt "Popup/Instance/Paragraph"
+msgid "To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices."
+msgstr ""
+
 #: front/src/components/ShortcutsModal.vue:79
+msgctxt "Popup/Keyboard shortcuts/Table.Label/Verb"
 msgid "Toggle queue looping"
 msgstr ""
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:288
+#: front/src/views/admin/library/AlbumDetail.vue:222
+#: front/src/views/admin/library/ArtistDetail.vue:211
+#: front/src/views/admin/library/LibraryDetail.vue:200
+#: front/src/views/admin/library/TrackDetail.vue:274
+#: front/src/views/admin/moderation/AccountsDetail.vue:317
 #: front/src/views/admin/moderation/DomainsDetail.vue:225
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label"
 msgid "Total size"
-msgstr ""
+msgstr "Не используется"
 
-#: front/src/views/content/libraries/Card.vue:61
+#: front/src/views/content/libraries/Card.vue:68
+msgctxt "Content/Library/Card.Help text"
 msgid "Total size of the files in this library"
 msgstr "Суммарный размер файлов в этой библиотеке"
 
-#: front/src/views/admin/moderation/DomainsDetail.vue:113
-#, fuzzy
+#: front/src/views/admin/moderation/DomainsDetail.vue:105
+msgctxt "Content/*/*"
 msgid "Total users"
 msgstr "Не используется"
 
 #: front/src/components/audio/SearchBar.vue:27
-#: src/components/library/Track.vue:262
+#: front/src/components/library/TrackBase.vue:173
+#: front/src/components/library/TrackDetail.vue:128
 #: front/src/components/metadata/Search.vue:138
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Track"
 msgstr "Трек"
 
-#: front/src/views/content/libraries/FilesTable.vue:205
+#: front/src/views/admin/library/UploadDetail.vue:199
+msgctxt "*/*/*"
+msgid "Track"
+msgstr "Трек"
+
+#: front/src/components/library/EditCard.vue:13
+msgctxt "Content/Library/Card/Short"
+msgid "Track #%{ id } - %{ name }"
+msgstr ""
+
+#: front/src/views/admin/library/TrackDetail.vue:91
 #, fuzzy
-msgid "Track already present in one of your libraries"
-msgstr "Трек уже был представлен в одной из ваших библиотек"
+msgctxt "Content/Moderation/Title"
+msgid "Track data"
+msgstr "Название трека"
 
-#: front/src/components/library/Track.vue:85
+#: front/src/components/library/TrackDetail.vue:4
+msgctxt "Content/Track/Title/Noun"
 msgid "Track information"
 msgstr "Информация о треке"
 
-#: front/src/components/library/radios/Filter.vue:44
-msgid "Track matching filter"
-msgstr "Трек подходящий под фильтр"
-
-#: front/src/components/mixins/Translations.vue:23
-#: front/src/components/mixins/Translations.vue:24
+#: front/src/components/mixins/Translations.vue:50
+#: front/src/components/mixins/Translations.vue:51
+msgctxt "Content/*/Dropdown/Noun"
 msgid "Track name"
 msgstr "Название трека"
 
-#: front/src/views/content/libraries/FilesTable.vue:209
-#, fuzzy
-msgid "Track uploaded, but not processed by the server yet"
-msgstr "Трек загружен но ещё не обработан сервером"
+#: front/src/components/manage/library/AlbumsTable.vue:42
+#: front/src/components/manage/library/ArtistsTable.vue:42
+#: front/src/views/admin/library/AlbumDetail.vue:252
+#: front/src/views/admin/library/ArtistDetail.vue:251
+#: front/src/views/admin/library/Base.vue:14
+#: front/src/views/admin/library/LibraryDetail.vue:229
+#: front/src/views/admin/library/TracksList.vue:24
+msgctxt "*/*/*"
+msgid "Tracks"
+msgstr "Треки"
 
 #: front/src/components/instance/Stats.vue:54
-#, fuzzy
-msgid "tracks"
-msgstr "треки"
-
-#: front/src/components/library/Album.vue:81
-#: front/src/components/playlists/PlaylistModal.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:329
-#: front/src/views/admin/moderation/DomainsDetail.vue:265
+#: front/src/components/library/AlbumDetail.vue:19
+#: front/src/components/playlists/PlaylistModal.vue:47
+#: front/src/views/admin/moderation/AccountsDetail.vue:362
+#: front/src/views/admin/moderation/DomainsDetail.vue:274
 #: front/src/views/content/Base.vue:8 src/views/content/libraries/Detail.vue:8
-#: front/src/views/playlists/Detail.vue:50 src/views/radios/Detail.vue:34
+#: front/src/views/playlists/Detail.vue:51 src/views/radios/Detail.vue:34
 #, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Tracks"
 msgstr "Треки"
 
-#: front/src/components/library/Artist.vue:54
+#: front/src/components/library/ArtistDetail.vue:33
+msgctxt "Content/Artist/Title"
 msgid "Tracks by this artist"
 msgstr "Треки этого исполнителя"
 
 #: front/src/components/instance/Stats.vue:25
+msgctxt "Content/About/Paragraph/Unit"
 msgid "Tracks favorited"
 msgstr "Избранные треки"
 
 #: front/src/components/instance/Stats.vue:19
+msgctxt "Content/About/Paragraph/Unit"
 msgid "tracks listened"
 msgstr "треков прослушано"
 
-#: front/src/components/library/Track.vue:138
-#: front/src/components/manage/library/FilesTable.vue:41
-#: front/src/views/admin/moderation/AccountsDetail.vue:151
+#: front/src/components/library/radios/Filter.vue:44
+#, fuzzy
+msgctxt "Popup/Radio/Title/Noun"
+msgid "Tracks matching filter"
+msgstr "Трек подходящий под фильтр"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:180
+msgctxt "Content/Moderation/Table.Label/Noun"
+msgid "Type"
+msgstr "Тип"
+
+#: front/src/components/library/TrackDetail.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:250
+msgctxt "Content/Track/Table.Label/Noun"
 msgid "Type"
 msgstr "Тип"
 
 #: front/src/components/manage/moderation/AccountsTable.vue:44
 #: front/src/components/manage/moderation/DomainsTable.vue:42
+#, fuzzy
+msgctxt "Content/Moderation/Table.Label/Short"
 msgid "Under moderation rule"
-msgstr ""
+msgstr "Удалить радио"
 
-#: front/src/views/content/remote/Card.vue:100
-#: src/views/content/remote/Card.vue:105
+#: front/src/views/content/remote/Card.vue:104
+#: src/views/content/remote/Card.vue:109
+#, fuzzy
+msgctxt "*/Library/Button.Label/Verb"
 msgid "Unfollow"
 msgstr "Отписаться"
 
-#: front/src/views/content/remote/Card.vue:101
+#: front/src/views/content/remote/Card.vue:105
+msgctxt "Popup/Library/Title"
 msgid "Unfollow this library?"
 msgstr "Отписаться от этой библиотеки?"
 
-#: front/src/components/About.vue:15
-msgid "Unfortunately, owners of this instance did not yet take the time to complete this page."
+#: front/src/components/About.vue:17
+#, fuzzy
+msgctxt "Content/About/Paragraph"
+msgid "Unfortunately, the owners of this instance did not yet take the time to complete this page."
 msgstr "К сожалению, владельцы этого узла ещё не заполнили эту страницу."
 
+#: front/src/components/federation/FetchButton.vue:54
+#: front/src/components/federation/FetchButton.vue:55
+msgctxt "*/*/Error"
+msgid "Unknowkn error"
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:144
+msgctxt "Popup/Import/Error.Label"
+msgid "Unkwown error"
+msgstr ""
+
 #: front/src/components/Home.vue:37
-#, fuzzy
+msgctxt "Content/Home/Title"
 msgid "Unlimited music"
 msgstr "Безграничная музыка"
 
-#: front/src/components/audio/Player.vue:351
+#: front/src/components/audio/Player.vue:602
+msgctxt "Sidebar/Player/Icon.Tooltip/Verb"
 msgid "Unmute"
 msgstr ""
 
-#: front/src/components/manage/moderation/InstancePolicyCard.vue:45
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:57
-#, fuzzy
+msgctxt "Content/Moderation/Card.Button.Label/Verb"
 msgid "Update"
 msgstr "Дата загрузки"
 
+#: front/src/components/auth/ApplicationForm.vue:64
+#, fuzzy
+msgctxt "Content/Applications/Button.Label/Verb"
+msgid "Update application"
+msgstr "Обновить список воспроизведения"
+
 #: front/src/components/auth/Settings.vue:50
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update avatar"
 msgstr "Обновить аватар"
 
 #: front/src/views/content/libraries/Form.vue:25
+msgctxt "Content/Library/Button.Label/Verb"
 msgid "Update library"
 msgstr "Обновить библиотеку"
 
-#: front/src/components/manage/moderation/InstancePolicyForm.vue:3
-msgid "Update moderation rule"
-msgstr ""
-
 #: front/src/components/playlists/Form.vue:33
+msgctxt "Content/Playlist/Button.Label/Verb"
 msgid "Update playlist"
 msgstr "Обновить список воспроизведения"
 
 #: front/src/components/auth/Settings.vue:27
+msgctxt "Content/Settings/Button.Label/Verb"
 msgid "Update settings"
 msgstr "Обновить настройки"
 
 #: front/src/views/auth/PasswordResetConfirm.vue:21
-#, fuzzy
+msgctxt "Content/Signup/Button.Label"
 msgid "Update your password"
 msgstr "Обновите ваш пароль"
 
-#: front/src/views/content/libraries/Card.vue:44
+#: front/src/views/content/libraries/Card.vue:45
 #: front/src/views/content/libraries/DetailArea.vue:24
+msgctxt "Content/Library/Card.Button.Label/Verb"
 msgid "Upload"
 msgstr "Загрузить"
 
 #: front/src/components/auth/Settings.vue:45
+msgctxt "Content/Settings/Title/Verb"
 msgid "Upload a new avatar"
 msgstr "Загрузить новый аватар"
 
 #: front/src/views/content/Home.vue:6
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload audio content"
 msgstr "Загрузить аудио"
 
-#: front/src/views/content/libraries/FilesTable.vue:57
+#: front/src/views/admin/library/UploadDetail.vue:85
+#, fuzzy
+msgctxt "Content/Moderation/Title"
+msgid "Upload data"
+msgstr "Дата загрузки"
+
+#: front/src/views/content/libraries/FilesTable.vue:58
+msgctxt "*/*/*/Noun"
 msgid "Upload date"
 msgstr "Дата загрузки"
 
-#: front/src/components/library/FileUpload.vue:219
-#: front/src/components/library/FileUpload.vue:220
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:258
+msgctxt "Content/Library/Help text"
 msgid "Upload denied, ensure the file is not too big and that you have not reached your quota"
 msgstr "Загрузка отклонена, убедитсь что файл не слишком большой и вы не превысили квоту"
 
+#: front/src/components/library/ImportStatusModal.vue:8
+msgctxt "Popup/Import/Message"
+msgid "Upload is still pending and will soon be processed by the server."
+msgstr ""
+
 #: front/src/views/content/Home.vue:7
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here."
 msgstr "Загрузите музыку (mp3, ogg, flac и т.д.) из вашей личной библиотеки прямо из вашего браузера и наслаждайтесь ей здесь."
 
-#: front/src/components/library/FileUpload.vue:31
+#: front/src/components/library/FileUpload.vue:30
+msgctxt "Content/Library/Title/Verb"
 msgid "Upload new tracks"
 msgstr "Загрузить новые треки"
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:269
-#, fuzzy
+#: front/src/views/admin/moderation/AccountsDetail.vue:298
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Upload quota"
 msgstr "Квота загрузки"
 
-#: front/src/components/library/FileUpload.vue:228
+#: front/src/components/library/FileUpload.vue:267
+msgctxt "Content/Library/Help text"
 msgid "Upload timeout, please try again"
 msgstr ""
 
-#: front/src/components/library/FileUpload.vue:100
+#: front/src/components/library/ImportStatusModal.vue:14
+msgctxt "Popup/Import/Message"
+msgid "Upload was skipped because a similar one is already available in one of your libraries."
+msgstr ""
+
+#: front/src/components/library/ImportStatusModal.vue:11
+msgctxt "Popup/Import/Message"
+msgid "Upload was successfully processed by the server."
+msgstr ""
+
+#: front/src/components/library/FileUpload.vue:109
+msgctxt "Content/Library/Table"
 msgid "Uploaded"
 msgstr "Загружено"
 
 #: front/src/components/library/FileUpload.vue:5
-#, fuzzy
+msgctxt "Content/Library/Tab.Title/Short"
 msgid "Uploading"
 msgstr "Загружается"
 
-#: front/src/components/library/FileUpload.vue:103
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:112
+msgctxt "Content/Library/Table"
 msgid "Uploading…"
 msgstr "Загружается"
 
-#: front/src/components/manage/moderation/AccountsTable.vue:41
-#: front/src/components/mixins/Translations.vue:37
-#: front/src/views/admin/moderation/AccountsDetail.vue:305
-#: front/src/views/admin/moderation/DomainsDetail.vue:241
-#: front/src/components/mixins/Translations.vue:38
+#: front/src/components/manage/library/LibrariesTable.vue:52
 #, fuzzy
+msgctxt "Content/*/*/Noun"
+msgid "Uploads"
+msgstr "Загрузить"
+
+#: front/src/views/admin/library/Base.vue:20
+#: front/src/views/admin/library/UploadsList.vue:24
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Uploads"
+msgstr "Загрузить"
+
+#: front/src/components/manage/moderation/AccountsTable.vue:41
+#: front/src/components/mixins/Translations.vue:63
+#: front/src/views/admin/library/AlbumDetail.vue:242
+#: front/src/views/admin/library/ArtistDetail.vue:231
+#: front/src/views/admin/library/LibraryDetail.vue:239
+#: front/src/views/admin/library/TrackDetail.vue:294
+#: front/src/views/admin/moderation/AccountsDetail.vue:337
+#: front/src/views/admin/moderation/DomainsDetail.vue:244
+#: front/src/components/mixins/Translations.vue:64
+msgctxt "Content/Moderation/Table.Label/Noun"
 msgid "Uploads"
 msgstr "Загрузить"
 
+#: front/src/components/auth/ApplicationForm.vue:16
+msgctxt "Content/Applications/Help Text"
+msgid "Use \"urn:ietf:wg:oauth:2.0:oob\" as a redirect URI if your application is not served on the web."
+msgstr ""
+
 #: front/src/components/Footer.vue:16
+msgctxt "Footer/*/List item.Link"
 msgid "Use another instance"
 msgstr "Использовать другой узел"
 
 #: front/src/views/auth/PasswordReset.vue:12
+msgctxt "Content/Signup/Paragraph"
 msgid "Use this form to request a password reset. We will send an email to the given address with instructions to reset your password."
 msgstr "Используйте эту форму чтобы запросить сброс пароля. Мы вышлем письмо на указанный адрес с инструкциями по сбросу вашего пароля."
 
 #: front/src/components/manage/moderation/InstancePolicyForm.vue:111
+msgctxt "Content/Moderation/Help text"
 msgid "Use this setting to temporarily enable/disable the policy without completely removing it."
 msgstr ""
 
 #: front/src/components/manage/users/InvitationsTable.vue:49
+msgctxt "Content/Admin/Table"
 msgid "Used"
 msgstr "Использовано"
 
 #: front/src/views/content/libraries/Detail.vue:26
+msgctxt "Content/Library/Table.Label"
 msgid "User"
 msgstr "Пользователь"
 
 #: front/src/components/instance/Stats.vue:5
+msgctxt "Content/About/Title/Noun"
 msgid "User activity"
 msgstr "Пользовательская активность"
 
-#: front/src/components/library/Album.vue:88
-#: src/components/library/Artist.vue:60
-#: front/src/components/library/Track.vue:168
+#: front/src/components/library/AlbumDetail.vue:26
+#: front/src/components/library/ArtistDetail.vue:39
+#: front/src/components/library/TrackDetail.vue:79
+#, fuzzy
+msgctxt "Content/*/Title/Noun"
 msgid "User libraries"
 msgstr "Пользовательские библиотеки"
 
 #: front/src/components/library/Radios.vue:20
+msgctxt "Content/Radio/Title"
 msgid "User radios"
 msgstr "Пользовательские радио"
 
 #: front/src/components/auth/Signup.vue:19
 #: front/src/components/manage/users/UsersTable.vue:37
-#: front/src/components/mixins/Translations.vue:33
-#: front/src/views/admin/moderation/AccountsDetail.vue:85
-#: front/src/components/mixins/Translations.vue:34
+#: front/src/components/mixins/Translations.vue:59
+#: front/src/views/admin/moderation/AccountsDetail.vue:114
+#: front/src/components/mixins/Translations.vue:60
+msgctxt "Content/*/*"
 msgid "Username"
 msgstr "Имя пользователя"
 
 #: front/src/components/auth/Login.vue:15
+msgctxt "Content/Login/Input.Label/Noun"
 msgid "Username or email"
 msgstr "Имя пользователя или пароль"
 
 #: front/src/components/instance/Stats.vue:13
+msgctxt "Content/About/Paragraph/Unit"
 msgid "users"
 msgstr "пользователи"
 
-#: front/src/components/Sidebar.vue:91
+#: front/src/components/Sidebar.vue:102
 #: front/src/components/manage/moderation/DomainsTable.vue:39
-#: front/src/components/mixins/Translations.vue:35
+#: front/src/components/mixins/Translations.vue:61
 #: src/views/admin/Settings.vue:81 front/src/views/admin/users/Base.vue:5
-#: src/views/admin/users/UsersList.vue:3
-#: front/src/views/admin/users/UsersList.vue:21
-#: front/src/components/mixins/Translations.vue:36
+#: src/views/admin/users/UsersList.vue:21
+#: front/src/components/mixins/Translations.vue:62
+#, fuzzy
+msgctxt "*/*/*/Noun"
 msgid "Users"
 msgstr "Пользователи"
 
 #: front/src/components/Footer.vue:29
 #, fuzzy
+msgctxt "Footer/*/Title"
 msgid "Using Funkwhale"
 msgstr "О Funkwhale"
 
 #: front/src/components/Footer.vue:13
-#, fuzzy
+msgctxt "Footer/*/List item"
 msgid "Version %{version}"
 msgstr "Исходный код (%{version})"
 
 #: front/src/views/content/libraries/Quota.vue:29
 #: front/src/views/content/libraries/Quota.vue:56
 #: front/src/views/content/libraries/Quota.vue:82
+msgctxt "Content/Library/Link/Verb"
 msgid "View files"
 msgstr "Просмотреть файлы"
 
-#: front/src/components/library/Album.vue:37
-#: src/components/library/Artist.vue:35
-#: front/src/components/library/Track.vue:51
+#: front/src/components/library/AlbumBase.vue:81
+#: front/src/components/library/ArtistBase.vue:92
+#: front/src/components/library/TrackBase.vue:100
+#: front/src/views/admin/library/AlbumDetail.vue:42
+#: front/src/views/admin/library/ArtistDetail.vue:41
+#: front/src/views/admin/library/LibraryDetail.vue:34
+#: front/src/views/admin/library/LibraryDetail.vue:45
+#: front/src/views/admin/library/TrackDetail.vue:41
+#: front/src/views/admin/library/UploadDetail.vue:35
+#: front/src/views/admin/library/UploadDetail.vue:46
+#: front/src/views/admin/moderation/AccountsDetail.vue:37
+#: front/src/views/admin/moderation/AccountsDetail.vue:45
+msgctxt "Content/Moderation/Link/Verb"
+msgid "View in Django's admin"
+msgstr ""
+
+#: front/src/components/library/AlbumBase.vue:61
+#: front/src/components/library/ArtistBase.vue:72
+#: front/src/components/library/TrackBase.vue:80
 #: front/src/components/metadata/ArtistCard.vue:49
 #: front/src/components/metadata/ReleaseCard.vue:53
+#, fuzzy
+msgctxt "Content/*/*/Clickable, Verb"
 msgid "View on MusicBrainz"
 msgstr "Смотреть на MusicBrainz"
 
 #: front/src/views/content/libraries/Form.vue:18
+msgctxt "Content/Library/Dropdown.Label"
 msgid "Visibility"
 msgstr "Видимость"
 
-#: front/src/views/content/libraries/Card.vue:59
-msgid "Visibility: everyone on this instance"
-msgstr "Видимость: все на этом узле"
-
-#: front/src/views/content/libraries/Card.vue:60
-msgid "Visibility: everyone, including other instances"
-msgstr "Видимость: все, включая другие узлы"
-
-#: front/src/views/content/libraries/Card.vue:58
-msgid "Visibility: nobody except me"
-msgstr "Видимость: никто кроме меня"
+#: front/src/components/manage/library/LibrariesTable.vue:11
+#: front/src/components/manage/library/LibrariesTable.vue:51
+#: front/src/components/manage/library/UploadsTable.vue:11
+#: front/src/components/manage/library/UploadsTable.vue:63
+#: front/src/views/admin/library/LibraryDetail.vue:94
+#: front/src/views/admin/library/UploadDetail.vue:101
+#, fuzzy
+msgctxt "*/*/*"
+msgid "Visibility"
+msgstr "Видимость"
 
-#: front/src/components/library/Album.vue:67
+#: front/src/components/library/AlbumDetail.vue:4
+msgctxt "Content/Album/"
 msgid "Volume %{ number }"
 msgstr ""
 
-#: front/src/components/playlists/PlaylistModal.vue:20
-msgid "We cannot add the track to a playlist"
-msgstr "Нам не удалось добавить трек в список воспроизведения"
-
-#: front/src/components/playlists/Form.vue:14
-msgid "We cannot create the playlist"
-msgstr "Нам не удалось создать список воспроизведения"
-
-#: front/src/components/auth/Signup.vue:13
-msgid "We cannot create your account"
-msgstr "Нам не удалось создать ваш аккаунт"
-
-#: front/src/components/audio/Player.vue:64
+#: front/src/components/federation/FetchButton.vue:69
 #, fuzzy
-msgid "We cannot load this track"
-msgstr "Нам не удалось добавить трек в список воспроизведения"
+msgctxt "Popup/*/Loading.Title"
+msgid "Waiting for result…"
+msgstr "Загружаем ваше избранное..."
 
 #: front/src/components/auth/Login.vue:7
+#, fuzzy
+msgctxt "Content/Login/Error message.Title"
 msgid "We cannot log you in"
-msgstr ""
-
-#: front/src/components/auth/Settings.vue:38
-msgid "We cannot save your avatar"
-msgstr "Мы не смогли сохранить ваш аватар"
-
-#: front/src/components/auth/Settings.vue:14
-msgid "We cannot save your settings"
 msgstr "Мы не смогли сохранить ваши настройки"
 
-#: front/src/components/Home.vue:127
-msgid "We do not track you or bother you with ads"
-msgstr "Мы не отслеживаем вас и не надоедаем вам рекламой"
-
-#: front/src/components/library/Track.vue:95
+#: front/src/components/auth/ApplicationForm.vue:3
 #, fuzzy
-msgid "We don't have any copyright information for this track"
-msgstr "У нас нет уведомлений для показа!"
+msgctxt "Content/*/Error message.Title"
+msgid "We cannot save your changes"
+msgstr "Нам не удалось создать ваш аккаунт"
 
-#: front/src/components/library/Track.vue:106
-#, fuzzy
-msgid "We don't have any licensing information for this track"
-msgstr "У нас нет уведомлений для показа!"
+#: front/src/components/Home.vue:122
+msgctxt "Content/Home/List item"
+msgid "We do not track you or bother you with ads"
+msgstr "Мы не отслеживаем вас и не надоедаем вам рекламой"
 
-#: front/src/components/library/FileUpload.vue:40
-#, fuzzy
+#: front/src/components/library/FileUpload.vue:39
+msgctxt "Content/Library/Link"
 msgid "We recommend using Picard for that purpose."
 msgstr "мы рекомендуем использовать Picard для этого"
 
 #: front/src/components/Home.vue:7
+msgctxt "Content/Home/Title"
 msgid "We think listening to music should be simple."
 msgstr "Мы считаем что прослушивание музыки должно быть простым."
 
-#: front/src/components/PageNotFound.vue:10
-msgid "We're sorry, the page you asked for does not exist:"
-msgstr "Извините, страницы которую вы запрашивали не существует:"
-
-#: front/src/components/Home.vue:153
+#: front/src/components/Home.vue:148
+msgctxt "Head/Home/Title"
 msgid "Welcome"
 msgstr "Добро пожаловать"
 
 #: front/src/components/Home.vue:5
+msgctxt "Content/Home/Title/Verb"
 msgid "Welcome on Funkwhale"
 msgstr "Добро пожаловать в Funkwhale"
 
 #: front/src/components/Home.vue:24
+msgctxt "Content/Home/Title"
 msgid "Why funkwhale?"
 msgstr "Почему funkwhale?"
 
 #: front/src/components/audio/EmbedWizard.vue:13
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget height"
 msgstr ""
 
 #: front/src/components/audio/EmbedWizard.vue:6
+msgctxt "Popup/Embed/Input.Label"
 msgid "Widget width"
 msgstr ""
 
-#: front/src/components/Sidebar.vue:118
+#: front/src/components/auth/ApplicationForm.vue:155
+msgctxt "Content/OAuth Scopes/Label/Verb"
+msgid "Write"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:21
+msgctxt "Content/Auth/Label/Noun"
+msgid "Write-only"
+msgstr ""
+
+#: front/src/components/auth/ApplicationForm.vue:156
+msgctxt "Content/OAuth Scopes/Help Text"
+msgid "Write-only access to user data"
+msgstr ""
+
+#: front/src/components/Sidebar.vue:129
 #: front/src/components/manage/moderation/AccountsTable.vue:72
 #: front/src/components/manage/moderation/DomainsTable.vue:58
+msgctxt "*/*/*"
 msgid "Yes"
 msgstr "Да"
 
 #: front/src/components/auth/Logout.vue:8
+msgctxt "Content/Login/Button.Label"
 msgid "Yes, log me out!"
 msgstr ""
 
 #: front/src/views/content/libraries/Form.vue:19
-#, fuzzy
+msgctxt "Content/Library/Paragraph"
 msgid "You are able to share your library with other people, regardless of its visibility."
 msgstr "Вы сможете делиться вашей библиотекой с другими людьми независимо от её видимости."
 
-#: front/src/components/library/FileUpload.vue:33
+#: front/src/components/library/FileUpload.vue:32
+msgctxt "Content/Library/Paragraph"
 msgid "You are about to upload music to your library. Before proceeding, please ensure that:"
 msgstr "Вы собираетесь загрузить музыку в вашу библиотеку. Перед тем как продолжить, убедитесь что:"
 
+#: front/src/components/SetInstanceModal.vue:12
+msgctxt "Popup/Login/Paragraph"
+msgid "You are currently connected to <a href=\"%{ url }\" target=\"_blank\">%{ hostname }&nbsp;<i class=\"external icon\"/></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted."
+msgstr ""
+
+#: front/src/components/library/ArtistDetail.vue:6
+msgctxt "Content/Artist/Paragraph"
+msgid "You are currently hiding content related to this artist."
+msgstr ""
+
 #: front/src/components/auth/Logout.vue:7
+#, fuzzy
+msgctxt "Content/Login/Paragraph"
 msgid "You are currently logged in as %{ username }"
 msgstr "Вы вошли как %{ username }"
 
+#: front/src/components/library/FileUpload.vue:35
+msgctxt "Content/Library/List item"
+msgid "You are not uploading copyrighted content in a public library, otherwise you may be infringing the law"
+msgstr ""
+
+#: front/src/components/SetInstanceModal.vue:98
+msgctxt "*/Instance/Message"
+msgid "You are now using the Funkwhale instance at %{ url }"
+msgstr ""
+
 #: front/src/views/content/Home.vue:17
+msgctxt "Content/Library/Paragraph"
 msgid "You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner."
 msgstr "Вы можете подписаться на библиотеки других пользователей чтобы получать доступ к новой музыке. На публичные библиотеки можно подписаться сразу, в то время как подписка на приватную библиотеку требует подтверждения владельца."
 
-#: front/src/components/Home.vue:133
+#: front/src/components/Home.vue:128
+msgctxt "Content/Home/List item"
 msgid "You can invite friends and family to your instance so they can enjoy your music"
 msgstr "Вы можете пригласить друзей и семью на ваш узел чтобы они могли наслаждаться вашей музыкой"
 
+#: front/src/components/moderation/FilterModal.vue:31
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You can manage and update your filters anytime from your account settings."
+msgstr ""
+
 #: front/src/views/auth/EmailConfirm.vue:24
-#, fuzzy
+msgctxt "Content/Signup/Paragraph"
 msgid "You can now use the service without limitations."
 msgstr "Ваш адрес электронной почты был подтверждён, теперь вы можете пользоваться сервисом без ограничений."
 
 #: front/src/components/library/radios/Builder.vue:7
+msgctxt "Content/Radio/Paragraph"
 msgid "You can use this interface to build your own custom radio, which will play tracks according to your criteria."
 msgstr "Вы можете использовать этот интерфейс чтобы создать собственное радио, которое будет проигрывать треки согласно вашим критериям."
 
-#: front/src/components/auth/SubsonicTokenForm.vue:8
+#: front/src/components/auth/SubsonicTokenForm.vue:7
+msgctxt "Content/Settings/Paragraph"
 msgid "You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance."
 msgstr "Вы можете наслаждаться вашим списком воспроизведения и музыкой в режиме оффлайн, например с вашего смартфона или планшета."
 
-#: front/src/views/admin/moderation/AccountsDetail.vue:46
+#: front/src/components/auth/Settings.vue:202
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any application connected with your account."
+msgstr "У нас нет уведомлений для показа!"
+
+#: front/src/components/auth/Settings.vue:261
+#, fuzzy
+msgctxt "Content/Applications/Paragraph"
+msgid "You don't have any configured application yet."
+msgstr "У нас нет уведомлений для показа!"
+
+#: front/src/views/admin/moderation/AccountsDetail.vue:75
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this account."
-msgstr ""
+msgstr "У нас нет уведомлений для показа!"
 
 #: front/src/views/admin/moderation/DomainsDetail.vue:39
+#, fuzzy
+msgctxt "Content/Moderation/Card.Title"
 msgid "You don't have any rule in place for this domain."
+msgstr "У нас нет уведомлений для показа!"
+
+#: front/src/components/library/EditForm.vue:52
+msgctxt "Content/Library/Paragraph"
+msgid "You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval."
 msgstr ""
 
-#: front/src/components/Sidebar.vue:158
+#: front/src/components/Sidebar.vue:171
+msgctxt "Sidebar/Player/Title"
 msgid "You have a radio playing"
 msgstr "У вас проигрывается радио"
 
-#: front/src/components/audio/Player.vue:71
+#: front/src/components/audio/Player.vue:69
+msgctxt "Sidebar/Player/Error message.Paragraph"
 msgid "You may have a connectivity issue."
 msgstr ""
 
-#: front/src/App.vue:17
-msgid "You need to select an instance in order to continue"
-msgstr "Вы должны выбрать узел чтобы продолжить"
-
 #: front/src/components/auth/Settings.vue:100
+msgctxt "Popup/Settings/List item"
 msgid "You will be logged out from this session and have to log in with the new one"
 msgstr ""
 
+#: front/src/components/auth/Authorize.vue:51
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be redirected to <strong>%{ url }</strong>"
+msgstr ""
+
+#: front/src/components/auth/Authorize.vue:49
+msgctxt "Content/Auth/Paragraph"
+msgid "You will be shown a code to copy-paste in the application."
+msgstr ""
+
 #: front/src/components/auth/Settings.vue:71
+msgctxt "Content/Settings/Paragraph"
 msgid "You will have to update your password on your clients that use this password."
 msgstr "Вам потребуется обновить пароль на своих клиентах чтобы использовать его."
 
-#: front/src/components/favorites/List.vue:112
+#: front/src/components/moderation/FilterModal.vue:20
+msgctxt "Popup/Moderation/Paragraph"
+msgid "You will not see tracks, albums and user activity linked to this artist anymore:"
+msgstr ""
+
+#: front/src/components/auth/Signup.vue:13
+#, fuzzy
+msgctxt "Content/Signup/Form/Paragraph"
+msgid "Your account cannot be created."
+msgstr "Список воспроизведения создан"
+
+#: front/src/components/auth/Settings.vue:215
+#, fuzzy
+msgctxt "Content/Settings/Title/Noun"
+msgid "Your applications"
+msgstr "Ваши уведомления"
+
+#: front/src/components/auth/Settings.vue:38
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your avatar cannot be saved"
+msgstr ""
+
+#: front/src/components/library/EditForm.vue:3
+msgctxt "Content/Library/Paragraph"
+msgid "Your edit was successfully submitted."
+msgstr ""
+
+#: front/src/components/favorites/List.vue:116
+msgctxt "Head/Favorites/Title"
 msgid "Your Favorites"
 msgstr "Ваше избранное"
 
-#: front/src/components/Home.vue:114
+#: front/src/components/Home.vue:109
+msgctxt "Content/Home/Title"
 msgid "Your music, your way"
 msgstr ""
 
-#: front/src/views/Notifications.vue:7
+#: front/src/views/Notifications.vue:4
+msgctxt "Content/Notifications/Title"
 msgid "Your notifications"
 msgstr "Ваши уведомления"
 
+#: front/src/components/auth/Settings.vue:76
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your password cannot be changed"
+msgstr ""
+
 #: front/src/views/auth/PasswordResetConfirm.vue:29
+msgctxt "Content/Signup/Card.Paragraph"
 msgid "Your password has been updated successfully."
 msgstr "Ваш пароль был успешно обновлён."
 
+#: front/src/components/auth/Settings.vue:14
+#, fuzzy
+msgctxt "Content/Settings/Error message.Title"
+msgid "Your settings can't be updateds"
+msgstr "Настройки обновлены"
+
 #: front/src/components/auth/Settings.vue:101
+msgctxt "Popup/Settings/List item"
 msgid "Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password"
 msgstr "Ваш пароль Subsonic будет изменён на новый случайный, что приведёт к отключению всех устройств, которые использовали старый пароль Subsonic"
+
+#: front/src/edits.js:47
+#, fuzzy
+msgctxt "*/*/*/Short, Noun"
+msgid "Position"
+msgstr "Описание"
+
+#: front/src/edits.js:54
+#, fuzzy
+msgctxt "Content/Track/*/Noun"
+msgid "Copyright"
+msgstr "Копировать"
+
+#: front/src/components/library/AlbumBase.vue:183
+#, fuzzy
+msgctxt "Content/Album/Header.Title"
+msgid "Album containing %{ count } track, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgid_plural "Album containing %{ count } tracks, by <a class=\"internal\" href=\"%{ artistUrl }\">%{ artist }</a>"
+msgstr[0] "Альбом содержит %{ count } трек от %{ artist }"
+msgstr[1] "Альбом содержит %{ count } трека от %{ artist }"
+msgstr[2] "Альбом содержит %{ count } треков от %{ artist }"
+
+#: front/src/components/audio/PlayButton.vue:220
+#, fuzzy
+msgctxt "*/Queue/Message"
+msgid "%{ count } track was added to your queue"
+msgid_plural "%{ count } tracks were added to your queue"
+msgstr[0] "%{ count } трек добавлен в вашу очередь"
+msgstr[1] "%{ count } трека добавлено в вашу очередь"
+msgstr[2] "%{ count } треков добавлено в вашу очередь"
diff --git a/front/package.json b/front/package.json
index adeb1fb19d6bc64a4bee8b1f099245fc285875db..22b5f3bb5ed35aebd5cb562c5f752ec2a65f8533 100644
--- a/front/package.json
+++ b/front/package.json
@@ -13,6 +13,7 @@
   "dependencies": {
     "axios": "^0.18.0",
     "dateformat": "^3.0.3",
+    "diff": "^4.0.1",
     "django-channels": "^1.1.6",
     "howler": "^2.0.14",
     "js-logger": "^1.4.1",
diff --git a/front/public/favicon.png b/front/public/favicon.png
index 089442fab7cb4e68cec9de87d421b64495e3263a..df1cb56f0ef94c6112fa7a368de8d74ba1041225 100644
Binary files a/front/public/favicon.png and b/front/public/favicon.png differ
diff --git a/front/scripts/contextualize.py b/front/scripts/contextualize.py
new file mode 100644
index 0000000000000000000000000000000000000000..edff72145a380464f02b022c20ec0bd34dc33256
--- /dev/null
+++ b/front/scripts/contextualize.py
@@ -0,0 +1,82 @@
+import argparse
+import polib
+
+
+def get_missing(entries):
+    """
+    Return a list of entries with:
+    - a msgcontext
+    - an empty msgstr
+    """
+    for e in entries:
+        if e.translated():
+            continue
+        yield e
+    return []
+
+
+def match(entries, other_entries):
+    """
+    Given two list of po entries, will return a list of 2-tuples with
+    match from the second list
+    """
+
+    by_id = {}
+    for e in other_entries:
+        is_translated = bool(e.msgstr)
+        if not is_translated:
+            continue
+        by_id[e.msgid] = e
+
+    matches = []
+    for e in entries:
+        matches.append((e, by_id.get(e.msgid)))
+
+    return matches
+
+
+def update(new, old):
+    """
+    Update a new po entry with translation from the first one (removing fuzzy if needed)
+    """
+    new.msgstr = old.msgstr
+    new.flags = [f for f in new.flags if f != "fuzzy"]
+
+
+def contextualize(old_po, new_po, edit=False):
+    old = polib.pofile(old_po)
+    new = polib.pofile(new_po)
+    missing = list(get_missing(new))
+    print(
+        "Found {} entries with contexts and missing translations ({} total)".format(
+            len(missing), len(new)
+        )
+    )
+    matches = match(missing, old)
+    found = [m for m in matches if m[1] is not None]
+    print("Found {} matching entries".format(len(found)))
+    if edit:
+        print("Applying changes")
+        for matched, matching in found:
+            update(matched, matching)
+        new.save()
+    else:
+        print("--no-dry-run not provided, not applying change")
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(
+        description="""
+        Given two .po file paths, it will populate empty contextualized messages
+        in the second one with matching message IDs from the first one, if any.
+
+        This is especially helpful when you add some contexts on existing translated strings
+        but don't want to have those being retranslated.
+    """
+    )
+    parser.add_argument("old_po", help="Path of the po file to use as a source")
+    parser.add_argument("new_po", help="Path of the po file to populate")
+    parser.add_argument("--no-dry-run", action="store_true")
+    args = parser.parse_args()
+
+    contextualize(old_po=args.old_po, new_po=args.new_po, edit=args.no_dry_run)
diff --git a/front/scripts/i18n-populate-contextualized-strings.sh b/front/scripts/i18n-populate-contextualized-strings.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fa47eb4d6f4b2757bbf608b317a0ecba25f1dd63
--- /dev/null
+++ b/front/scripts/i18n-populate-contextualized-strings.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -eu
+
+# Typical use:
+# cp -r locales old_locales
+# ./scripts/i18n-extract.sh
+# ./scripts/i18n-populate-contextualized-strings.sh old_locales locales
+# Then review/commit the changes
+
+old_locales_dir=$1
+new_locales_dir=$2
+
+locales=$(tail -n +2 src/locales.js | sed -e 's/export default //' | jq '.locales[].code' | xargs echo)
+
+# Generate .po files for each available language.
+echo $locales
+for lang in $locales; do
+    echo "Fixing contexts for $lang…"
+    old_po_file=$old_locales_dir/$lang/LC_MESSAGES/app.po
+    new_po_file=$new_locales_dir/$lang/LC_MESSAGES/app.po
+    python3 ./scripts/contextualize.py $old_po_file $new_po_file --no-dry-run
+done;
diff --git a/front/src/App.vue b/front/src/App.vue
index 02383e6cfbf41e17e45c5382f57d75e764eadc7f..5711466c5bb9cd29eaec058174a9fe7a4c5376b9 100644
--- a/front/src/App.vue
+++ b/front/src/App.vue
@@ -1,5 +1,5 @@
 <template>
-  <div id="app">
+  <div id="app" :key="String($store.state.instance.instanceUrl)">
     <!-- here, we display custom stylesheets, if any -->
     <link
       v-for="url in customStylesheets"
@@ -8,42 +8,19 @@
       :href="url"
       :key="url"
     >
-    <div class="ui main text container instance-chooser" v-if="!$store.state.instance.instanceUrl">
-      <div class="ui padded segment">
-        <h1 class="ui header">
-          <translate>Choose your instance</translate>
-        </h1>
-        <form class="ui form" @submit.prevent="$store.dispatch('instance/setUrl', instanceUrl)">
-          <p>
-            <translate>You need to select an instance in order to continue</translate>
-          </p>
-          <div class="ui action input">
-            <input type="text" v-model="instanceUrl">
-            <button type="submit" class="ui button">
-              <translate>Submit</translate>
-            </button>
-          </div>
-          <p>
-            <translate>Suggested choices</translate>
-          </p>
-          <div class="ui bulleted list">
-            <div class="ui item" v-for="url in suggestedInstances">
-              <a @click="instanceUrl = url; $store.dispatch('instance/setUrl', url)">{{ url }}</a>
-            </div>
-          </div>
-        </form>
-      </div>
-    </div>
-    <template v-else>
+    <template>
       <sidebar></sidebar>
+      <set-instance-modal @update:show="showSetInstanceModal = $event" :show="showSetInstanceModal"></set-instance-modal>
       <service-messages v-if="messages.length > 0"/>
       <router-view :key="$route.fullPath"></router-view>
       <div class="ui fitted divider"></div>
       <app-footer
         :version="version"
         @show:shortcuts-modal="showShortcutsModal = !showShortcutsModal"
+        @show:set-instance-modal="showSetInstanceModal = !showSetInstanceModal"
       ></app-footer>
       <playlist-modal v-if="$store.state.auth.authenticated"></playlist-modal>
+      <filter-modal v-if="$store.state.auth.authenticated"></filter-modal>
       <shortcuts-modal @update:show="showShortcutsModal = $event" :show="showShortcutsModal"></shortcuts-modal>
       <GlobalEvents @keydown.h.exact="showShortcutsModal = !showShortcutsModal"/>
     </template>
@@ -54,7 +31,7 @@
 import Vue from 'vue'
 import axios from 'axios'
 import _ from '@/lodash'
-import {mapState} from 'vuex'
+import {mapState, mapGetters} from 'vuex'
 import { WebSocketBridge } from 'django-channels'
 import GlobalEvents from '@/components/utils/global-events'
 import Sidebar from '@/components/Sidebar'
@@ -63,17 +40,21 @@ import ServiceMessages from '@/components/ServiceMessages'
 import moment from  'moment'
 import locales from './locales'
 import PlaylistModal from '@/components/playlists/PlaylistModal'
+import FilterModal from '@/components/moderation/FilterModal'
 import ShortcutsModal from '@/components/ShortcutsModal'
+import SetInstanceModal from '@/components/SetInstanceModal'
 
 export default {
   name: 'app',
   components: {
     Sidebar,
     AppFooter,
+    FilterModal,
     PlaylistModal,
     ShortcutsModal,
     GlobalEvents,
-    ServiceMessages
+    ServiceMessages,
+    SetInstanceModal,
   },
   data () {
     return {
@@ -81,6 +62,7 @@ export default {
       nodeinfo: null,
       instanceUrl: null,
       showShortcutsModal: false,
+      showSetInstanceModal: false,
     }
   },
   created () {
@@ -110,30 +92,57 @@ export default {
       id: 'sidebarCount',
       handler: this.incrementNotificationCountInSidebar
     })
+    this.$store.commit('ui/addWebsocketEventHandler', {
+      eventName: 'mutation.created',
+      id: 'sidebarReviewEditCount',
+      handler: this.incrementReviewEditCountInSidebar
+    })
+    this.$store.commit('ui/addWebsocketEventHandler', {
+      eventName: 'mutation.updated',
+      id: 'sidebarReviewEditCount',
+      handler: this.incrementReviewEditCountInSidebar
+    })
+  },
+  mounted () {
+    let self = this
+
+    // slight hack to allow use to have internal links in <translate> tags
+    // while preserving router behaviour
+    document.documentElement.addEventListener('click', function (event) {
+      if (!event.target.matches('a.internal')) return;
+      self.$router.push(event.target.getAttribute('href'))
+      event.preventDefault();
+    }, false);
+
   },
   destroyed () {
     this.$store.commit('ui/removeWebsocketEventHandler', {
       eventName: 'inbox.item_added',
       id: 'sidebarCount',
     })
+    this.$store.commit('ui/removeWebsocketEventHandler', {
+      eventName: 'mutation.created',
+      id: 'sidebarReviewEditCount',
+    })
+    this.$store.commit('ui/removeWebsocketEventHandler', {
+      eventName: 'mutation.updated',
+      id: 'sidebarReviewEditCount',
+    })
     this.disconnect()
   },
   methods: {
     incrementNotificationCountInSidebar (event) {
       this.$store.commit('ui/incrementNotifications', {type: 'inbox', count: 1})
     },
+    incrementReviewEditCountInSidebar (event) {
+      this.$store.commit('ui/incrementNotifications', {type: 'pendingReviewEdits', value: event.pending_review_count})
+    },
     fetchNodeInfo () {
       let self = this
       axios.get('instance/nodeinfo/2.0/').then(response => {
         self.nodeinfo = response.data
       })
     },
-    switchInstance () {
-      let confirm = window.confirm(this.$gettext('This will erase your local data and disconnect you, do you want to continue?'))
-      if (confirm) {
-        this.$store.commit('instance/instanceUrl', null)
-      }
-    },
     autodetectLanguage () {
       let userLanguage = navigator.language || navigator.userLanguage
       let available = locales.locales.map(e => { return e.code })
@@ -184,14 +193,37 @@ export default {
         console.log('Connected to WebSocket')
       })
     },
+    getTrackInformationText(track) {
+      const trackTitle = track.title
+      const artistName = (
+        (track.artist) ? track.artist.name : track.album.artist.name)
+      const text = `♫ ${trackTitle} – ${artistName} ♫`
+      return text
+    },
+    updateDocumentTitle() {
+      let parts = []
+      const currentTrackPart = (
+        (this.currentTrack) ? this.getTrackInformationText(this.currentTrack)
+        : null)
+      if (currentTrackPart) {
+        parts.push(currentTrackPart)
+      }
+      if (this.$store.state.ui.pageTitle) {
+        parts.push(this.$store.state.ui.pageTitle)
+      }
+      parts.push(this.$store.state.instance.settings.instance.name.value || 'Funkwhale')
+      document.title = parts.join(' – ')
+    },
   },
   computed: {
     ...mapState({
       messages: state => state.ui.messages
     }),
+    ...mapGetters({
+      currentTrack: 'queue/currentTrack'
+    }),
     suggestedInstances () {
       let instances = this.$store.state.instance.knownInstances.slice(0)
-      console.log('instance', instances)
       if (this.$store.state.instance.frontSettings.defaultServerUrl) {
         let serverUrl = this.$store.state.instance.frontSettings.defaultServerUrl
         if (!serverUrl.endsWith('/')) {
@@ -200,7 +232,6 @@ export default {
         instances.push(serverUrl)
       }
       instances.push(this.$store.getters['instance/defaultUrl'](), 'https://demo.funkwhale.audio/')
-      console.log('HELLO', instances)
       return _.uniq(instances.filter((e) => {return e}))
     },
     version () {
@@ -254,9 +285,20 @@ export default {
             console.log('No momentjs locale available for', shortLocale)
           })
         })
-        console.log(moment.locales())
       }
-    }
+    },
+    'currentTrack': {
+      immediate: true,
+      handler(newValue) {
+        this.updateDocumentTitle()
+      },
+    },
+    '$store.state.ui.pageTitle': {
+      immediate: true,
+      handler(newValue) {
+        this.updateDocumentTitle()
+      },
+    },
   }
 }
 </script>
diff --git a/front/src/EmbedFrame.vue b/front/src/EmbedFrame.vue
index 7987b054a44213976944251afe7c152e7043ad82..9c677e56e3a52ac1845460e86657c04fda60e873 100644
--- a/front/src/EmbedFrame.vue
+++ b/front/src/EmbedFrame.vue
@@ -139,7 +139,7 @@ export default {
   data () {
     return {
       time,
-      supportedTypes: ['track', 'album'],
+      supportedTypes: ['track', 'album', 'artist'],
       baseUrl: '',
       error: null,
       type: null,
@@ -158,6 +158,7 @@ export default {
   },
   created () {
     let params = getURLParams()
+    this.baseUrl = params.b || ''
     this.type = params.type
     if (this.supportedTypes.indexOf(this.type) === -1) {
       this.error = 'invalid_type'
@@ -229,7 +230,10 @@ export default {
         this.fetchTrack(id)
       }
       if (type === 'album') {
-        this.fetchTracks({album: id, playable: true})
+        this.fetchTracks({album: id, playable: true, ordering: ",disc_number,position"})
+      }
+      if (type === 'artist') {
+        this.fetchTracks({artist: id, playable: true, ordering: "-release_date,disc_number,position"})
       }
     },
     play (index) {
@@ -353,7 +357,11 @@ export default {
       this.$nextTick(() => {
         self.bindEvents()
         if (self.tracks.length > 0) {
-          var topPos = document.getElementById(`queue-item-${v}`).offsetTop;
+          let el = document.getElementById(`queue-item-${v}`);
+          if (!el) {
+            return
+          }
+          var topPos = el.offsetTop;
           document.getElementById('queue').scrollTop = topPos-10;
         }
       })
@@ -395,6 +403,7 @@ a:hover {
 }
 section.controls {
   display: flex;
+  width: 100%;
 }
 .cover {
   max-width: 120px;
@@ -405,6 +414,9 @@ section.controls {
   flex: 1;
   align-self: flex-end;
 }
+.player .plyr {
+  min-width: inherit;
+}
 article .content {
   flex: 1;
   display: flex;
@@ -484,10 +496,16 @@ section .plyr--audio .plyr__controls {
 @media screen and (max-width: 460px) {
   article,
   article .content {
+    position: relative;
     display: block;
   }
+  .content header {
+    padding-right: 80px;
+  }
   .cover.main {
-    float: right;
+    position: absolute;
+    right: 0;
+    top: 0;
     img {
       height: 60px;
       width: 60px;
@@ -496,12 +514,67 @@ section .plyr--audio .plyr__controls {
 }
 
 @media screen and (max-width: 320px) {
+  .content header {
+    font-size: 14px;
+  }
+  .content h3 {
+    font-size: 15px;
+  }
   .logo-wrapper,
   .position-cell {
     display: none;
   }
+  .plyr__volume {
+    min-width: 70px;
+  }
+  .queue .artist {
+    display: none;
+  }
+}
+
+@media screen and (max-width: 200px) {
+  .content header {
+    padding-right: 1em;
+    font-size: 13px;
+  }
+  .content h3 {
+    font-size: 14px;
+  }
+  .cover.main {
+    display: none;
+  }
+  .plyr__progress {
+    display: none;
+  }
+  .controls .plyr__control,
+  .player .plyr__control {
+    padding: 3px;
+  }
+  .queue td:last-child {
+    display: none;
+  }
+}
+
+@media screen and (max-width: 170px) {
+  .plyr__volume {
+    min-width: inherit;
+  }
 }
 
+@media screen and (max-height: 180px) {
+  .queue-wrapper {
+    display: none;
+  }
+  article .content {
+    display: flex;
+    align-items: flex-start;
+    width: 100%;
+    height: 100vh;
+  }
+  article .content header {
+    flex-grow: 1;
+  }
+}
 // themes
 
 .dark {
diff --git a/front/src/assets/logo/logo-full-500.png b/front/src/assets/logo/logo-full-500.png
index 952f3803326c30ceb84c54913203015efc7fddb9..b9d5b395feb0668f9cf1b1d7d0915d38768f78c9 100644
Binary files a/front/src/assets/logo/logo-full-500.png and b/front/src/assets/logo/logo-full-500.png differ
diff --git a/front/src/assets/logo/logo-full.png b/front/src/assets/logo/logo-full.png
deleted file mode 100644
index 725dcc8acfcc2165751caf98b6fee964832b4677..0000000000000000000000000000000000000000
Binary files a/front/src/assets/logo/logo-full.png and /dev/null differ
diff --git a/front/src/assets/logo/logo-with-text.svg b/front/src/assets/logo/logo-with-text.svg
deleted file mode 100644
index 46ee3b3c628177e221fd81fe6376e3d4f1ae8cb6..0000000000000000000000000000000000000000
--- a/front/src/assets/logo/logo-with-text.svg
+++ /dev/null
@@ -1,34 +0,0 @@
-<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 283.5 44.7" enable-background="new 0 0 283.5 44.7" xml:space="preserve">
-<g>
-	<path fill="#222222" d="M3.9,16.7c0-9,3.5-12.5,14-12.5c2.2,0,5,0.2,6.5,0.5c0.8,0.2,1.5,0.8,1.5,1.5v2.7c0,0.8-0.6,1.5-1.5,1.5
-		h-0.9c-1.1,0-2-0.4-3.4-0.4c-6.5,0-7.8,1.3-7.8,6.7v0.4h8.9c0.8,0,1.5,0.6,1.5,1.5v2.9c0,0.9-0.6,1.5-1.5,1.5h-8.9v15.2
-		c0,0.8-0.6,1.5-1.5,1.5H5.4c-0.8,0-1.5-0.7-1.5-1.5V16.7z"/>
-	<path fill="#222222" d="M36.4,28.4c0,4.1,1.9,5.8,4.7,5.8c2.4,0,4.7-1.7,6.5-3.5V14.4c0-0.8,0.7-1.5,1.5-1.5h5.5
-		c0.8,0,1.5,0.7,1.5,1.5v23.8c0,0.8-0.6,1.5-1.5,1.5h-5.5c-0.8,0-1.5-0.7-1.5-1.5v-1.6c-2.3,2-4.8,3.6-8.5,3.6
-		c-6.5,0-11.1-3.4-11.1-11.7v-14c0-0.8,0.6-1.5,1.5-1.5h5.5c0.8,0,1.5,0.7,1.5,1.5V28.4z"/>
-	<path fill="#222222" d="M81.7,24.2c0-4.1-1.9-5.8-4.7-5.8c-2.4,0-4.8,1.7-6.6,3.5v16.4c0,0.8-0.6,1.5-1.5,1.5h-5.5
-		c-0.9,0-1.5-0.7-1.5-1.5V14.4c0-0.8,0.6-1.5,1.5-1.5H69c0.8,0,1.5,0.7,1.5,1.5V16c2.3-2,4.8-3.6,8.6-3.6c6.5,0,11.1,3.4,11.1,11.7
-		v14c0,0.8-0.6,1.5-1.5,1.5h-5.5c-0.8,0-1.5-0.7-1.5-1.5V24.2z"/>
-	<path fill="#222222" d="M104.5,23.5c2.9,0,4.8-1.2,5.8-3.3l2.4-5c0.6-1.4,2.1-2.3,3.5-2.3h4.6c1.3,0,1.5,1,0.8,2.3l-3.2,6.7
-		c-1,2.2-3,3.9-5.2,4.4c2,0.6,3.7,2,5.2,4.4l4.2,6.7c0.8,1.3,0.4,2.3-0.8,2.3h-4.6c-1.6,0-2.9-1-3.7-2.3l-3.1-5
-		c-1.3-2.2-3.6-3.2-5.8-3.2v9.1c0,0.8-0.6,1.5-1.5,1.5h-5.5c-0.8,0-1.5-0.7-1.5-1.5v-32c0-0.8,0.6-1.5,1.5-1.5h5.5
-		c0.8,0,1.5,0.7,1.5,1.5V23.5z"/>
-	<path fill="#222222" d="M148.2,12.9c1.4,0,2.4,0.8,2.8,2.1l4,13.2l4-13.2c0.4-1.4,1.8-2.1,3.3-2.1h4.5c1.2,0,1.4,0.9,1,2.1
-		l-7.4,22.5c-0.4,1.3-1.8,2.1-3.1,2.1h-3.5c-1.2,0-2.7-0.8-3.1-2.1L146,23l-4.7,14.6c-0.4,1.3-1.9,2.1-3.1,2.1h-3.5
-		c-1.3,0-2.6-0.8-3.1-2.1l-7.4-22.5c-0.4-1.2-0.1-2.1,1-2.1h4.5c1.5,0,2.8,0.8,3.3,2.1l4,13.2l4-13.2c0.4-1.3,1.4-2.1,2.8-2.1H148.2
-		z"/>
-	<path fill="#222222" d="M191.1,24.2c0-4.1-1.9-5.8-4.6-5.8c-2.4,0-4.8,1.7-6.6,3.5v16.4c0,0.8-0.6,1.5-1.5,1.5h-5.5
-		c-0.8,0-1.5-0.7-1.5-1.5v-32c0-0.8,0.7-1.5,1.5-1.5h5.5c0.8,0,1.5,0.7,1.5,1.5V16c2.3-2,4.8-3.6,8.6-3.6c6.5,0,11.1,3.4,11.1,11.7
-		v14c0,0.8-0.7,1.5-1.5,1.5h-5.5c-0.8,0-1.5-0.7-1.5-1.5V24.2z"/>
-	<path fill="#222222" d="M213.9,19.6c-0.6,0.8-1.6,1.3-2.8,1.3h-3.6c-0.8,0-1.5-0.6-1.5-1.5c0-5.2,5.2-7,13.3-7
-		c7.2,0,12.9,3,12.9,10.6v15.1c0,0.8-0.7,1.5-1.5,1.5h-4.7c-0.8,0-1.5-0.7-1.5-1.5v-0.8c-2.3,1.6-5,2.8-8.9,2.8
-		c-6.5,0-11.5-2.9-11.5-8.6s5-8.5,11.5-8.5h8.1c0-3.9-1.6-5.1-5-5.1C216.6,18,214.7,18.6,213.9,19.6z M223.7,32.4v-3.8h-7.5
-		c-2.4,0-3.7,1.3-3.7,3c0,1.7,1.3,3,4,3C219.4,34.6,221.9,33.5,223.7,32.4z"/>
-	<path fill="#222222" d="M239.6,39.7c-0.8,0-1.5-0.7-1.5-1.5v-32c0-0.8,0.7-1.5,1.5-1.5h5.5c0.8,0,1.5,0.7,1.5,1.5v32
-		c0,0.8-0.6,1.5-1.5,1.5H239.6z"/>
-	<path fill="#222222" d="M259.6,28.9c0.3,4,2.1,5.7,6.2,5.7c2.1,0,4-0.6,4.8-1.6c0.7-0.8,1.6-1.3,2.8-1.3h3.6c0.8,0,1.5,0.7,1.5,1.5
-		c0,5.2-5.3,7-13.3,7c-8.9,0-14.3-4.8-14.3-13.8c0-9,5.4-13.9,14.3-13.9c8.9,0,14.2,4.8,14.2,13.6v1.4c0,0.8-0.6,1.5-1.5,1.5H259.6z
-		 M259.6,23.7h11.4c-0.2-3.7-2-5.7-5.7-5.7C261.7,18,259.8,20,259.6,23.7z"/>
-</g>
-</svg>
diff --git a/front/src/assets/logo/logo.png b/front/src/assets/logo/logo.png
index 7cf56217190077265543b6d20d8c44115122241e..409e172e90deccd8a285c5f77cbce696b3eda7a1 100644
Binary files a/front/src/assets/logo/logo.png and b/front/src/assets/logo/logo.png differ
diff --git a/front/src/assets/logo/logo.svg b/front/src/assets/logo/logo.svg
index 5909fcc98b73f5b6d087aeb692c633e096918010..fe3141b68eb3a163917a98a3f5002cd4da759067 100644
--- a/front/src/assets/logo/logo.svg
+++ b/front/src/assets/logo/logo.svg
@@ -1,19 +1,91 @@
-<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
-<g>
-	<g>
-		<path fill="#4082B4" d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
-			c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"/>
-		<path fill="#4082B4" d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
-			c0,17.1-13.9,31-31,31c-17.1,0-31-13.9-31-31c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C29.6,87.6,48.1,106.1,70.9,106.1z"
-			/>
-		<path fill="#4082B4" d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
-			c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,33.8,27.5,61.3,61.3,61.3c33.8,0,61.3-27.5,61.3-61.3
-			C132.2,64.3,131.7,63.8,131.1,63.8z"/>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Calque_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 252.65424 228.43591"
+   xml:space="preserve"
+   sodipodi:docname="logo-transparent.svg"
+   width="252.65424"
+   height="228.43591"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
+   id="metadata25"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs23" /><sodipodi:namedview
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1920"
+   inkscape:window-height="1043"
+   id="namedview21"
+   showgrid="true"
+   inkscape:zoom="1.84375"
+   inkscape:cx="210.72257"
+   inkscape:cy="88.813847"
+   inkscape:window-x="0"
+   inkscape:window-y="0"
+   inkscape:window-maximized="1"
+   inkscape:current-layer="Calque_1"><inkscape:grid
+     type="xygrid"
+     id="grid4535"
+     originx="-1.1305091"
+     originy="-14.869552" /></sodipodi:namedview>
+<style
+   type="text/css"
+   id="style2">
+	.st0{fill:#FFFFFF;}
+	.st1{fill:#009FE3;}
+	.st2{fill:#3C3C3B;}
+</style>
+
+<g
+   id="g18"
+   transform="matrix(1.3627521,0,0,1.3627521,-48.105149,-68.371499)">
+	<g
+   id="g16">
+		<g
+   id="g12">
+			<path
+   class="st1"
+   d="m 128,157.1 c 17.7,0 32.1,-14.4 32.1,-32.1 0,-0.9 -0.8,-1.7 -1.7,-1.7 h -12.1 c -0.9,0 -1.7,0.8 -1.7,1.7 0,9.1 -7.4,16.6 -16.6,16.6 -9.1,0 -16.6,-7.4 -16.6,-16.6 0,-0.9 -0.8,-1.7 -1.7,-1.7 H 97.6 c -0.9,0 -1.7,0.8 -1.7,1.7 0,17.8 14.4,32.1 32.1,32.1 z"
+   id="path6"
+   inkscape:connector-curvature="0"
+   style="fill:#009fe3" />
+			<path
+   class="st1"
+   d="m 128,187.4 c 34.3,0 62.3,-28 62.3,-62.3 0,-0.9 -0.8,-1.7 -1.7,-1.7 h -12.1 c -0.9,0 -1.7,0.8 -1.7,1.7 0,25.9 -21,46.9 -46.9,46.9 C 102,172 81,151 81,125.1 c 0,-0.9 -0.8,-1.7 -1.7,-1.7 H 67.4 c -0.9,0 -1.7,0.8 -1.7,1.7 -0.2,34.3 27.8,62.3 62.3,62.3 z"
+   id="path8"
+   inkscape:connector-curvature="0"
+   style="fill:#009fe3" />
+			<path
+   class="st1"
+   d="m 219,123.4 h -12.1 c -0.9,0 -1.7,0.8 -1.7,1.7 0,42.6 -34.8,77.3 -77.3,77.3 -42.6,0 -77.3,-34.6 -77.3,-77.3 0,-0.9 -0.8,-1.7 -1.7,-1.7 H 37 c -0.9,0 -1.7,0.8 -1.7,1.7 0,51.1 41.6,92.7 92.7,92.7 51.1,0 92.7,-41.6 92.7,-92.7 0,-0.9 -0.8,-1.7 -1.7,-1.7 z"
+   id="path10"
+   inkscape:connector-curvature="0"
+   style="fill:#009fe3" />
+		</g>
+		<path
+   class="st2"
+   d="m 86.3,83.3 c 6.2,3.2 12.9,3.8 18.9,7.3 3.9,2.3 6.4,4.8 8.8,8.6 3.8,5.7 3.6,12.9 3.6,12.9 l 0.5,7.9 c 0,0 3,7.9 9.7,7.9 7.1,0 9.7,-7.9 9.7,-7.9 l 0.5,-7.9 c 0,0 -0.2,-7.1 3.6,-12.9 2.4,-3.8 4.8,-6.5 8.8,-8.6 6,-3.5 12.7,-4.1 18.9,-7.3 6.2,-3.2 12.2,-7.3 16.3,-13 4.1,-5.7 6,-13.3 3.8,-20 -11.8,-0.6 -25.4,0.8 -35.8,6.4 -14.5,7.7 -23.3,5 -25.9,16.5 h -0.2 c -2.6,-11.6 -11.3,-8.8 -25.9,-16.5 -10.4,-5.6 -24,-7 -35.8,-6.4 -2.3,6.7 -0.3,14.2 3.8,20 4.4,5.8 10.5,9.9 16.7,13 z"
+   id="path14"
+   inkscape:connector-curvature="0"
+   style="fill:#3c3c3b" />
 	</g>
-	<path fill="#222222" d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
-		c0,0,2,5.2,6.4,5.2c4.7,0,6.4-5.2,6.4-5.2l0.3-5.2c0,0-0.1-4.7,2.4-8.5c1.6-2.5,3.2-4.3,5.8-5.7c4-2.3,8.4-2.7,12.5-4.8
-		c4.1-2.1,8.1-4.8,10.8-8.6c2.7-3.8,4-8.8,2.5-13.2c-7.8-0.4-16.8,0.5-23.7,4.2c-9.6,5.1-15.4,3.3-17.1,10.9h-0.1
-		c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"/>
 </g>
-</svg>
+</svg>
\ No newline at end of file
diff --git a/front/src/assets/logo/logos.png b/front/src/assets/logo/logos.png
deleted file mode 100644
index d73f4c36bb0cea8f8dd89e8696f9abd746fac518..0000000000000000000000000000000000000000
Binary files a/front/src/assets/logo/logos.png and /dev/null differ
diff --git a/front/src/assets/logo/text.svg b/front/src/assets/logo/text.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b09a620def51a6c12a052b078c575cfcce4317aa
--- /dev/null
+++ b/front/src/assets/logo/text.svg
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="271.66678mm"
+   height="53.491325mm"
+   viewBox="0 0 271.66678 53.491325"
+   version="1.1"
+   id="svg4600"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="with-text.svg">
+  <defs
+     id="defs4594">
+	
+	
+	
+	
+	
+	
+	
+	
+	
+</defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.7"
+     inkscape:cx="392.13629"
+     inkscape:cy="-23.988564"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1043"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata4597">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(34.652951,-109.48195)">
+    <g
+       id="g5240">
+      <g
+         id="g18"
+         transform="matrix(0.31910664,0,0,0.31910664,-45.917415,93.471844)">
+	<g
+   id="g16">
+		<g
+   id="g12">
+			<path
+   class="st1"
+   d="m 128,157.1 c 17.7,0 32.1,-14.4 32.1,-32.1 0,-0.9 -0.8,-1.7 -1.7,-1.7 h -12.1 c -0.9,0 -1.7,0.8 -1.7,1.7 0,9.1 -7.4,16.6 -16.6,16.6 -9.1,0 -16.6,-7.4 -16.6,-16.6 0,-0.9 -0.8,-1.7 -1.7,-1.7 H 97.6 c -0.9,0 -1.7,0.8 -1.7,1.7 0,17.8 14.4,32.1 32.1,32.1 z"
+   id="path6"
+   inkscape:connector-curvature="0"
+   style="fill:#009fe3" />
+
+			<path
+   class="st1"
+   d="m 128,187.4 c 34.3,0 62.3,-28 62.3,-62.3 0,-0.9 -0.8,-1.7 -1.7,-1.7 h -12.1 c -0.9,0 -1.7,0.8 -1.7,1.7 0,25.9 -21,46.9 -46.9,46.9 C 102,172 81,151 81,125.1 c 0,-0.9 -0.8,-1.7 -1.7,-1.7 H 67.4 c -0.9,0 -1.7,0.8 -1.7,1.7 -0.2,34.3 27.8,62.3 62.3,62.3 z"
+   id="path8"
+   inkscape:connector-curvature="0"
+   style="fill:#009fe3" />
+
+			<path
+   class="st1"
+   d="m 219,123.4 h -12.1 c -0.9,0 -1.7,0.8 -1.7,1.7 0,42.6 -34.8,77.3 -77.3,77.3 -42.6,0 -77.3,-34.6 -77.3,-77.3 0,-0.9 -0.8,-1.7 -1.7,-1.7 H 37 c -0.9,0 -1.7,0.8 -1.7,1.7 0,51.1 41.6,92.7 92.7,92.7 51.1,0 92.7,-41.6 92.7,-92.7 0,-0.9 -0.8,-1.7 -1.7,-1.7 z"
+   id="path10"
+   inkscape:connector-curvature="0"
+   style="fill:#009fe3" />
+
+		</g>
+
+		<path
+   class="st2"
+   d="m 86.3,83.3 c 6.2,3.2 12.9,3.8 18.9,7.3 3.9,2.3 6.4,4.8 8.8,8.6 3.8,5.7 3.6,12.9 3.6,12.9 l 0.5,7.9 c 0,0 3,7.9 9.7,7.9 7.1,0 9.7,-7.9 9.7,-7.9 l 0.5,-7.9 c 0,0 -0.2,-7.1 3.6,-12.9 2.4,-3.8 4.8,-6.5 8.8,-8.6 6,-3.5 12.7,-4.1 18.9,-7.3 6.2,-3.2 12.2,-7.3 16.3,-13 4.1,-5.7 6,-13.3 3.8,-20 -11.8,-0.6 -25.4,0.8 -35.8,6.4 -14.5,7.7 -23.3,5 -25.9,16.5 h -0.2 c -2.6,-11.6 -11.3,-8.8 -25.9,-16.5 -10.4,-5.6 -24,-7 -35.8,-6.4 -2.3,6.7 -0.3,14.2 3.8,20 4.4,5.8 10.5,9.9 16.7,13 z"
+   id="path14"
+   inkscape:connector-curvature="0"
+   style="fill:#3c3c3b" />
+
+	</g>
+
+</g>
+      <g
+         transform="translate(-0.75595238,-0.75595238)"
+         id="g5221">
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 32.845914,132.89252 c 0,-6.69443 2.603389,-9.29781 10.413554,-9.29781 1.636415,0 3.719126,0.14876 4.834864,0.37191 0.59506,0.14876 1.115738,0.59506 1.115738,1.11574 v 2.00832 c 0,0.59506 -0.446295,1.11574 -1.115738,1.11574 h -0.669443 c -0.818208,0 -1.48765,-0.29753 -2.529006,-0.29753 -4.834864,0 -5.801837,0.96698 -5.801837,4.98363 v 0.29753 h 6.620045 c 0.59506,0 1.115738,0.4463 1.115738,1.11574 v 2.15709 c 0,0.66945 -0.446295,1.11574 -1.115738,1.11574 h -6.620045 v 11.30614 c 0,0.59506 -0.446295,1.11574 -1.115737,1.11574 h -4.016657 c -0.59506,0 -1.115738,-0.52068 -1.115738,-1.11574 z"
+           id="path5166" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 57.020235,141.59528 c 0,3.04968 1.413268,4.31418 3.495978,4.31418 1.785181,0 3.495979,-1.2645 4.834864,-2.60339 v -12.12435 c 0,-0.59506 0.520678,-1.11573 1.115738,-1.11573 h 4.091039 c 0.59506,0 1.115738,0.52067 1.115738,1.11573 v 17.70304 c 0,0.59506 -0.446295,1.11574 -1.115738,1.11574 h -4.091039 c -0.59506,0 -1.115738,-0.52068 -1.115738,-1.11574 v -1.19012 c -1.710798,1.48765 -3.570361,2.67777 -6.322514,2.67777 -4.834864,0 -8.25646,-2.529 -8.25646,-8.70275 v -10.41355 c 0,-0.59506 0.446295,-1.11574 1.115738,-1.11574 h 4.091038 c 0.595061,0 1.115738,0.52068 1.115738,1.11574 v 10.33917 z"
+           id="path5168" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 90.715518,138.47121 c 0,-3.04968 -1.413268,-4.31419 -3.495979,-4.31419 -1.78518,0 -3.570361,1.26451 -4.909246,2.60339 v 12.19874 c 0,0.59506 -0.446295,1.11573 -1.115738,1.11573 h -4.091039 c -0.669442,0 -1.115738,-0.52067 -1.115738,-1.11573 v -17.77743 c 0,-0.59506 0.446296,-1.11573 1.115738,-1.11573 h 4.165422 c 0.59506,0 1.115737,0.52067 1.115737,1.11573 v 1.19012 c 1.710798,-1.48765 3.570362,-2.67777 6.396897,-2.67777 4.834865,0 8.256461,2.52901 8.256461,8.70276 v 10.41355 c 0,0.59506 -0.446295,1.11574 -1.115738,1.11574 h -4.091039 c -0.59506,0 -1.115738,-0.52068 -1.115738,-1.11574 z"
+           id="path5170" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 107.67473,137.95053 c 2.1571,0 3.57036,-0.89259 4.31419,-2.45462 l 1.78518,-3.71913 c 0.4463,-1.04135 1.56203,-1.71079 2.60339,-1.71079 h 3.42159 c 0.96698,0 1.11574,0.74382 0.59507,1.71079 l -2.38025,4.98363 c -0.74382,1.63642 -2.23147,2.90092 -3.86789,3.27283 1.48765,0.4463 2.75216,1.48765 3.86789,3.27283 l 3.12407,4.98363 c 0.59506,0.96698 0.29753,1.7108 -0.59506,1.7108 h -3.4216 c -1.19012,0 -2.15709,-0.74382 -2.75215,-1.7108 l -2.30586,-3.71912 c -0.96697,-1.63642 -2.67777,-2.38024 -4.31418,-2.38024 v 6.76881 c 0,0.59506 -0.4463,1.11573 -1.11574,1.11573 h -4.09104 c -0.59506,0 -1.11574,-0.52067 -1.11574,-1.11573 v -23.80241 c 0,-0.59506 0.4463,-1.11574 1.11574,-1.11574 h 4.09104 c 0.59506,0 1.11574,0.52068 1.11574,1.11574 v 12.79379 z"
+           id="path5172" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 140.1799,130.06599 c 1.04135,0 1.78518,0.59506 2.08271,1.56203 l 2.9753,9.81849 2.9753,-9.81849 c 0.29753,-1.04136 1.33888,-1.56203 2.45462,-1.56203 h 3.34722 c 0.89259,0 1.04135,0.66944 0.74382,1.56203 l -5.50431,16.73607 c -0.29753,0.96697 -1.33888,1.56203 -2.30585,1.56203 h -2.60339 c -0.89259,0 -2.00833,-0.59506 -2.30586,-1.56203 l -3.49598,-10.78547 -3.49598,10.85985 c -0.29753,0.96697 -1.41327,1.56203 -2.30586,1.56203 h -2.60338 c -0.96698,0 -1.93395,-0.59506 -2.30586,-1.56203 l -5.50431,-16.73607 c -0.29753,-0.89259 -0.0744,-1.56203 0.74383,-1.56203 h 3.34721 c 1.11574,0 2.08271,0.59506 2.45462,1.56203 l 2.9753,9.81849 2.9753,-9.81849 c 0.29753,-0.96697 1.04136,-1.56203 2.08272,-1.56203 h 3.27283 z"
+           id="path5174" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 172.09,138.47121 c 0,-3.04968 -1.41327,-4.31419 -3.4216,-4.31419 -1.78518,0 -3.57036,1.26451 -4.90924,2.60339 v 12.19874 c 0,0.59506 -0.4463,1.11573 -1.11574,1.11573 h -4.09104 c -0.59506,0 -1.11574,-0.52067 -1.11574,-1.11573 v -23.80241 c 0,-0.59506 0.52068,-1.11574 1.11574,-1.11574 h 4.09104 c 0.59506,0 1.11574,0.52068 1.11574,1.11574 v 7.2151 c 1.71079,-1.48765 3.57036,-2.67777 6.39689,-2.67777 4.83487,0 8.25646,2.52901 8.25646,8.70276 v 10.41355 c 0,0.59506 -0.52067,1.11574 -1.11573,1.11574 h -4.09104 c -0.59506,0 -1.11574,-0.52068 -1.11574,-1.11574 z"
+           id="path5176" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 189.04921,135.04961 c -0.44629,0.59506 -1.19012,0.96698 -2.08271,0.96698 h -2.67777 c -0.59506,0 -1.11573,-0.4463 -1.11573,-1.11574 0,-3.86789 3.86789,-5.20678 9.89287,-5.20678 5.35554,0 9.59535,2.23148 9.59535,7.88455 v 11.23176 c 0,0.59506 -0.52068,1.11574 -1.11574,1.11574 h -3.49598 c -0.59506,0 -1.11574,-0.52068 -1.11574,-1.11574 v -0.59506 c -1.7108,1.19012 -3.71912,2.08271 -6.62004,2.08271 -4.83487,0 -8.55399,-2.15709 -8.55399,-6.39689 0,-4.23981 3.71912,-6.32252 8.55399,-6.32252 h 6.02498 c 0,-2.90092 -1.19012,-3.79351 -3.71912,-3.79351 -1.56204,0.0744 -2.9753,0.52068 -3.57037,1.2645 z m 7.28949,9.52097 v -2.82654 h -5.57869 c -1.78518,0 -2.75215,0.96697 -2.75215,2.23148 0,1.2645 0.96697,2.23147 2.9753,2.23147 2.15709,0 4.01666,-0.8182 5.35554,-1.63641 z"
+           id="path5178" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 208.16552,150.0005 c -0.59506,0 -1.11573,-0.52068 -1.11573,-1.11574 v -23.8024 c 0,-0.59506 0.52067,-1.11574 1.11573,-1.11574 h 4.09104 c 0.59506,0 1.11574,0.52068 1.11574,1.11574 v 23.8024 c 0,0.59506 -0.44629,1.11574 -1.11574,1.11574 z"
+           id="path5180" />
+        <path
+           style="fill:#3c3c3b;fill-opacity:1;stroke-width:0.74382526"
+           inkscape:connector-curvature="0"
+           d="m 223.04203,141.96719 c 0.22315,2.9753 1.56203,4.2398 4.61171,4.2398 1.56204,0 2.97531,-0.44629 3.57037,-1.19012 0.52067,-0.59506 1.19012,-0.96697 2.08271,-0.96697 h 2.67777 c 0.59506,0 1.11574,0.52068 1.11574,1.11574 0,3.86789 -3.94228,5.20677 -9.89288,5.20677 -6.62004,0 -10.6367,-3.57036 -10.6367,-10.26478 0,-6.69443 4.01666,-10.33917 10.6367,-10.33917 6.62004,0 10.56232,3.57036 10.56232,10.11602 v 1.04135 c 0,0.59506 -0.4463,1.11574 -1.11574,1.11574 h -13.612 z m 0,-3.86789 h 8.47961 c -0.14877,-2.75216 -1.48765,-4.23981 -4.23981,-4.23981 -2.67777,0 -4.09104,1.48765 -4.2398,4.23981 z"
+           id="path5182" />
+      </g>
+    </g>
+  </g>
+  <style
+     id="style2"
+     type="text/css">
+	.st0{fill:#FFFFFF;}
+	.st1{fill:#009FE3;}
+	.st2{fill:#3C3C3B;}
+</style>
+</svg>
diff --git a/front/src/components/About.vue b/front/src/components/About.vue
index cfffb7b6a2de69beec727d6a230ec4df00941d64..87f741aa819f38ba84c856522979f25e6f6016d1 100644
--- a/front/src/components/About.vue
+++ b/front/src/components/About.vue
@@ -3,10 +3,10 @@
     <section class="ui vertical center aligned stripe segment">
       <div class="ui text container">
         <h1 class="ui huge header">
-            <translate v-if="instance.name.value" :translate-params="{instance: instance.name.value}">
+            <span v-translate="{instance: instance.name.value}" translate-context="Content/About/Title/Short, Noun" v-if="instance.name.value" :translate-params="{instance: instance.name.value}">
              About %{ instance }
-            </translate>
-            <translate v-else>About this instance</translate>
+            </span>
+            <translate translate-context="Content/About/Title" v-else>About this instance</translate>
         </h1>
         <stats></stats>
       </div>
@@ -15,12 +15,12 @@
       <div
         class="ui middle aligned stackable text container">
         <p
-        v-if="!instance.short_description.value && !instance.long_description.value"><translate>Unfortunately, owners of this instance did not yet take the time to complete this page.</translate></p>
+        v-if="!instance.short_description.value && !instance.long_description.value"><translate translate-context="Content/About/Paragraph">Unfortunately, the owners of this instance did not yet take the time to complete this page.</translate></p>
         <router-link
           class="ui button"
           v-if="$store.state.auth.availablePermissions['settings']"
           :to="{path: '/manage/settings', hash: 'instance'}">
-          <i class="pencil icon"></i><translate>Edit instance info</translate>
+          <i class="pencil icon"></i><translate translate-context="Content/Settings/Button.Label/Verb">Edit instance info</translate>
         </router-link>
         <div class="ui hidden divider"></div>
       </div>
@@ -64,7 +64,7 @@ export default {
     }),
     labels() {
       return {
-        title: this.$gettext("About this instance")
+        title: this.$pgettext('Content/About/Title', "About this instance")
       }
     }
   }
diff --git a/front/src/components/Footer.vue b/front/src/components/Footer.vue
index 2767167e2fc30cf097047e61b4915df593884b06..2d06b50c768e368c538b15bbcf6b33a00c6b42ab 100644
--- a/front/src/components/Footer.vue
+++ b/front/src/components/Footer.vue
@@ -3,23 +3,23 @@
     <div class="ui container">
       <div class="ui stackable equal height stackable grid">
         <section class="four wide column">
-          <h4 v-translate class="ui header">
-            <translate :translate-params="{instanceName: instanceHostname}" >About %{instanceName}</translate>
+          <h4 class="ui header">
+            <translate translate-context="Footer/About/Title" :translate-params="{instanceName: instanceHostname}" >About %{instanceName}</translate>
           </h4>
           <div class="ui link list">
             <router-link class="item" to="/about">
-              <translate>About page</translate>
+              <translate translate-context="Footer/About/List item.Link">About page</translate>
             </router-link>
-            <div class="item" v-if="version">
-              <translate :translate-params="{version: version}" >Version %{version}</translate>
+              <a v-if="version" class="item" href="https://docs.funkwhale.audio/changelog.html" target="_blank">
+                <translate translate-context="Footer/*/List item" :translate-params="{version: version}" >Version %{version}</translate>
+              </a>
+            <div role="button" class="item" @click="$emit('show:set-instance-modal')" >
+              <translate translate-context="Footer/*/List item.Link">Use another instance</translate>
             </div>
-            <a @click="switchInstance" class="item" >
-              <translate>Use another instance</translate>
-            </a>
           </div>
           <div class="ui form">
             <div class="ui field">
-              <label><translate>Change language</translate></label>
+              <label><translate translate-context="Footer/Settings/Dropdown.Label/Short, Verb">Change language</translate></label>
               <select class="ui dropdown" :value="$language.current" @change="$store.commit('ui/currentLanguage', $event.target.value)">
                 <option v-for="(language, key) in $language.available" :key="key" :value="key">{{ language }}</option>
               </select>
@@ -27,31 +27,31 @@
           </div>
         </section>
         <section class="four wide column">
-          <h4 v-translate class="ui header">Using Funkwhale</h4>
+          <h4 v-translate class="ui header" translate-context="Footer/*/Title">Using Funkwhale</h4>
           <div class="ui link list">
-            <a href="https://docs.funkwhale.audio" class="item" target="_blank"><translate>Documentation</translate></a>
-            <a href="https://docs.funkwhale.audio/users/apps.html" class="item" target="_blank"><translate>Mobile and desktop apps</translate></a>
-            <div role="button" class="item" @click="$emit('show:shortcuts-modal')"><translate>Keyboard shortcuts</translate></div>
+            <a href="https://docs.funkwhale.audio" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link/Short, Noun">Documentation</translate></a>
+            <a href="https://funkwhale.audio/apps" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Mobile and desktop apps</translate></a>
+            <div role="button" class="item" @click="$emit('show:shortcuts-modal')"><translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate></div>
           </div>
         </section>
         <section class="four wide column">
-          <h4 v-translate class="ui header">Getting help</h4>
+          <h4 v-translate translate-context="Footer/*/Link" class="ui header">Getting help</h4>
           <div class="ui link list">
-            <a href="https://socialhub.network/c/funkwhale" class="item" target="_blank"><translate>Support forum</translate></a>
-            <a href="https://riot.im/app/#/room/#funkwhale-troubleshooting:matrix.org" class="item" target="_blank"><translate>Chat room</translate></a>
-            <a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="item" target="_blank"><translate>Issue tracker</translate></a>
+            <a href="https://governance.funkwhale.audio/g/kQgxNq15/funkwhale" class="item" target="_blank"><translate translate-context="Footer/*/Listitem.Link">Support forum</translate></a>
+            <a href="https://riot.im/app/#/room/#funkwhale-troubleshooting:matrix.org" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Chat room</translate></a>
+            <a href="https://dev.funkwhale.audio/funkwhale/funkwhale/issues" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Issue tracker</translate></a>
           </div>
         </section>
         <section class="four wide column">
-          <h4 v-translate class="ui header">About Funkwhale</h4>
+          <h4 v-translate class="ui header" translate-context="Footer/*/Title/Short">About Funkwhale</h4>
           <div class="ui link list">
-            <a href="https://funkwhale.audio" class="item" target="_blank"><translate>Official website</translate></a>
-            <a href="https://contribute.funkwhale.audio" class="item" target="_blank"><translate>Contribute</translate></a>
-            <a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="item" target="_blank"><translate>Source code</translate></a>
+            <a href="https://funkwhale.audio" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Official website</translate></a>
+            <a href="https://contribute.funkwhale.audio" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Contribute</translate></a>
+            <a href="https://dev.funkwhale.audio/funkwhale/funkwhale" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Source code</translate></a>
           </div>
           <div class="ui hidden divider"></div>
           <p>
-            <translate>The funkwhale logo was kindly designed and provided by Francis Gading.</translate>
+            <translate translate-context="Footer/*/List item.Link">The funkwhale logo was kindly designed and provided by Francis Gading.</translate>
           </p>
         </section>
       </div>
@@ -66,18 +66,6 @@ import axios from 'axios'
 
 export default {
   props: ["version"],
-  methods: {
-    switchInstance() {
-      let confirm = window.confirm(
-        this.$gettext(
-          "This will erase your local data and disconnect you, do you want to continue?"
-        )
-      )
-      if (confirm) {
-        this.$store.commit("instance/instanceUrl", null)
-      }
-    }
-  },
   computed: {
     ...mapState({
       messages: state => state.ui.messages
@@ -88,13 +76,6 @@ export default {
       parser.href = url
       return parser.hostname
     },
-    suggestedInstances() {
-      let instances = [
-        this.$store.getters["instance/defaultUrl"](),
-        "https://demo.funkwhale.audio"
-      ]
-      return instances
-    }
   }
 }
 </script>
@@ -102,4 +83,8 @@ export default {
 footer p {
   color: grey;
 }
+
+footer#footer div.item:hover {
+  color: rgba(0, 0, 0, 0.87);
+}
 </style>
diff --git a/front/src/components/Home.vue b/front/src/components/Home.vue
index bdca00005221abce7058d08dd9141d3cd3175867..b88369d952a816c0a4b9acf7db0555b8290049e3 100644
--- a/front/src/components/Home.vue
+++ b/front/src/components/Home.vue
@@ -3,15 +3,15 @@
     <section class="ui vertical center aligned stripe segment">
       <div class="ui text container">
         <h1 class="ui huge header">
-          <translate>Welcome on Funkwhale</translate>
+          <translate translate-context="Content/Home/Title/Verb">Welcome on Funkwhale</translate>
         </h1>
-        <p><translate>We think listening to music should be simple.</translate></p>
+        <p><translate translate-context="Content/Home/Title">We think listening to music should be simple.</translate></p>
         <router-link class="ui icon button" to="/about">
           <i class="info icon"></i>
-          <translate>Learn more about this instance</translate>
+          <translate translate-context="Content/Home/Button.Label/Verb">Learn more about this instance</translate>
         </router-link>
         <router-link class="ui icon teal button" to="/library">
-          <translate>Get me to the library</translate>
+          <translate translate-context="Content/Home/Button.Label/Verb">Get me to the library</translate>
           <i class="right arrow icon"></i>
         </router-link>
       </div>
@@ -22,9 +22,9 @@
           <div class="row">
             <div class="eight wide left floated column">
               <h2 class="ui header">
-                <translate>Why funkwhale?</translate>
+                <translate translate-context="Content/Home/Title">Why funkwhale?</translate>
               </h2>
-              <p><translate>That's simple: we loved Grooveshark and we want to build something even better.</translate></p>
+              <p><translate translate-context="Content/Home/Paragraph">That's simple: we loved Grooveshark and we want to build something even better.</translate></p>
             </div>
             <div class="four wide left floated column">
               <img class="ui medium image" src="../assets/logo/logo.png" />
@@ -35,26 +35,26 @@
       <div class="ui middle aligned stackable text container">
         <div class="ui hidden divider"></div>
         <h2 class="ui header">
-          <translate>Unlimited music</translate>
+          <translate translate-context="Content/Home/Title">Unlimited music</translate>
         </h2>
-        <p><translate>Funkwhale is designed to make it easy to listen to music you like, or to discover new artists.</translate></p>
+        <p><translate translate-context="Content/Home/Paragraph">Funkwhale is designed to make it easy to listen to music you like, or to discover new artists.</translate></p>
         <div class="ui list">
           <div class="item">
             <i class="sound icon"></i>
             <div class="content">
-              <translate>Click once, listen for hours using built-in radios</translate>
+              <translate translate-context="Content/Home/List item/Verb">Click once, listen for hours using built-in radios</translate>
             </div>
           </div>
           <div class="item">
             <i class="heart icon"></i>
             <div class="content">
-              <translate>Keep a track of your favorite songs</translate>
+              <translate translate-context="Content/Home/List item/Verb">Keep a track of your favorite songs</translate>
             </div>
           </div>
           <div class="item">
             <i class="list icon"></i>
             <div class="content">
-              <translate>Playlists? We got them</translate>
+              <translate translate-context="Content/Home/List item">Playlists? We got them</translate>
             </div>
           </div>
         </div>
@@ -62,28 +62,23 @@
       <div class="ui middle aligned stackable text container">
         <div class="ui hidden divider"></div>
         <h2 class="ui header">
-          <translate>Clean library</translate>
+          <translate translate-context="Content/Home/Title">A clean library</translate>
         </h2>
-        <p><translate>Funkwhale takes care of handling your music</translate>.</p>
+        <p><translate translate-context="Content/Home/Paragraph">Funkwhale takes care of handling your music</translate>.</p>
         <div class="ui list">
-          <div class="item">
-            <i class="download icon"></i>
-            <div class="content">
-              <translate>Import music from various platforms, such as YouTube or SoundCloud</translate>
-            </div>
-          </div>
           <div class="item">
             <i class="tag icon"></i>
             <div
               class="content"
-              v-translate="{url: musicbrainzUrl}">
+              v-translate="{url: musicbrainzUrl}"
+              translate-context="Content/Home/List item/Verb">
                 Get quality metadata about your music thanks to <a href="%{ url }" target="_blank">MusicBrainz</a>
             </div>
           </div>
           <div class="item">
             <i class="plus icon"></i>
             <div class="content">
-              <translate>Covers, lyrics, our goal is to have them all ;)</translate>
+              <translate translate-context="Content/Home/List item">Covers, lyrics, our goal is to have them all ;)</translate>
             </div>
           </div>
         </div>
@@ -91,20 +86,20 @@
       <div class="ui middle aligned stackable text container">
         <div class="ui hidden divider"></div>
         <h2 class="ui header">
-          <translate>Easy to use</translate>
+          <translate translate-context="Content/Home/Title">Easy to use</translate>
         </h2>
-        <p><translate>Funkwhale is dead simple to use.</translate></p>
+        <p><translate translate-context="Content/Home/Paragraph">Funkwhale is dead simple to use.</translate></p>
         <div class="ui list">
           <div class="item">
             <i class="book icon"></i>
             <div class="content">
-              <translate>No add-ons, no plugins : you only need a web library</translate>
+              <translate translate-context="Content/Home/List item">No add-ons, no plugins : you only need a web library</translate>
             </div>
           </div>
           <div class="item">
             <i class="wizard icon"></i>
             <div class="content">
-              <translate>Access your music from a clean interface that focus on what really matters</translate>
+              <translate translate-context="Content/Home/List item">Access your music from a clean interface that focuses on what really matters</translate>
             </div>
           </div>
         </div>
@@ -112,26 +107,26 @@
       <div class="ui middle aligned stackable text container">
         <div class="ui hidden divider"></div>
         <h2 class="ui header">
-          <translate>Your music, your way</translate>
+          <translate translate-context="Content/Home/Title">Your music, your way</translate>
         </h2>
-        <p><translate>Funkwhale is free and gives you control on your music.</translate></p>
+        <p><translate translate-context="Content/Home/Paragraph">Funkwhale is free and gives you control on your music.</translate></p>
         <div class="ui list">
           <div class="item">
             <i class="smile icon"></i>
             <div class="content">
-              <translate>The plaform is free and open-source, you can install it and modify it without worries</translate>
+              <translate translate-context="Content/Home/List item">The plaform is free and open-source, you can install it and modify it without worries</translate>
             </div>
           </div>
           <div class="item">
             <i class="protect icon"></i>
             <div class="content">
-              <translate>We do not track you or bother you with ads</translate>
+              <translate translate-context="Content/Home/List item">We do not track you or bother you with ads</translate>
             </div>
           </div>
           <div class="item">
             <i class="users icon"></i>
             <div class="content">
-              <translate>You can invite friends and family to your instance so they can enjoy your music</translate>
+              <translate translate-context="Content/Home/List item">You can invite friends and family to your instance so they can enjoy your music</translate>
             </div>
           </div>
         </div>
@@ -150,7 +145,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Welcome")
+        title: this.$pgettext('Head/Home/Title', "Welcome")
       }
     }
   }
diff --git a/front/src/components/Logo.vue b/front/src/components/Logo.vue
index ff87dc299885acf39c57a67967d32ab3b3b87193..9785437c975b8e19669eb8da3296553a2fb58224 100644
--- a/front/src/components/Logo.vue
+++ b/front/src/components/Logo.vue
@@ -1,21 +1,21 @@
 <template>
   <svg version="1.1" id="layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-  	 viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
+     viewBox="0 0 141.7 141.7" enable-background="new 0 0 141.7 141.7" xml:space="preserve">
   <g>
-  	<g>
-  		<path :fill="fill" d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
-  			c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"/>
-  		<path :fill="fill" d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
-  			c0,17.1-13.9,31-31,31c-17.1,0-31-13.9-31-31c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C29.6,87.6,48.1,106.1,70.9,106.1z"
-  			/>
-  		<path :fill="fill" d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
-  			c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,33.8,27.5,61.3,61.3,61.3c33.8,0,61.3-27.5,61.3-61.3
-  			C132.2,64.3,131.7,63.8,131.1,63.8z"/>
-  	</g>
-  	<path :fill="fill" d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
-  		c0,0,2,5.2,6.4,5.2c4.7,0,6.4-5.2,6.4-5.2l0.3-5.2c0,0-0.1-4.7,2.4-8.5c1.6-2.5,3.2-4.3,5.8-5.7c4-2.3,8.4-2.7,12.5-4.8
-  		c4.1-2.1,8.1-4.8,10.8-8.6c2.7-3.8,4-8.8,2.5-13.2c-7.8-0.4-16.8,0.5-23.7,4.2c-9.6,5.1-15.4,3.3-17.1,10.9h-0.1
-  		c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"/>
+    <g>
+      <path :fill="fill" d="M70.9,86.1c11.7,0,21.2-9.5,21.2-21.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,6-4.9,11-11,11
+        c-6,0-11-4.9-11-11c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C49.7,76.6,59.2,86.1,70.9,86.1z"/>
+      <path :fill="fill" d="M70.9,106.1c22.7,0,41.2-18.5,41.2-41.2c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1
+        c0,17.1-13.9,31-31,31c-17.1,0-31-13.9-31-31c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1C29.6,87.6,48.1,106.1,70.9,106.1z"
+        />
+      <path :fill="fill" d="M131.1,63.8h-8c-0.6,0-1.1,0.5-1.1,1.1C122,93.1,99,116,70.9,116c-28.2,0-51.1-22.9-51.1-51.1
+        c0-0.6-0.5-1.1-1.1-1.1h-8c-0.6,0-1.1,0.5-1.1,1.1c0,33.8,27.5,61.3,61.3,61.3c33.8,0,61.3-27.5,61.3-61.3
+        C132.2,64.3,131.7,63.8,131.1,63.8z"/>
+    </g>
+    <path :fill="fill" d="M43.3,37.3c4.1,2.1,8.5,2.5,12.5,4.8c2.6,1.5,4.2,3.2,5.8,5.7c2.5,3.8,2.4,8.5,2.4,8.5l0.3,5.2
+      c0,0,2,5.2,6.4,5.2c4.7,0,6.4-5.2,6.4-5.2l0.3-5.2c0,0-0.1-4.7,2.4-8.5c1.6-2.5,3.2-4.3,5.8-5.7c4-2.3,8.4-2.7,12.5-4.8
+      c4.1-2.1,8.1-4.8,10.8-8.6c2.7-3.8,4-8.8,2.5-13.2c-7.8-0.4-16.8,0.5-23.7,4.2c-9.6,5.1-15.4,3.3-17.1,10.9h-0.1
+      c-1.7-7.7-7.5-5.8-17.1-10.9c-6.9-3.7-15.9-4.6-23.7-4.2c-1.5,4.4-0.2,9.4,2.5,13.2C35.2,32.5,39.2,35.2,43.3,37.3z"/>
   </g>
   </svg>
 
diff --git a/front/src/components/PageNotFound.vue b/front/src/components/PageNotFound.vue
index ef4e66f456cb03e63ad4dfcf441a22bcc1536735..4dce665bbefaf0cc0957f8200ae939a7e641c5fd 100644
--- a/front/src/components/PageNotFound.vue
+++ b/front/src/components/PageNotFound.vue
@@ -5,14 +5,14 @@
         <h1 class="ui huge header">
           <i class="warning icon"></i>
           <div class="content">
-            <translate>Page not found!</translate>
+            <translate translate-context="Content/*/Title">Page not found!</translate>
           </div>
         </h1>
-        <p><translate>We're sorry, the page you asked for does not exist:</translate></p>
+        <p><translate translate-context="Content/*/Paragraph">Sorry, the page you asked for does not exist:</translate></p>
         <a :href="path">{{ path }}</a>
         <div class="ui hidden divider"></div>
-        <router-link class="ui icon button" to="/">
-          <translate>Go to home page</translate>
+        <router-link class="ui icon labeled right button" to="/">
+          <translate translate-context="Content/*/Button.Label/Verb">Go to home page</translate>
           <i class="right arrow icon"></i>
         </router-link>
       </div>
@@ -30,7 +30,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Page Not Found")
+        title: this.$pgettext('Head/*/Title', "Page Not Found")
       }
     }
   }
diff --git a/front/src/components/Pagination.vue b/front/src/components/Pagination.vue
index 963b000a81b490d468a439be130893b66b5a7084..4820822380b0b44b084d7569f476782ec77bc324 100644
--- a/front/src/components/Pagination.vue
+++ b/front/src/components/Pagination.vue
@@ -36,7 +36,7 @@ export default {
   computed: {
     labels() {
       return {
-        pagination: this.$gettext("Pagination")
+        pagination: this.$pgettext('Content/*/Hidden text/Noun', "Pagination")
       }
     },
     pages: function() {
diff --git a/front/src/components/SetInstanceModal.vue b/front/src/components/SetInstanceModal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b2c278564a8f453cb729f5d65def4ad29d73bd93
--- /dev/null
+++ b/front/src/components/SetInstanceModal.vue
@@ -0,0 +1,147 @@
+<template>
+  <modal @update:show="$emit('update:show', $event); isError = false" :show="show">
+    <div class="header"><translate translate-context="Popup/Instance/Title">Choose your instance</translate></div>
+    <div class="scrolling content">
+      <div v-if="isError" class="ui negative message">
+        <div class="header"><translate translate-context="Popup/Instance/Error message.Title">It is not possible to connect to the given URL</translate></div>
+        <ul class="list">
+          <li><translate translate-context="Popup/Instance/Error message.List item">The server might be down</translate></li>
+          <li><translate translate-context="Popup/Instance/Error message.List item">The given address is not a Funkwhale server</translate></li>
+        </ul>
+      </div>
+      <form class="ui form" @submit.prevent="checkAndSwitch(instanceUrl)">
+        <p v-if="$store.state.instance.instanceUrl" class="description" translate-context="Popup/Login/Paragraph" v-translate="{url: $store.state.instance.instanceUrl, hostname: instanceHostname }">
+            You are currently connected to <a href="%{ url }" target="_blank">%{ hostname }&nbsp;<i class="external icon"></i></a>. If you continue, you will be disconnected from your current instance and all your local data will be deleted.
+        </p>
+        <p v-else>
+          <translate translate-context="Popup/Instance/Paragraph">To continue, please select the Funkwhale instance you want to connect to. Enter the address directly, or select one of the suggested choices.</translate>
+        </p>
+        <div class="field">
+          <label><translate translate-context="Popup/Instance/Input.Label/Noun">Instance URL</translate></label>
+          <div class="ui action input">
+            <input type="text" v-model="instanceUrl" placeholder="https://funkwhale.server">
+            <button type="submit" :class="['ui', 'icon', {loading: isLoading}, 'button']">
+              <translate translate-context="*/*/Button.Label/Verb">Submit</translate>
+            </button>
+          </div>
+        </div>
+      </form>
+      <div class="ui hidden divider"></div>
+      <form class="ui form" @submit.prevent="">
+        <div class="field">
+          <label><translate translate-context="Popup/Instance/List.Label">Suggested choices</translate></label>
+          <button v-for="url in suggestedInstances" @click="checkAndSwitch(url)" class="ui basic button">{{ url }}</button>
+        </div>
+      </form>
+    </div>
+    <div class="actions">
+      <div class="ui cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
+    </div>
+  </modal>
+</template>
+
+<script>
+import Modal from '@/components/semantic/Modal'
+import axios from 'axios'
+import _ from "@/lodash"
+
+export default {
+  props: ['show'],
+  components: {
+    Modal,
+  },
+  data() {
+    return {
+      instanceUrl: null,
+      nodeinfo: null,
+      isError: false,
+      isLoading: false,
+      path: 'api/v1/instance/nodeinfo/2.0/',
+    }
+  },
+  methods: {
+    fetchNodeInfo () {
+      let self = this
+      axios.get('instance/nodeinfo/2.0/').then(response => {
+        self.nodeinfo = response.data
+      })
+    },
+    fetchUrl (url) {
+      let urlFetch = url
+      if (!urlFetch.endsWith('/')) {
+        urlFetch = `${urlFetch}/${this.path}`
+      } else {
+        urlFetch =  `${urlFetch}${this.path}`
+      }
+      if (!urlFetch.startsWith('https://') && !urlFetch.startsWith('http://')) {
+        urlFetch = `https://${urlFetch}`
+      }
+      return urlFetch
+    },
+    requestDistantNodeInfo (url) {
+      var self = this
+      axios.get(this.fetchUrl(url)).then(function (response) {
+        self.isLoading = false
+        if(!url.startsWith('https://') && !url.startsWith('http://')) {
+          url = `https://${url}`
+        }
+        self.switchInstance(url)
+      }).catch(function (error) {
+        self.isLoading = false
+        self.isError = true
+      })
+    },
+    switchInstance (url) {
+      // Here we disconnect from the current instance and reconnect to the new one. No check is performed...
+      this.$emit('update:show', false)
+      this.isError = false
+      let msg = this.$pgettext('*/Instance/Message', 'You are now using the Funkwhale instance at %{ url }')
+      this.$store.commit('ui/addMessage', {
+        content: this.$gettextInterpolate(msg, {url: url}),
+        date: new Date()
+      })
+      let self = this
+      this.$nextTick(() => {
+        self.$store.commit('instance/instanceUrl', null)
+        self.$store.dispatch('instance/setUrl', url)
+      })
+    },
+    checkAndSwitch (url) {
+      // First we have to check if the address is a valid FW server. If yes, we switch:
+      this.isError = false // Clear error message if any...
+      this.isLoading = true
+      this.requestDistantNodeInfo(url)
+    },
+  },
+  computed: {
+    suggestedInstances () {
+      let instances = this.$store.state.instance.knownInstances.slice(0)
+      if (this.$store.state.instance.frontSettings.defaultServerUrl) {
+        let serverUrl = this.$store.state.instance.frontSettings.defaultServerUrl
+        if (!serverUrl.endsWith('/')) {
+          serverUrl = serverUrl + '/'
+        }
+        instances.push(serverUrl)
+      }
+      let self = this
+      instances.push(this.$store.getters['instance/defaultUrl'](), 'https://demo.funkwhale.audio/')
+      return _.uniq(instances.filter((e) => {return e != self.$store.state.instance.instanceUrl}))
+    },
+    instanceHostname() {
+      let url = this.$store.state.instance.instanceUrl
+      let parser = document.createElement("a")
+      parser.href = url
+      return parser.hostname
+    },
+  },
+  watch: {
+    '$store.state.instance.instanceUrl' () {
+      this.$store.dispatch('instance/fetchSettings')
+      this.fetchNodeInfo()
+    },
+  },
+}
+</script>
+
+<style scoped>
+</style>
diff --git a/front/src/components/ShortcutsModal.vue b/front/src/components/ShortcutsModal.vue
index 2338658dd7b80a9d67c0e424f22b7b7f827270b1..5b1a7349d441a0de9c708f2ab9dbc03f576ab98e 100644
--- a/front/src/components/ShortcutsModal.vue
+++ b/front/src/components/ShortcutsModal.vue
@@ -1,11 +1,11 @@
 <template>
   <modal @update:show="$emit('update:show', $event)" :show="show">
     <header class="header">
-      <translate>Keyboard shortcuts</translate>
+      <translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate>
     </header>
     <section class="scrolling content">
       <table
-        class="ui compact collapsing basic fixed single line table"
+        class="ui compact collapsing basic table"
         v-for="section in sections"
         :key="section.title">
       <caption>{{ section.title }}</caption>
@@ -18,7 +18,7 @@
       </table>
     </section>
     <footer class="actions">
-      <div class="ui cancel button"><translate>Close</translate></div>
+      <div class="ui cancel button"><translate translate-context="Popup/Keyboard shortcuts/Button.Label/Verb">Close</translate></div>
     </footer>
   </modal>
 </template>
@@ -35,11 +35,11 @@ export default {
     sections () {
       return [
         {
-          title: this.$gettext('General shortcuts'),
+          title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'General shortcuts'),
           shortcuts: [
             {
               key: 'h',
-              summary: this.$gettext('Show available keyboard shortcuts')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Show available keyboard shortcuts')
             }
           ]
         },
@@ -52,35 +52,35 @@ export default {
         // s.prevent.exact="shuffle"
 
         {
-          title: this.$gettext('Audio player shortcuts'),
+          title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'Audio player shortcuts'),
           shortcuts: [
             {
               key: 'space',
-              summary: this.$gettext('Pause/play the current track')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Pause/play the current track')
             },
             {
               key: 'ctrl left',
-              summary: this.$gettext('Play previous track')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play previous track')
             },
             {
               key: 'ctrl right',
-              summary: this.$gettext('Play next track')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play next track')
             },
             {
               key: 'ctrl up',
-              summary: this.$gettext('Increase volume')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Increase volume')
             },
             {
               key: 'ctrl down',
-              summary: this.$gettext('Decrease volume')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Decrease volume')
             },
             {
               key: 'l',
-              summary: this.$gettext('Toggle queue looping')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle queue looping')
             },
             {
               key: 's',
-              summary: this.$gettext('Shuffle queue')
+              summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Shuffle queue')
             },
           ]
         }
diff --git a/front/src/components/Sidebar.vue b/front/src/components/Sidebar.vue
index 8c44d6041b33415423eff0fe857ebebcc83838bf..8b183b215875b532c40faeff53ed547d1eb766ef 100644
--- a/front/src/components/Sidebar.vue
+++ b/front/src/components/Sidebar.vue
@@ -16,13 +16,13 @@
 
   <div class="menu-area">
     <div class="ui compact fluid two item inverted menu">
-      <a :class="[{active: selectedTab === 'library'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'library'" data-tab="library"><translate>Browse</translate></a>
+      <a :class="[{active: selectedTab === 'library'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'library'" data-tab="library"><translate translate-context="*/Library/*/Verb">Browse</translate></a>
       <a :class="[{active: selectedTab === 'queue'}, 'item']" role="button" @click.prevent.stop="selectedTab = 'queue'" data-tab="queue">
-        <translate>Queue</translate>&nbsp;
+        <translate translate-context="Sidebar/Queue/Tab.Title/Noun">Queue</translate>&nbsp;
          <template v-if="queue.tracks.length === 0">
-           <translate>(empty)</translate>
+           <translate translate-context="Sidebar/Queue/Tab.Title">(empty)</translate>
          </template>
-         <translate v-else :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}">
+         <translate translate-context="Sidebar/Queue/Tab.Title" v-else :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}">
           (%{ index } of %{ length })
          </translate>
       </a>
@@ -32,70 +32,81 @@
     <section :class="['ui', 'bottom', 'attached', {active: selectedTab === 'library'}, 'tab']" :aria-label="labels.mainMenu">
       <nav class="ui inverted vertical large fluid menu" role="navigation" :aria-label="labels.mainMenu">
         <div class="item">
-          <header class="header"><translate>My account</translate></header>
+          <header class="header"><translate translate-context="Sidebar/Profile/Title">My account</translate></header>
           <div class="menu">
             <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'profile', params: {username: $store.state.auth.username}}">
               <i class="user icon"></i>
-              <translate :translate-params="{username: $store.state.auth.username}">
+              <translate translate-context="Sidebar/Profile/List item.Link" :translate-params="{username: $store.state.auth.username}">
                 Logged in as %{ username }
               </translate>
               <img class="ui right floated circular tiny avatar image" v-if="$store.state.auth.profile.avatar.square_crop" v-lazy="$store.getters['instance/absoluteUrl']($store.state.auth.profile.avatar.square_crop)" />
             </router-link>
-            <router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/settings'}"><i class="setting icon"></i><translate>Settings</translate></router-link>
+            <router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/settings'}"><i class="setting icon"></i><translate translate-context="*/*/*/Noun">Settings</translate></router-link>
             <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'notifications'}">
               <i class="feed icon"></i>
-              <translate>Notifications</translate>
+              <translate translate-context="*/Notifications/*">Notifications</translate>
               <div
                 v-if="$store.state.ui.notifications.inbox > 0"
                 :class="['ui', 'teal', 'label']">
                 {{ $store.state.ui.notifications.inbox }}</div>
             </router-link>
-            <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'logout'}"><i class="sign out icon"></i><translate>Logout</translate></router-link>
+            <router-link class="item" v-if="$store.state.auth.authenticated" :to="{name: 'logout'}"><i class="sign out icon"></i><translate translate-context="Sidebar/Login/List item.Link/Verb">Logout</translate></router-link>
             <template v-else>
-              <router-link class="item" :to="{name: 'login'}"><i class="sign in icon"></i><translate>Login</translate></router-link>
+              <router-link class="item" :to="{name: 'login'}"><i class="sign in icon"></i><translate translate-context="*/Login/*/Verb">Login</translate></router-link>
               <router-link class="item" :to="{path: '/signup'}">
                 <i class="corner add icon"></i>
-                <translate>Create an account</translate>
+                <translate translate-context="*/Signup/Link/Verb">Create an account</translate>
               </router-link>
             </template>
           </div>
         </div>
         <div class="item">
-          <header class="header"><translate>Music</translate></header>
+          <header class="header"><translate translate-context="*/*/*/Noun">Music</translate></header>
           <div class="menu">
-            <router-link class="item" :to="{path: '/library'}"><i class="sound icon"></i><translate>Browse library</translate></router-link>
-            <router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/favorites'}"><i class="heart icon"></i><translate>Favorites</translate></router-link>
+            <router-link class="item" :to="{path: '/library'}"><i class="sound icon"></i><translate translate-context="Sidebar/Library/List item.Link/Verb">Browse library</translate></router-link>
+            <router-link class="item" v-if="$store.state.auth.authenticated" :to="{path: '/favorites'}"><i class="heart icon"></i><translate translate-context="Sidebar/Favorites/List item.Link/Noun">Favorites</translate></router-link>
             <a
               @click="$store.commit('playlists/chooseTrack', null)"
               v-if="$store.state.auth.authenticated"
               class="item">
-              <i class="list icon"></i><translate>Playlists</translate>
+              <i class="list icon"></i><translate translate-context="*/*/*">Playlists</translate>
             </a>
             <router-link
               v-if="$store.state.auth.authenticated"
-              class="item" :to="{name: 'content.index'}"><i class="upload icon"></i><translate>Add content</translate></router-link>
+              class="item" :to="{name: 'content.index'}"><i class="upload icon"></i><translate translate-context="*/Library/*/Verb">Add content</translate></router-link>
           </div>
         </div>
         <div class="item" v-if="$store.state.auth.availablePermissions['settings'] || $store.state.auth.availablePermissions['moderation']">
-          <header class="header"><translate>Administration</translate></header>
+          <header class="header"><translate translate-context="Sidebar/Admin/Title/Noun">Administration</translate></header>
           <div class="menu">
             <router-link
-              v-if="$store.state.auth.availablePermissions['settings']"
+              v-if="$store.state.auth.availablePermissions['library']"
               class="item"
-              :to="{path: '/manage/settings'}">
-              <i class="settings icon"></i><translate>Settings</translate>
+              :to="{name: 'manage.library.edits', query: {q: 'is_approved:null'}}">
+              <i class="book icon"></i><translate translate-context="*/*/*">Library</translate>
+              <div
+                v-if="$store.state.ui.notifications.pendingReviewEdits > 0"
+                :title="labels.pendingReviewEdits"
+                :class="['ui', 'teal', 'label']">
+                {{ $store.state.ui.notifications.pendingReviewEdits }}</div>
+            </router-link>
+            <router-link
+              v-if="$store.state.auth.availablePermissions['moderation']"
+              class="item"
+              :to="{name: 'manage.moderation.domains.list'}">
+              <i class="shield icon"></i><translate translate-context="*/Moderation/*">Moderation</translate>
             </router-link>
             <router-link
               v-if="$store.state.auth.availablePermissions['settings']"
               class="item"
               :to="{name: 'manage.users.users.list'}">
-              <i class="users icon"></i><translate>Users</translate>
+              <i class="users icon"></i><translate translate-context="*/*/*/Noun">Users</translate>
             </router-link>
             <router-link
-              v-if="$store.state.auth.availablePermissions['moderation']"
+              v-if="$store.state.auth.availablePermissions['settings']"
               class="item"
-              :to="{name: 'manage.moderation.domains.list'}">
-              <i class="shield icon"></i><translate>Moderation</translate>
+              :to="{path: '/manage/settings'}">
+              <i class="settings icon"></i><translate translate-context="*/*/*/Noun">Settings</translate>
             </router-link>
           </div>
         </div>
@@ -105,10 +116,10 @@
       <i class="history icon"></i>
       <div class="content">
         <div class="header">
-          <translate>Do you want to restore your previous queue?</translate>
+          <translate translate-context="Sidebar/Queue/Message">Do you want to restore your previous queue?</translate>
         </div>
         <p>
-          <translate
+          <translate translate-context="*/*/*"
             translate-plural="%{ count } tracks"
             :translate-n="queue.previousQueue.tracks.length"
             :translate-params="{count: queue.previousQueue.tracks.length}">
@@ -116,8 +127,8 @@
           </translate>
         </p>
         <div class="ui two buttons">
-          <div @click="queue.restore()" class="ui basic inverted green button"><translate>Yes</translate></div>
-          <div @click="queue.removePrevious()" class="ui basic inverted red button"><translate>No</translate></div>
+          <div @click="queue.restore()" class="ui basic inverted green button"><translate translate-context="*/*/*">Yes</translate></div>
+          <div @click="queue.removePrevious()" class="ui basic inverted red button"><translate translate-context="*/*/*">No</translate></div>
         </div>
       </div>
     </div>
@@ -158,10 +169,10 @@
       <div v-if="$store.state.radios.running" class="ui black message">
         <div class="content">
           <div class="header">
-            <i class="feed icon"></i> <translate>You have a radio playing</translate>
+            <i class="feed icon"></i> <translate translate-context="Sidebar/Player/Title">You have a radio playing</translate>
           </div>
-          <p><translate>New tracks will be appended here automatically.</translate></p>
-          <div @click="$store.dispatch('radios/stop')" class="ui basic inverted red button"><translate>Stop radio</translate></div>
+          <p><translate translate-context="Sidebar/Player/Paragraph">New tracks will be appended here automatically.</translate></p>
+          <div @click="$store.dispatch('radios/stop')" class="ui basic inverted red button"><translate translate-context="*/Player/Button.Label/Short, Verb">Stop radio</translate></div>
         </div>
       </div>
     </section>
@@ -209,13 +220,15 @@ export default {
       url: state => state.route.path
     }),
     labels() {
-      let mainMenu = this.$gettext("Main menu")
-      let selectTrack = this.$gettext("Play this track")
-      let pendingFollows = this.$gettext("Pending follow requests")
+      let mainMenu = this.$pgettext('Sidebar/*/Hidden text', "Main menu")
+      let selectTrack = this.$pgettext('Sidebar/Player/Hidden text', "Play this track")
+      let pendingFollows = this.$pgettext('Sidebar/Notifications/Hidden text', "Pending follow requests")
+      let pendingReviewEdits = this.$pgettext('Sidebar/Moderation/Hidden text', "Pending review edits")
       return {
         pendingFollows,
         mainMenu,
-        selectTrack
+        selectTrack,
+        pendingReviewEdits
       }
     },
     tracks: {
@@ -261,6 +274,29 @@ export default {
           ? 0
           : container.clientHeight / 2
       container.scrollTop = container.scrollTop - scrollBack
+    },
+    applyContentFilters () {
+      let artistIds = this.$store.getters['moderation/artistFilters']().map((f) => {
+        return f.target.id
+      })
+
+      if (artistIds.length === 0) {
+        return
+      }
+      let self = this
+      let tracks = this.tracks.slice().reverse()
+      tracks.forEach(async (t, i) => {
+        // we loop from the end because removing index from the start can lead to removing the wrong tracks
+        let realIndex = tracks.length - i - 1
+        let matchArtist = artistIds.indexOf(t.artist.id) > -1
+        if (matchArtist) {
+          return await self.cleanTrack(realIndex)
+        }
+        if (t.album && artistIds.indexOf(t.album.artist.id) > -1) {
+          return await self.cleanTrack(realIndex)
+        }
+      })
+
     }
   },
   watch: {
@@ -276,6 +312,9 @@ export default {
       if (this.selectedTab !== "queue") {
         this.scrollToCurrent()
       }
+    },
+    "$store.state.moderation.lastUpdate": function () {
+      this.applyContentFilters()
     }
   }
 }
diff --git a/front/src/components/admin/SettingsGroup.vue b/front/src/components/admin/SettingsGroup.vue
index 85bb9eeaee5243a60d4841c264ea8947f9918fce..0c0774bbe1055f9baf771246c2c00a8b56994307 100644
--- a/front/src/components/admin/SettingsGroup.vue
+++ b/front/src/components/admin/SettingsGroup.vue
@@ -3,13 +3,13 @@
     <div class="ui divider" />
     <h3 class="ui header">{{ group.label }}</h3>
     <div v-if="errors.length > 0" class="ui negative message">
-      <div class="header"><translate>Error while saving settings</translate></div>
+      <div class="header"><translate translate-context="Content/Settings/Error message.Title">Error while saving settings</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
     </div>
     <div v-if="result" class="ui positive message">
-      <translate>Settings updated successfully.</translate>
+      <translate translate-context="Content/Settings/Paragraph">Settings updated successfully.</translate>
     </div>
     <p v-if="group.help">{{ group.help }}</p>
     <div v-for="setting in settings" class="ui field">
@@ -65,7 +65,7 @@
     <button
       type="submit"
       :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']">
-        <translate>Save</translate>
+        <translate translate-context="Content/*/Button.Label/Verb">Save</translate>
     </button>
   </form>
 </template>
diff --git a/front/src/components/audio/EmbedWizard.vue b/front/src/components/audio/EmbedWizard.vue
index 7a50ffa54223a189d40cd91fbbe9f0e41b0814ee..e4412937e54e542a684381656a0810cf4c924b9b 100644
--- a/front/src/components/audio/EmbedWizard.vue
+++ b/front/src/components/audio/EmbedWizard.vue
@@ -4,30 +4,36 @@
       <div class="two fields">
         <div class="field">
           <div class="field">
-            <label for="embed-width"><translate>Widget width</translate></label>
-            <p><translate>Leave empty for a responsive widget</translate></p>
+            <label for="embed-width"><translate translate-context="Popup/Embed/Input.Label">Widget width</translate></label>
+            <p><translate translate-context="Popup/Embed/Paragraph">Leave empty for a responsive widget</translate></p>
             <input id="embed-width" type="number" v-model.number="width" min="0" step="10" />
           </div>
           <template v-if="type != 'track'">
             <br>
             <div class="field">
-              <label for="embed-height"><translate>Widget height</translate></label>
+              <label for="embed-height"><translate translate-context="Popup/Embed/Input.Label">Widget height</translate></label>
               <input id="embed-height" type="number" v-model="height" :min="minHeight" max="1000" step="10" />
             </div>
           </template>
         </div>
         <div class="field">
-          <button @click="copy" class="ui right floated button"><translate>Copy</translate></button>
-          <label for="embed-width"><translate>Embed code</translate></label>
-          <p><translate>Copy/paste this code in your website HTML</translate></p>
-          <div class="ui hidden divider"></div>
-          <textarea ref="textarea":value="embedCode" rows="3" readonly>
+          <button @click="copy" class="ui right teal labeled icon floated button"><i class="copy icon"></i><translate translate-context="*/*/Button.Label/Short, Verb">Copy</translate></button>
+          <label for="embed-width"><translate translate-context="Popup/Embed/Input.Label/Noun">Embed code</translate></label>
+          <p><translate translate-context="Popup/Embed/Paragraph">Copy/paste this code in your website HTML</translate></p>
+          <textarea ref="textarea":value="embedCode" rows="5" readonly>
           </textarea>
+          <div class="ui right">
+          <p class="message" v-if=copied><translate translate-context="Content/*/Paragraph">Text copied to clipboard!</translate></p>
+          </div>
         </div>
       </div>
     </div>
     <div class="preview">
-      <h3><translate>Preview</translate></h3>
+      <h3>
+        <a :href="iframeSrc" target="_blank">
+          <translate translate-context="Popup/Embed/Title/Noun">Preview</translate>
+        </a>
+      </h3>
       <iframe :width="frameWidth" :height="height" scrolling="no" frameborder="no" :src="iframeSrc"></iframe>
     </div>
   </div>
@@ -41,7 +47,8 @@ export default {
     let d = {
       width: null,
       height: 150,
-      minHeight: 100
+      minHeight: 100,
+      copied: false
     }
     if (this.type === 'album') {
       d.height = 330
@@ -70,6 +77,11 @@ export default {
     copy () {
       this.$refs.textarea.select()
       document.execCommand("Copy")
+      let self = this
+      self.copied = true
+      this.timeout = setTimeout(() => {
+        self.copied = false
+      }, 5000)
     }
   }
 }
@@ -77,4 +89,9 @@ export default {
 
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped>
+.message {
+  position: absolute;
+  right: 0;
+  bottom: -2em;
+}
 </style>
diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue
index d438a14a02b412156accdf2a45c385defa0e42f3..c1eeeedd47b30c308fee7bbba6861e1942d1d00f 100644
--- a/front/src/components/audio/PlayButton.vue
+++ b/front/src/components/audio/PlayButton.vue
@@ -1,5 +1,5 @@
 <template>
-  <span :title="title" :class="['ui', {'tiny': discrete}, {'buttons': !dropdownOnly && !iconOnly}]">
+  <span :title="title" :class="['ui', {'tiny': discrete}, {'icon': !discrete}, {'buttons': !dropdownOnly && !iconOnly}]">
     <button
       v-if="!dropdownOnly"
       :title="labels.playNow"
@@ -7,14 +7,25 @@
       :disabled="!playable"
       :class="buttonClasses.concat(['ui', {loading: isLoading}, {'mini': discrete}, {disabled: !playable}])">
       <i :class="[playIconClass, 'icon']"></i>
-      <template v-if="!discrete && !iconOnly"><slot><translate>Play</translate></slot></template>
+      <template v-if="!discrete && !iconOnly"><slot><translate translate-context="*/Queue/Button.Label/Short, Verb">Play</translate></slot></template>
     </button>
-    <div v-if="!discrete && !iconOnly" :class="['ui', {disabled: !playable}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]">
-      <i :class="dropdownIconClasses.concat(['icon'])"></i>
+    <div v-if="!discrete && !iconOnly" :class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]">
+      <i :class="dropdownIconClasses.concat(['icon'])" :title="title" ></i>
       <div class="menu">
-        <button class="item basic" ref="add" data-ref="add" :disabled="!playable" @click.stop.prevent="add" :title="labels.addToQueue"><i class="plus icon"></i><translate>Add to queue</translate></button>
-        <button class="item basic" ref="addNext" data-ref="addNext" :disabled="!playable" @click.stop.prevent="addNext()" :title="labels.playNext"><i class="step forward icon"></i><translate>Play next</translate></button>
-        <button class="item basic" ref="playNow" data-ref="playNow" :disabled="!playable" @click.stop.prevent="addNext(true)" :title="labels.playNow"><i class="play icon"></i><translate>Play now</translate></button>
+        <button class="item basic" ref="add" data-ref="add" :disabled="!playable" @click.stop.prevent="add" :title="labels.addToQueue">
+          <i class="plus icon"></i><translate translate-context="*/Queue/Dropdown/Button/Label/Short">Add to queue</translate>
+        </button>
+        <button class="item basic" ref="addNext" data-ref="addNext" :disabled="!playable" @click.stop.prevent="addNext()" :title="labels.playNext">
+          <i class="step forward icon"></i>{{ labels.playNext }}
+        </button>
+        <button class="item basic" ref="playNow" data-ref="playNow" :disabled="!playable" @click.stop.prevent="addNext(true)" :title="labels.playNow">
+          <i class="play icon"></i>{{ labels.playNow }}</button>
+        <button v-if="track" class="item basic" :disabled="!playable" @click.stop.prevent="$store.dispatch('radios/start', {type: 'similar', objectId: track.id})" :title="labels.startRadio">
+          <i class="feed icon"></i><translate translate-context="*/Queue/Button.Label/Short, Verb">Start radio</translate>
+        </button>
+        <button v-if="filterableArtist" class="item basic" :disabled="!filterableArtist" @click.stop.prevent="filterArtist" :title="labels.hideArtist">
+          <i class="eye slash outline icon"></i><translate translate-context="*/Queue/Dropdown/Button/Label/Short">Hide content from this artist</translate>
+        </button>
       </div>
     </div>
   </span>
@@ -36,13 +47,13 @@ export default {
     discrete: {type: Boolean, default: false},
     dropdownOnly: {type: Boolean, default: false},
     iconOnly: {type: Boolean, default: false},
-    artist: {type: Number, required: false},
-    album: {type: Number, required: false},
+    artist: {type: Object, required: false},
+    album: {type: Object, required: false},
     isPlayable: {type: Boolean, required: false, default: null}
   },
   data () {
     return {
-      isLoading: false
+      isLoading: false,
     }
   },
   mounted () {
@@ -60,17 +71,18 @@ export default {
   computed: {
     labels () {
       return {
-        playNow: this.$gettext('Play now'),
-        addToQueue: this.$gettext('Add to current queue'),
-        playNext: this.$gettext('Play next')
+        playNow: this.$pgettext('*/Queue/Dropdown/Button/Title', 'Play now'),
+        addToQueue: this.$pgettext('*/Queue/Dropdown/Button/Title', 'Add to current queue'),
+        playNext: this.$pgettext('*/Queue/Dropdown/Button/Title', 'Play next'),
+        startRadio: this.$pgettext('*/Queue/Dropdown/Button/Title', 'Play similar songs')
       }
     },
     title () {
       if (this.playable) {
-        return this.$gettext('Play...')
+        return this.$pgettext('*/Queue/Button/Title', 'Play...')
       } else {
         if (this.track) {
-          return this.$gettext('This track is not available in any library you have access to')
+          return this.$pgettext('*/Queue/Button/Title', 'This track is not available in any library you have access to')
         }
       }
     },
@@ -81,7 +93,7 @@ export default {
       if (this.track) {
         return this.track.uploads && this.track.uploads.length > 0
       } else if (this.artist) {
-        return this.albums.filter((a) => {
+        return this.artist.albums.filter((a) => {
           return a.is_playable === true
         }).length > 0
       } else if (this.tracks) {
@@ -90,9 +102,24 @@ export default {
         }).length > 0
       }
       return false
+    },
+    filterableArtist () {
+      if (this.track) {
+        return this.track.artist
+      }
+      if (this.album) {
+        return this.album.artist
+      }
+      if (this.artist) {
+        return this.artist
+      }
     }
   },
   methods: {
+
+    filterArtist () {
+      this.$store.dispatch('moderation/hide', {type: 'artist', target: this.filterableArtist})
+    },
     getTracksPage (page, params, resolve, tracks) {
       if (page > 10) {
         // it's 10 * 100 tracks already, let's stop here
@@ -103,6 +130,7 @@ export default {
       let self = this
       params['page_size'] = 100
       params['page'] = page
+      params['hidden'] = ''
       tracks = tracks || []
       axios.get('tracks/', {params: params}).then((response) => {
         response.data.results.forEach(t => {
@@ -133,15 +161,27 @@ export default {
         } else if (self.playlist) {
           let url = 'playlists/' + self.playlist.id + '/'
           axios.get(url + 'tracks/').then((response) => {
-            resolve(response.data.results.map(plt => {
+            let artistIds = self.$store.getters['moderation/artistFilters']().map((f) => {
+              return f.target.id
+            })
+            let tracks = response.data.results.map(plt => {
               return plt.track
-            }))
+            })
+            if (artistIds.length > 0) {
+              // skip tracks from hidden artists
+              tracks = tracks.filter((t) => {
+                let matchArtist = artistIds.indexOf(t.artist.id) > -1
+                return !(matchArtist || t.album && artistIds.indexOf(t.album.artist.id) > -1)
+              })
+            }
+
+            resolve(tracks)
           })
         } else if (self.artist) {
-          let params = {'artist': self.artist, 'ordering': 'album__release_date,position'}
+          let params = {'artist': self.artist.id, 'ordering': 'album__release_date,position'}
           self.getTracksPage(1, params, resolve)
         } else if (self.album) {
-          let params = {'album': self.album, 'ordering': 'position'}
+          let params = {'album': self.album.id, 'ordering': 'position'}
           self.getTracksPage(1, params, resolve)
         }
       })
@@ -177,12 +217,12 @@ export default {
       if (tracks.length < 1) {
         return
       }
-      let msg = this.$ngettext('%{ count } track was added to your queue', '%{ count } tracks were added to your queue', tracks.length)
+      let msg = this.$npgettext('*/Queue/Message', '%{ count } track was added to your queue', '%{ count } tracks were added to your queue', tracks.length)
       this.$store.commit('ui/addMessage', {
         content: this.$gettextInterpolate(msg, {count: tracks.length}),
         date: new Date()
       })
-    }
+    },
   }
 }
 </script>
diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue
index 575f6873662aa851bc83cd623226ff5259c88329..ea15ebc8720db69b7b0ccb69319329afdbf4e94a 100644
--- a/front/src/components/audio/Player.vue
+++ b/front/src/components/audio/Player.vue
@@ -1,16 +1,6 @@
 <template>
   <section class="ui inverted segment player-wrapper" :aria-label="labels.audioPlayer" :style="style">
     <div class="player">
-      <audio-track
-        ref="currentAudio"
-        v-if="currentTrack"
-        @errored="handleError"
-        :is-current="true"
-        :start-time="$store.state.player.currentTime"
-        :autoplay="$store.state.player.playing"
-        :key="audioKey"
-        :track="currentTrack">
-      </audio-track>
       <div v-if="currentTrack" class="track-area ui unstackable items">
         <div class="ui inverted item">
           <div class="ui tiny image">
@@ -38,6 +28,14 @@
                 v-if="$store.state.auth.authenticated"
                 :class="['inverted']"
                 :track="currentTrack"></track-playlist-icon>
+              <button
+                v-if="$store.state.auth.authenticated"
+                @click="$store.dispatch('moderation/hide', {type: 'artist', target: currentTrack.artist})"
+                :class="['ui', 'really', 'basic', 'circular', 'inverted', 'icon', 'button']"
+                :aria-label="labels.addArtistContentFilter"
+                :title="labels.addArtistContentFilter">
+                <i :class="['eye slash outline', 'basic', 'icon']"></i>
+              </button>
             </div>
           </div>
         </div>
@@ -45,7 +43,7 @@
       <div class="progress-area" v-if="currentTrack && !errored">
         <div class="ui grid">
           <div class="left floated four wide column">
-            <p class="timer start" @click="updateProgress(0)">{{currentTimeFormatted}}</p>
+            <p class="timer start" @click="setCurrentTime(0)">{{currentTimeFormatted}}</p>
           </div>
 
           <div v-if="!isLoadingAudio" class="right floated four wide column">
@@ -62,14 +60,14 @@
       </div>
       <div class="ui small warning message" v-if="currentTrack && errored">
         <div class="header">
-          <translate>We cannot load this track</translate>
+          <translate translate-context="Sidebar/Player/Error message.Title">The track cannot be loaded</translate>
         </div>
         <p v-if="hasNext && playing && $store.state.player.errorCount < $store.state.player.maxConsecutiveErrors">
-          <translate>The next track will play automatically in a few seconds…</translate>
+          <translate translate-context="Sidebar/Player/Error message.Paragraph">The next track will play automatically in a few seconds…</translate>
           <i class="loading spinner icon"></i>
         </p>
         <p>
-          <translate>You may have a connectivity issue.</translate>
+          <translate translate-context="Sidebar/Player/Error message.Paragraph">You may have a connectivity issue.</translate>
         </p>
       </div>
       <div class="two wide column controls ui grid">
@@ -200,7 +198,11 @@
           v-if="!showVolume"
           @click.prevent.stop="clean()"
           class="two wide column control">
-          <i :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
+          <i class="icons">
+
+            <i :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
+            <i :class="['ui corner large inverted', 'list', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
+          </i>
         </span>
       </div>
       <GlobalEvents
@@ -222,8 +224,10 @@ import GlobalEvents from "@/components/utils/global-events"
 import ColorThief from "@/vendor/color-thief"
 import { Howl } from "howler"
 import $ from 'jquery'
+import _ from '@/lodash'
+import url from '@/utils/url'
+import axios from 'axios'
 
-import AudioTrack from "@/components/audio/Track"
 import TrackFavoriteIcon from "@/components/favorites/TrackFavoriteIcon"
 import TrackPlaylistIcon from "@/components/playlists/TrackPlaylistIcon"
 
@@ -232,7 +236,6 @@ export default {
     TrackFavoriteIcon,
     TrackPlaylistIcon,
     GlobalEvents,
-    AudioTrack
   },
   data() {
     let defaultAmbiantColors = [
@@ -247,11 +250,25 @@ export default {
       defaultAmbiantColors: defaultAmbiantColors,
       showVolume: false,
       ambiantColors: defaultAmbiantColors,
-      audioKey: String(new Date()),
-      dummyAudio: null
+      currentSound: null,
+      dummyAudio: null,
+      isUpdatingTime: false,
+      sourceErrors: 0,
+      progressInterval: null,
+      maxPreloaded: 3,
+      preloadDelay: 15,
+      soundsCache: [],
+      soundId: null,
+      playTimeout: null,
+      nextTrackPreloaded: false
     }
   },
   mounted() {
+    this.$store.dispatch('player/updateProgress', 0)
+    this.$store.commit('player/playing', false)
+    this.$store.commit("player/isLoadingAudio", false)
+    Howler.unload()  // clear existing cache, if any
+    this.nextTrackPreloaded = false
     // we trigger the watcher explicitely it does not work otherwise
     this.sliderVolume = this.volume
     // this is needed to unlock audio playing under some browsers,
@@ -262,9 +279,15 @@ export default {
       autoplay: false,
       src: ["noop.webm", "noop.mp3"]
     })
+    if (this.currentTrack) {
+      this.getSound(this.currentTrack)
+    }
   },
-  destroyed() {
+  beforeDestroy () {
     this.dummyAudio.unload()
+    this.observeProgress(false)
+  },
+  destroyed() {
   },
   methods: {
     ...mapActions({
@@ -272,15 +295,31 @@ export default {
       mute: "player/mute",
       unmute: "player/unmute",
       clean: "queue/clean",
-      updateProgress: "player/updateProgress"
     }),
+    async getTrackData (trackData) {
+      let data = null
+      if (!trackData.uploads.length || trackData.uploads.length === 0) {
+        // we don't have upload informations for this track, we need to fetch it
+        await axios.get(`tracks/${trackData.id}/`).then((response) => {
+          data = response.data
+        }, error => {
+          data = null
+        })
+      } else {
+        return trackData
+      }
+      if (data === null) {
+        return
+      }
+      return data
+    },
     shuffle() {
       let disabled = this.queue.tracks.length === 0
       if (this.isShuffling || disabled) {
         return
       }
       let self = this
-      let msg = this.$gettext("Queue shuffled!")
+      let msg = this.$pgettext('Content/Queue/Message', "Queue shuffled!")
       this.isShuffling = true
       setTimeout(() => {
         self.$store.dispatch("queue/shuffle", () => {
@@ -308,7 +347,7 @@ export default {
       let time
       let target = this.$refs.progress
       time = (e.layerX / target.offsetWidth) * this.duration
-      this.$refs.currentAudio.setCurrentTime(time)
+      this.setCurrentTime(time)
     },
     updateBackground() {
       // delete existing canvas, if any
@@ -323,6 +362,239 @@ export default {
     handleError({ sound, error }) {
       this.$store.commit("player/isLoadingAudio", false)
       this.$store.dispatch("player/trackErrored")
+    },
+    getSound (trackData) {
+      let cached = this.getSoundFromCache(trackData)
+      if (cached) {
+        return cached.sound
+      }
+      let srcs = this.getSrcs(trackData)
+      let self = this
+      let sound = new Howl({
+        src: srcs.map((s) => { return s.url }),
+        format: srcs.map((s) => { return s.type }),
+        autoplay: false,
+        loop: false,
+        html5: true,
+        preload: true,
+        volume: this.volume,
+        onend: function () {
+          self.ended()
+        },
+        onunlock: function () {
+          if (this.$store.state.player.playing) {
+            self.soundId = self.sound.play(self.soundId)
+          }
+        },
+        onload: function () {
+          let sound = this
+          let node = this._sounds[0]._node;
+          node.addEventListener('progress', () => {
+            if (sound != self.currentSound) {
+              return
+            }
+            self.updateBuffer(node)
+          })
+        },
+        onplay: function () {
+          self.$store.commit('player/isLoadingAudio', false)
+          self.$store.commit('player/resetErrorCount')
+          self.$store.commit('player/errored', false)
+          self.$store.commit('player/duration', this.duration())
+        },
+        onloaderror: function (sound, error) {
+          self.removeFromCache(this)
+          if (this != self.currentSound) {
+            return
+          }
+          console.log('Error while playing:', sound, error)
+          self.handleError({sound, error})
+        },
+      })
+      this.addSoundToCache(sound, trackData)
+      return sound
+    },
+    getSrcs: function (trackData) {
+      let sources = trackData.uploads.map(u => {
+        return {
+          type: u.extension,
+          url: this.$store.getters['instance/absoluteUrl'](u.listen_url),
+        }
+      })
+      // We always add a transcoded MP3 src at the end
+      // because transcoding is expensive, but we want browsers that do
+      // not support other codecs to be able to play it :)
+      sources.push({
+        type: 'mp3',
+        url: url.updateQueryString(
+          this.$store.getters['instance/absoluteUrl'](trackData.listen_url),
+          'to',
+          'mp3'
+        )
+      })
+      if (this.$store.state.auth.authenticated) {
+        // we need to send the token directly in url
+        // so authentication can be checked by the backend
+        // because for audio files we cannot use the regular Authentication
+        // header
+        sources.forEach(e => {
+          e.url = url.updateQueryString(e.url, 'jwt', this.$store.state.auth.token)
+        })
+      }
+      return sources
+    },
+
+    updateBuffer (node) {
+      // from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
+      let range = 0;
+      let bf = node.buffered;
+      let time = node.currentTime;
+      try {
+        while(!(bf.start(range) <= time && time <= bf.end(range))) {
+          range += 1;
+        }
+      } catch (IndexSizeError) {
+        return
+      }
+      let loadPercentage
+      let start =  bf.start(range)
+      let end =  bf.end(range)
+      if (range === 0) {
+        // easy case, no user-seek
+        let loadStartPercentage = start / node.duration;
+        let loadEndPercentage = end / node.duration;
+        loadPercentage = loadEndPercentage - loadStartPercentage;
+      } else {
+        let loaded = end - start
+        let remainingToLoad = node.duration - start
+        // user seeked a specific position in the audio, our progress must be
+        // computed based on the remaining portion of the track
+        loadPercentage = loaded / remainingToLoad;
+      }
+      if (loadPercentage * 100 === this.bufferProgress) {
+        return
+      }
+      this.$store.commit('player/bufferProgress', loadPercentage * 100)
+    },
+    updateProgress: function () {
+      this.isUpdatingTime = true
+      if (this.currentSound && this.currentSound.state() === 'loaded') {
+        let t = this.currentSound.seek()
+        let d = this.currentSound.duration()
+        this.$store.dispatch('player/updateProgress', t)
+        this.updateBuffer(this.currentSound._sounds[0]._node)
+        let toPreload = this.$store.state.queue.tracks[this.currentIndex + 1]
+        if (!this.nextTrackPreloaded && toPreload && !this.getSoundFromCache(toPreload) && (t > this.preloadDelay || d - t < 30)) {
+          this.getSound(toPreload)
+          this.nextTrackPreloaded = true
+        }
+      }
+    },
+    observeProgress: function (enable) {
+      let self = this
+      if (enable) {
+        if (self.progressInterval) {
+          clearInterval(self.progressInterval)
+        }
+        self.progressInterval = setInterval(() => {
+          self.updateProgress()
+        }, 1000)
+      } else {
+        clearInterval(self.progressInterval)
+      }
+    },
+    setCurrentTime (t) {
+      if (t < 0 | t > this.duration) {
+        return
+      }
+      if (!this.currentSound || !this.currentSound._sounds[0]) {
+        return
+      }
+      if (t === this.currentSound.seek()) {
+        return
+      }
+      if (t === 0) {
+        this.updateProgressThrottled.cancel()
+      }
+      this.currentSound.seek(t)
+    },
+    ended: function () {
+      let onlyTrack = this.$store.state.queue.tracks.length === 1
+      if (this.looping === 1 || (onlyTrack && this.looping === 2)) {
+        this.currentSound.seek(0)
+        this.$store.dispatch('player/updateProgress', 0)
+        this.soundId = this.currentSound.play(this.soundId)
+      } else {
+        this.$store.dispatch('player/trackEnded', this.currentTrack)
+      }
+    },
+    getSoundFromCache (trackData) {
+      return this.soundsCache.filter((d) => {
+        if (d.track.id !== trackData.id) {
+          return false
+        }
+
+        return true
+      })[0]
+    },
+    addSoundToCache (sound, trackData) {
+      let data = {
+        date: new Date(),
+        track: trackData,
+        sound: sound
+      }
+      this.soundsCache.push(data)
+      this.checkCache()
+    },
+    checkCache () {
+      let self = this
+      let toKeep = []
+      _.reverse(this.soundsCache).forEach((e) => {
+        if (toKeep.length < self.maxPreloaded) {
+          toKeep.push(e)
+        } else {
+          let src = e.sound._src
+          e.sound.unload()
+        }
+      })
+      this.soundsCache = _.reverse(toKeep)
+    },
+    removeFromCache (sound) {
+      let toKeep = []
+      this.soundsCache.forEach((e) => {
+        if (e.sound === sound) {
+          e.sound.unload()
+        } else {
+          toKeep.push(e)
+        }
+      })
+      this.soundsCache = toKeep
+    },
+    async loadSound (newValue, oldValue) {
+      let trackData = newValue
+      let oldSound = this.currentSound
+      if (oldSound && trackData !== oldValue) {
+        oldSound.stop(this.soundId)
+        this.soundId = null
+      }
+      if (!trackData) {
+        return
+      }
+      if (!this.isShuffling && trackData != oldValue) {
+        trackData = await this.getTrackData(trackData)
+        if (trackData === null) {
+          this.handleError({})
+        }
+        this.currentSound = this.getSound(trackData)
+        this.$store.commit('player/isLoadingAudio', true)
+        if (this.playing) {
+          this.soundId = this.currentSound.play()
+          this.$store.commit('player/errored', false)
+          this.$store.commit('player/playing', true)
+          this.$store.dispatch('player/updateProgress', 0)
+          this.observeProgress(true)
+        }
+      }
     }
   },
   computed: {
@@ -335,6 +607,7 @@ export default {
       duration: state => state.player.duration,
       bufferProgress: state => state.player.bufferProgress,
       errored: state => state.player.errored,
+      currentTime: state => state.player.currentTime,
       queue: state => state.queue
     }),
     ...mapGetters({
@@ -345,25 +618,29 @@ export default {
       currentTimeFormatted: "player/currentTimeFormatted",
       progress: "player/progress"
     }),
+    updateProgressThrottled () {
+      return _.throttle(this.updateProgress, 250)
+    },
     labels() {
-      let audioPlayer = this.$gettext("Media player")
-      let previousTrack = this.$gettext("Previous track")
-      let play = this.$gettext("Play track")
-      let pause = this.$gettext("Pause track")
-      let next = this.$gettext("Next track")
-      let unmute = this.$gettext("Unmute")
-      let mute = this.$gettext("Mute")
-      let loopingDisabled = this.$gettext(
+      let audioPlayer = this.$pgettext('Sidebar/Player/Hidden text', "Media player")
+      let previousTrack = this.$pgettext('Sidebar/Player/Icon.Tooltip', "Previous track")
+      let play = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', "Play track")
+      let pause = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', "Pause track")
+      let next = this.$pgettext('Sidebar/Player/Icon.Tooltip', "Next track")
+      let unmute = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', "Unmute")
+      let mute = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', "Mute")
+      let loopingDisabled = this.$pgettext('Sidebar/Player/Icon.Tooltip',
         "Looping disabled. Click to switch to single-track looping."
       )
-      let loopingSingle = this.$gettext(
+      let loopingSingle = this.$pgettext('Sidebar/Player/Icon.Tooltip',
         "Looping on a single track. Click to switch to whole queue looping."
       )
-      let loopingWhole = this.$gettext(
+      let loopingWhole = this.$pgettext('Sidebar/Player/Icon.Tooltip',
         "Looping on whole queue. Click to disable looping."
       )
-      let shuffle = this.$gettext("Shuffle your queue")
-      let clear = this.$gettext("Clear your queue")
+      let shuffle = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', "Shuffle your queue")
+      let clear = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', "Clear your queue")
+      let addArtistContentFilter = this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Hide content from this artist…')
       return {
         audioPlayer,
         previousTrack,
@@ -376,7 +653,8 @@ export default {
         loopingSingle,
         loopingWhole,
         shuffle,
-        clear
+        clear,
+        addArtistContentFilter,
       }
     },
     style: function() {
@@ -404,22 +682,62 @@ export default {
         })
         .join(", ")
       return gradients
-    }
+    },
   },
   watch: {
-    currentTrack(newValue, oldValue) {
-      if (!this.isShuffling && newValue != oldValue) {
-        this.audioKey = String(new Date())
-      }
-      if (!newValue || !newValue.album.cover) {
-        this.ambiantColors = this.defaultAmbiantColors
-      }
+    currentTrack: {
+      async handler (newValue, oldValue) {
+        if (newValue === oldValue) {
+          return
+        }
+        this.nextTrackPreloaded = false
+        clearTimeout(this.playTimeout)
+        let self = this
+        if (this.currentSound) {
+          this.currentSound.pause()
+        }
+        this.$store.commit("player/isLoadingAudio", true)
+        this.playTimeout = setTimeout(async () => {
+          await self.loadSound(newValue, oldValue)
+          if (!newValue || !newValue.album.cover) {
+            self.ambiantColors = self.defaultAmbiantColors
+          }
+        }, 500);
+      },
+      immediate: false
     },
     volume(newValue) {
       this.sliderVolume = newValue
+      if (this.currentSound) {
+        this.currentSound.volume(newValue)
+      }
     },
     sliderVolume(newValue) {
       this.$store.commit("player/volume", newValue)
+    },
+    playing: async function (newValue) {
+      if (this.currentSound) {
+        if (newValue === true) {
+          this.soundId = this.currentSound.play(this.soundId)
+        } else {
+          this.currentSound.pause(this.soundId)
+        }
+      } else {
+        await this.loadSound(this.currentTrack, null)
+      }
+
+      this.observeProgress(newValue)
+    },
+    currentTime (newValue) {
+      if (!this.isUpdatingTime) {
+        this.setCurrentTime(newValue)
+      }
+      this.isUpdatingTime = false
+    },
+    emptyQueue (newValue) {
+      if (newValue) {
+        Howler.unload()
+      }
     }
   }
 }
@@ -491,6 +809,7 @@ export default {
     bottom: 1.1rem;
     left: 25%;
     cursor: pointer;
+    background-color: transparent;
   }
   input[type="range"]:focus {
     outline: none;
@@ -607,4 +926,8 @@ export default {
   animation-timing-function: linear;
   animation-iteration-count: infinite;
 }
+i.icons .corner.icon {
+  font-size: 1em;
+  right: -0.3em;
+}
 </style>
diff --git a/front/src/components/audio/Search.vue b/front/src/components/audio/Search.vue
index 307ca878f88061f038722b53a800489d8aa95ceb..40dbe403d4a2d8b95ae515498521a12b1cd8b041 100644
--- a/front/src/components/audio/Search.vue
+++ b/front/src/components/audio/Search.vue
@@ -1,6 +1,6 @@
 <template>
   <div>
-    <h2><translate>Search for some music</translate></h2>
+    <h2><translate translate-context="Content/Search/Title">Search for some music</translate></h2>
     <div :class="['ui', {'loading': isLoading }, 'search']">
       <div class="ui icon big input">
         <i class="search icon"></i>
@@ -8,22 +8,22 @@
       </div>
     </div>
     <template v-if="query.length > 0">
-      <h3 class="ui title"><translate>Artists</translate></h3>
+      <h3 class="ui title"><translate translate-context="*/*/*/Noun">Artists</translate></h3>
       <div v-if="results.artists.length > 0">
         <div class="ui cards">
           <artist-card :key="artist.id" v-for="artist in results.artists" :artist="artist" ></artist-card>
         </div>
       </div>
-      <p v-else><translate>No artist matched your query</translate></p>
+      <p v-else><translate translate-context="Content/Search/Paragraph">No artist matched your query</translate></p>
     </template>
     <template v-if="query.length > 0">
-      <h3 class="ui title"><translate>Albums</translate></h3>
+      <h3 class="ui title"><translate translate-context="*/*/*">Albums</translate></h3>
       <div v-if="results.albums.length > 0" class="ui stackable three column grid">
         <div class="column" :key="album.id" v-for="album in results.albums">
           <album-card class="fluid" :album="album" ></album-card>
         </div>
       </div>
-      <p v-else><translate>No album matched your query</translate></p>
+      <p v-else><translate translate-context="Content/Search/Paragraph">No album matched your query</translate></p>
     </template>
   </div>
 </template>
@@ -62,7 +62,7 @@ export default {
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Artist, album, track…')
+        searchPlaceholder: this.$pgettext('*/Search/Input.Placeholder', 'Artist, album, track…')
       }
     }
   },
diff --git a/front/src/components/audio/SearchBar.vue b/front/src/components/audio/SearchBar.vue
index 534ac0ac4f3862170a9b2a649a1746bba783cb0e..28b11b040d19dec5832cd5eb44971fd0e3a9b764 100644
--- a/front/src/components/audio/SearchBar.vue
+++ b/front/src/components/audio/SearchBar.vue
@@ -17,14 +17,14 @@ export default {
   computed: {
     labels () {
       return {
-        placeholder: this.$gettext('Search for artists, albums, tracks…')
+        placeholder: this.$pgettext('Sidebar/Search/Input.Placeholder', 'Search for artists, albums, tracks…')
       }
     }
   },
   mounted () {
-    let artistLabel = this.$gettext('Artist')
-    let albumLabel = this.$gettext('Album')
-    let trackLabel = this.$gettext('Track')
+    let artistLabel = this.$pgettext('*/*/*/Noun', 'Artist')
+    let albumLabel = this.$pgettext('*/*/*', 'Album')
+    let trackLabel = this.$pgettext('*/*/*/Noun', 'Track')
     let self = this
     jQuery(this.$el).search({
       type: 'category',
diff --git a/front/src/components/audio/Track.vue b/front/src/components/audio/Track.vue
deleted file mode 100644
index 2e0f8c421a0e780247224b93764b55fd476ae541..0000000000000000000000000000000000000000
--- a/front/src/components/audio/Track.vue
+++ /dev/null
@@ -1,225 +0,0 @@
-<template>
-  <i />
-</template>
-
-<script>
-import {mapState} from 'vuex'
-import _ from '@/lodash'
-import url from '@/utils/url'
-import {Howl} from 'howler'
-import axios from 'axios'
-
-// import logger from '@/logging'
-
-export default {
-  props: {
-    track: {type: Object},
-    isCurrent: {type: Boolean, default: false},
-    startTime: {type: Number, default: 0},
-    autoplay: {type: Boolean, default: false}
-  },
-  data () {
-    return {
-      trackData: this.track,
-      sourceErrors: 0,
-      sound: null,
-      isUpdatingTime: false,
-      progressInterval: null
-    }
-  },
-  mounted () {
-    let self = this
-    if (!this.trackData.uploads.length || this.trackData.uploads.length === 0) {
-      // we don't have upload informations for this track, we need to fetch it
-      axios.get(`tracks/${this.trackData.id}/`).then((response) => {
-        self.trackData = response.data
-        self.setupSound()
-      }, error => {
-        self.$emit('errored', {})
-      })
-    } else {
-      this.setupSound()
-    }
-  },
-  destroyed () {
-    this.observeProgress(false)
-    this.sound.unload()
-  },
-  computed: {
-    ...mapState({
-      playing: state => state.player.playing,
-      currentTime: state => state.player.currentTime,
-      duration: state => state.player.duration,
-      volume: state => state.player.volume,
-      looping: state => state.player.looping
-    }),
-    srcs: function () {
-      let sources = this.trackData.uploads.map(u => {
-        return {
-          type: u.extension,
-          url: this.$store.getters['instance/absoluteUrl'](u.listen_url),
-        }
-      })
-      // We always add a transcoded MP3 src at the end
-      // because transcoding is expensive, but we want browsers that do
-      // not support other codecs to be able to play it :)
-      sources.push({
-        type: 'mp3',
-        url: url.updateQueryString(
-          this.$store.getters['instance/absoluteUrl'](this.trackData.listen_url),
-          'to',
-          'mp3'
-        )
-      })
-      if (this.$store.state.auth.authenticated) {
-        // we need to send the token directly in url
-        // so authentication can be checked by the backend
-        // because for audio files we cannot use the regular Authentication
-        // header
-        sources.forEach(e => {
-          e.url = url.updateQueryString(e.url, 'jwt', this.$store.state.auth.token)
-        })
-      }
-      return sources
-    },
-    updateProgressThrottled () {
-      return _.throttle(this.updateProgress, 250)
-    }
-  },
-  methods: {
-    setupSound () {
-      let self = this
-      this.sound = new Howl({
-        src: this.srcs.map((s) => { return s.url }),
-        format: this.srcs.map((s) => { return s.type }),
-        autoplay: false,
-        loop: false,
-        html5: true,
-        preload: true,
-        volume: this.volume,
-        onend: function () {
-          self.ended()
-        },
-        onunlock: function () {
-          if (this.$store.state.player.playing) {
-            self.sound.play()
-          }
-        },
-        onload: function () {
-          self.$store.commit('player/isLoadingAudio', false)
-          self.$store.commit('player/resetErrorCount')
-          self.$store.commit('player/errored', false)
-          self.$store.commit('player/duration', self.sound.duration())
-          let node = self.sound._sounds[0]._node;
-          node.addEventListener('progress', () => {
-            self.updateBuffer(node)
-          })
-        },
-        onloaderror: function (sound, error) {
-          console.log('Error while playing:', sound, error)
-          self.$emit('errored', {sound, error})
-        },
-      })
-      if (this.autoplay) {
-        self.$store.commit('player/isLoadingAudio', true)
-        this.sound.play()
-        this.$store.commit('player/playing', true)
-        this.observeProgress(true)
-      }
-    },
-    updateBuffer (node) {
-      // from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
-      let range = 0;
-      let bf = node.buffered;
-      let time = node.currentTime;
-      try {
-        while(!(bf.start(range) <= time && time <= bf.end(range))) {
-          range += 1;
-        }
-      } catch (IndexSizeError) {
-        return
-      }
-      let loadPercentage
-      let start =  bf.start(range)
-      let end =  bf.end(range)
-      if (range === 0) {
-        // easy case, no user-seek
-        let loadStartPercentage = start / node.duration;
-        let loadEndPercentage = end / node.duration;
-        loadPercentage = loadEndPercentage - loadStartPercentage;
-      } else {
-        let loaded = end - start
-        let remainingToLoad = node.duration - start
-        // user seeked a specific position in the audio, our progress must be
-        // computed based on the remaining portion of the track
-        loadPercentage = loaded / remainingToLoad;
-      }
-      this.$store.commit('player/bufferProgress', loadPercentage * 100)
-    },
-    updateProgress: function () {
-      this.isUpdatingTime = true
-      if (this.sound && this.sound.state() === 'loaded') {
-        this.$store.dispatch('player/updateProgress', this.sound.seek())
-        this.updateBuffer(this.sound._sounds[0]._node)
-      }
-    },
-    observeProgress: function (enable) {
-      let self = this
-      if (enable) {
-        if (self.progressInterval) {
-          clearInterval(self.progressInterval)
-        }
-        self.progressInterval = setInterval(() => {
-          self.updateProgress()
-        }, 1000)
-      } else {
-        clearInterval(self.progressInterval)
-      }
-    },
-    setCurrentTime (t) {
-      if (t < 0 | t > this.duration) {
-        return
-      }
-      if (t === this.sound.seek()) {
-        return
-      }
-      if (t === 0) {
-        this.updateProgressThrottled.cancel()
-      }
-      this.sound.seek(t)
-    },
-    ended: function () {
-      let onlyTrack = this.$store.state.queue.tracks.length === 1
-      if (this.looping === 1 || (onlyTrack && this.looping === 2)) {
-        this.sound.seek(0)
-        this.sound.play()
-      } else {
-        this.$store.dispatch('player/trackEnded', this.trackData)
-      }
-    }
-  },
-  watch: {
-    playing: function (newValue) {
-      if (newValue === true) {
-        this.sound.play()
-      } else {
-        this.sound.pause()
-      }
-      this.observeProgress(newValue)
-    },
-    volume: function (newValue) {
-      this.sound.volume(newValue)
-    },
-    currentTime (newValue) {
-      if (!this.isUpdatingTime) {
-        this.setCurrentTime(newValue)
-      }
-      this.isUpdatingTime = false
-    }
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-</style>
diff --git a/front/src/components/audio/album/Card.vue b/front/src/components/audio/album/Card.vue
index 258b0f9d1a67e51b2f4e7349bd45c83feb7c08f2..bdc0dd6cb57b18eed7dfcc00ff45c929a027f4fb 100644
--- a/front/src/components/audio/album/Card.vue
+++ b/front/src/components/audio/album/Card.vue
@@ -11,7 +11,7 @@
         <div class="meta">
           <span>
             <router-link :title="album.artist.name" tag="span" :to="{name: 'library.artists.detail', params: {id: album.artist.id }}">
-              <span v-translate="{artist: album.artist.name}" :translate-params="{artist: album.artist.name}">By %{ artist }</span>
+              <span v-translate="{artist: album.artist.name}" translate-context="Content/Album/Card" :translate-params="{artist: album.artist.name}">By %{ artist }</span>
             </router-link>
           </span><span class="time" v-if="album.release_date">– {{ album.release_date | year }}</span>
         </div>
@@ -36,21 +36,21 @@
           </table>
           <div class="center aligned segment" v-if="album.tracks.length > initialTracks">
             <em v-if="!showAllTracks" @click="showAllTracks = true" class="expand">
-              <translate :translate-params="{count: album.tracks.length - initialTracks}" :translate-n="album.tracks.length - initialTracks" translate-plural="Show %{ count } more tracks">Show %{ count } more track</translate>
+              <translate translate-context="Content/Album/Card.Link/Verb" :translate-params="{count: album.tracks.length - initialTracks}" :translate-n="album.tracks.length - initialTracks" translate-plural="Show %{ count } more tracks">Show %{ count } more track</translate>
             </em>
             <em v-else @click="showAllTracks = false" class="expand">
-              <translate>Collapse</translate>
+              <translate translate-context="Content/*/Card.Link/Verb">Collapse</translate>
             </em>
           </div>
         </div>
       </div>
       <div class="extra content">
-        <play-button class="mini basic orange right floated" :tracks="album.tracks">
-          <translate>Play all</translate>
+        <play-button class="mini basic orange right floated" :tracks="tracksWithAlbum" :album="album">
+          <translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
         </play-button>
         <span>
           <i class="music icon"></i>
-          <translate :translate-params="{count: album.tracks.length}" :translate-n="album.tracks.length" translate-plural="%{ count } tracks">%{ count } track</translate>
+          <translate translate-context="*/*/*" :translate-params="{count: album.tracks.length}" :translate-n="album.tracks.length" translate-plural="%{ count } tracks">%{ count } track</translate>
         </span>
       </div>
     </div>
@@ -83,6 +83,20 @@ export default {
         return this.album.tracks
       }
       return this.album.tracks.slice(0, this.initialTracks)
+    },
+    tracksWithAlbum () {
+      // needed to include album data (especially cover)
+      // with tracks appended in queue (#795)
+      let self = this
+      return this.album.tracks.map(t => {
+        return  {
+          ...t,
+          album: {
+            ...self.album,
+            tracks: []
+          }
+        }
+      })
     }
   }
 }
diff --git a/front/src/components/audio/album/Widget.vue b/front/src/components/audio/album/Widget.vue
index f7100a9b86c3f33ea5ac3d0bef26f84d3f45f8ec..ecc0a280ed04b26779de42fad4537b77b4243426 100644
--- a/front/src/components/audio/album/Widget.vue
+++ b/front/src/components/audio/album/Widget.vue
@@ -5,6 +5,7 @@
     </h3>
     <button :disabled="!previousPage" @click="fetchData(previousPage)" :class="['ui', {disabled: !previousPage}, 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'angle left', 'icon']"></i></button>
     <button :disabled="!nextPage" @click="fetchData(nextPage)" :class="['ui', {disabled: !nextPage}, 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'angle right', 'icon']"></i></button>
+    <button @click="fetchData('albums/')" :class="['ui', 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'refresh', 'icon']"></i></button>
     <div class="ui hidden divider"></div>
     <div class="ui five cards">
       <div v-if="isLoading" class="ui inverted active dimmer">
@@ -12,7 +13,7 @@
       </div>
       <div class="card" v-for="album in albums" :key="album.id">
         <div :class="['ui', 'image', 'with-overlay', {'default-cover': !album.cover.original}]" v-lazy:background-image="getImageUrl(album)">
-          <play-button class="play-overlay" :icon-only="true" :is-playable="album.is_playable" :button-classes="['ui', 'circular', 'large', 'orange', 'icon', 'button']" :album="album.id"></play-button>
+          <play-button class="play-overlay" :icon-only="true" :is-playable="album.is_playable" :button-classes="['ui', 'circular', 'large', 'orange', 'icon', 'button']" :album="album"></play-button>
         </div>
         <div class="content">
           <router-link :title="album.title" :to="{name: 'library.albums.detail', params: {id: album.id}}">
@@ -28,7 +29,7 @@
         </div>
         <div class="extra content">
           <human-date class="left floated" :date="album.creation_date"></human-date>
-          <play-button class="right floated basic icon" :dropdown-only="true" :is-playable="album.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large', 'grey']" :album="album.id"></play-button>
+          <play-button class="right floated basic icon" :dropdown-only="true" :is-playable="album.is_playable" :dropdown-icon-classes="['ellipsis', 'horizontal', 'large', 'grey']" :album="album"></play-button>
         </div>
       </div>
     </div>
@@ -101,6 +102,9 @@ export default {
   watch: {
     offset () {
       this.fetchData()
+    },
+    "$store.state.moderation.lastUpdate": function () {
+      this.fetchData('albums/')
     }
   }
 }
diff --git a/front/src/components/audio/artist/Card.vue b/front/src/components/audio/artist/Card.vue
index d255928547da237b2074b6fb64a82717dc9dd2a5..b06cdcd75b126c3d5b7f68abce5923caf0c18a2a 100644
--- a/front/src/components/audio/artist/Card.vue
+++ b/front/src/components/audio/artist/Card.vue
@@ -21,17 +21,17 @@
                   {{ album.tracks_count }} tracks
                 </td>
                 <td>
-                  <play-button class="right floated basic icon" :is-playable="album.is_playable" :discrete="true" :album="album.id"></play-button>
+                  <play-button class="right floated basic icon" :is-playable="album.is_playable" :discrete="true" :album="album"></play-button>
                 </td>
               </tr>
             </tbody>
           </table>
           <div class="center aligned segment" v-if="artist.albums.length > initialAlbums">
             <em v-if="!showAllAlbums" @click="showAllAlbums = true" class="expand">
-              <translate :translate-params="{count: artist.albums.length - initialAlbums}" :translate-n="artist.albums.length - initialAlbums" translate-plural="Show %{ count } more albums">Show 1 more album</translate>
+              <translate translate-context="Content/Artist/Card.Link" :translate-params="{count: artist.albums.length - initialAlbums}" :translate-n="artist.albums.length - initialAlbums" translate-plural="Show %{ count } more albums">Show 1 more album</translate>
             </em>
             <em v-else @click="showAllAlbums = false" class="expand">
-              <translate>Collapse</translate>
+              <translate translate-context="Content/*/Card.Link/Verb">Collapse</translate>
             </em>
           </div>
         </div>
@@ -39,10 +39,10 @@
     <div class="extra content">
         <span>
           <i class="sound icon"></i>
-            <translate :translate-params="{count: artist.albums.length}" :translate-n="artist.albums.length" translate-plural="%{ count } albums">1 album</translate>
+            <translate translate-context="Content/Artist/Card" :translate-params="{count: artist.albums.length}" :translate-n="artist.albums.length" translate-plural="%{ count } albums">1 album</translate>
         </span>
-        <play-button :is-playable="isPlayable" class="mini basic orange right floated" :artist="artist.id">
-          <translate>Play all</translate>
+        <play-button :is-playable="isPlayable" class="mini basic orange right floated" :artist="artist">
+          <translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
         </play-button>
       </div>
     </div>
diff --git a/front/src/components/audio/track/Row.vue b/front/src/components/audio/track/Row.vue
index e391977f32cf70cb80adbfbccef029b752a4084e..abc4137bf397306b457cb19e8e9d39e6b21c0838 100644
--- a/front/src/components/audio/track/Row.vue
+++ b/front/src/components/audio/track/Row.vue
@@ -38,9 +38,9 @@
       {{ time.parse(track.uploads[0].duration) }}
     </td>
     <td colspan="4" v-else>
-      <translate>N/A</translate>
+      <translate translate-context="*/*/*">N/A</translate>
     </td>
-    <td colspan="2">
+    <td colspan="2" class="align right">
       <track-favorite-icon class="favorite-icon" :track="track"></track-favorite-icon>
       <track-playlist-icon
         v-if="$store.state.auth.authenticated"
diff --git a/front/src/components/audio/track/Table.vue b/front/src/components/audio/track/Table.vue
index 937025807864f950f3c4dae60a503c7ca8b29f54..31327ee3a5e3286cec4eded21ccc801d73e0b1eb 100644
--- a/front/src/components/audio/track/Table.vue
+++ b/front/src/components/audio/track/Table.vue
@@ -1,30 +1,36 @@
 <template>
-  <table class="ui compact very basic fixed single line unstackable table">
-    <thead>
-      <tr>
-        <th></th>
-        <th></th>
-        <th colspan="6"><translate>Title</translate></th>
-        <th colspan="4"><translate>Artist</translate></th>
-        <th colspan="4"><translate>Album</translate></th>
-        <th colspan="4"><translate>Duration</translate></th>
-        <th colspan="2"></th>
-      </tr>
-    </thead>
-    <tbody>
-      <track-row
-        :playable="playable"
-        :display-position="displayPosition"
-        :track="track"
-        :artist="artist"
-        :key="index + '-' + track.id"
-        v-for="(track, index) in tracks"></track-row>
-    </tbody>
-  </table>
+  <div class="table-wrapper">
+    <table class="ui compact very basic unstackable table">
+      <thead>
+        <tr>
+          <th></th>
+          <th></th>
+          <th colspan="6"><translate translate-context="Content/Track/*/Noun">Title</translate></th>
+          <th colspan="4"><translate translate-context="*/*/*/Noun">Artist</translate></th>
+          <th colspan="4"><translate translate-context="*/*/*">Album</translate></th>
+          <th colspan="4"><translate translate-context="Content/*/*">Duration</translate></th>
+          <th colspan="2"></th>
+        </tr>
+      </thead>
+      <tbody>
+        <track-row
+          :playable="playable"
+          :display-position="displayPosition"
+          :track="track"
+          :artist="artist"
+          :key="index + '-' + track.id"
+          v-for="(track, index) in allTracks"></track-row>
+      </tbody>
+    </table>
+    <button :class="['ui', {loading: isLoadingMore}, 'button']" v-if="loadMoreUrl" @click="loadMore(loadMoreUrl)">
+      <translate translate-context="Content/*/Button.Label">Load more…</translate>
+    </button>
+  </div>
 </template>
 
 <script>
 import backend from '@/audio/backend'
+import axios from 'axios'
 
 import TrackRow from '@/components/audio/track/Row'
 import Modal from '@/components/semantic/Modal'
@@ -33,6 +39,7 @@ export default {
   props: {
     tracks: {type: Array, required: true},
     playable: {type: Boolean, required: false, default: false},
+    nextUrl: {type: String, required: false, default: null},
     artist: {type: Object, required: false},
     displayPosition: {type: Boolean, default: false}
   },
@@ -42,7 +49,29 @@ export default {
   },
   data () {
     return {
-      backend: backend
+      backend: backend,
+      loadMoreUrl: this.nextUrl,
+      isLoadingMore: false,
+      additionalTracks: []
+    }
+  },
+  computed: {
+    allTracks () {
+      return this.tracks.concat(this.additionalTracks)
+    }
+  },
+  methods: {
+    loadMore (url) {
+      let self = this
+      self.isLoadingMore = true
+      axios.get(url).then((response) => {
+        self.additionalTracks = self.additionalTracks.concat(response.data.results)
+        self.loadMoreUrl = response.data.next
+        self.isLoadingMore = false
+      }, (error) => {
+        self.isLoadingMore = false
+
+      })
     }
   }
 }
diff --git a/front/src/components/audio/track/Widget.vue b/front/src/components/audio/track/Widget.vue
index f909945f0f97119fcb3ab3a36d8943bfe9513a3b..b8ad3c639c66eb756ca7f3d50148d08aa5e7c5df 100644
--- a/front/src/components/audio/track/Widget.vue
+++ b/front/src/components/audio/track/Widget.vue
@@ -103,6 +103,9 @@ export default {
   watch: {
     offset () {
       this.fetchData()
+    },
+    "$store.state.moderation.lastUpdate": function () {
+      this.fetchData(this.url)
     }
   }
 }
diff --git a/front/src/components/auth/ApplicationEdit.vue b/front/src/components/auth/ApplicationEdit.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b22ade7af6c00c4882a5a590525f7faec58aec25
--- /dev/null
+++ b/front/src/components/auth/ApplicationEdit.vue
@@ -0,0 +1,80 @@
+<template>
+  <main class="main pusher" v-title="labels.title">
+    <div class="ui vertical stripe segment">
+      <section class="ui text container">
+        <div v-if="isLoading" class="ui inverted active dimmer">
+          <div class="ui loader"></div>
+        </div>
+        <template v-else>
+          <router-link :to="{name: 'settings'}">
+            <translate translate-context="Content/Applications/Link">Back to settings</translate>
+          </router-link>
+          <h2 class="ui header">
+            <translate translate-context="Content/Applications/Title">Application details</translate>
+          </h2>
+          <div class="ui form">
+            <p>
+              <translate translate-context="Content/Application/Paragraph/">
+                Application ID and secret are really sensitive values and must be treated like passwords. Do not share those with anyone else.
+              </translate>
+            </p>
+            <div class="field">
+              <label><translate translate-context="Content/Applications/Label">Application ID</translate></label>
+              <copy-input :value="application.client_id" />
+            </div>
+            <div class="field">
+              <label><translate translate-context="Content/Applications/Label">Application secret</translate></label>
+              <copy-input :value="application.client_secret" />
+            </div>
+          </div>
+          <h2 class="ui header">
+            <translate translate-context="Content/Applications/Title">Edit application</translate>
+          </h2>
+          <application-form @updated="application = $event" :app="application" />
+        </template>
+      </section>
+    </div>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+
+import ApplicationForm from "@/components/auth/ApplicationForm"
+
+export default {
+  props: ['id'],
+  components: {
+    ApplicationForm
+  },
+  data() {
+    return {
+      application: null,
+      isLoading: false,
+    }
+  },
+  created () {
+    this.fetchApplication()
+  },
+  methods: {
+    fetchApplication () {
+      this.isLoading = true
+      let self = this
+      axios.get(`oauth/apps/${this.id}/`).then((response) => {
+        self.isLoading = false
+        self.application = response.data
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('Content/Applications/Title', "Edit application")
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/components/auth/ApplicationForm.vue b/front/src/components/auth/ApplicationForm.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c2eefbfdfb705643aad0bf728e7f8764a7d3a6af
--- /dev/null
+++ b/front/src/components/auth/ApplicationForm.vue
@@ -0,0 +1,185 @@
+<template>
+
+  <form class="ui form" @submit.prevent="submit()">
+    <div v-if="errors.length > 0" class="ui negative message">
+      <div class="header"><translate translate-context="Content/*/Error message.Title">We cannot save your changes</translate></div>
+      <ul class="list">
+        <li v-for="error in errors">{{ error }}</li>
+      </ul>
+    </div>
+    <div class="ui field">
+      <label><translate translate-context="Content/Applications/Input.Label/Noun">Name</translate></label>
+      <input name="name" required type="text" v-model="fields.name" />
+    </div>
+    <div class="ui field">
+      <label><translate translate-context="Content/Applications/Input.Label/Noun">Redirect URI</translate></label>
+      <input name="redirect_uris" type="text" v-model="fields.redirect_uris" />
+      <p class="help">
+        <translate translate-context="Content/Applications/Help Text">
+          Use "urn:ietf:wg:oauth:2.0:oob" as a redirect URI if your application is not served on the web.
+        </translate>
+      </p>
+    </div>
+    <div class="ui field">
+      <label><translate translate-context="Content/Applications/Input.Label/Noun">Scopes</translate></label>
+      <p>
+        <translate translate-context="Content/Applications/Paragraph/">
+          Checking the parent "Read" or "Write" scopes implies access to all the corresponding children scopes.
+        </translate>
+      </p>
+      <div class="ui stackable two column grid">
+        <div v-for="parent in allScopes" class="column">
+          <div class="ui parent checkbox">
+            <input
+              v-model="scopeArray"
+              :value="parent.id"
+              :id="parent.id"
+              type="checkbox">
+            <label :for="parent.id">
+              {{ parent.label }}
+              <p class="help">
+                {{ parent.description }}
+              </p>
+            </label>
+          </div>
+
+          <div v-for="child in parent.children">
+            <div class="ui child checkbox">
+              <input
+                v-model="scopeArray"
+                :value="child.id"
+                :id="child.id"
+                type="checkbox">
+              <label :for="child.id">
+                {{ child.id }}
+                <p class="help">
+                  {{ child.description }}
+                </p>
+              </label>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      </div>
+    <button :class="['ui', {'loading': isLoading}, 'green', 'button']" type="submit">
+      <translate v-if="updating" key="2" translate-context="Content/Applications/Button.Label/Verb">Update application</translate>
+      <translate v-else key="2" translate-context="Content/Applications/Button.Label/Verb">Create application</translate>
+    </button>
+  </form>
+</template>
+
+<script>
+import _ from "@/lodash"
+import axios from "axios"
+import TranslationsMixin from "@/components/mixins/Translations"
+
+export default {
+  mixins: [TranslationsMixin],
+  props: {
+    app: {type: Object, required: false},
+    defaults: {type: Object, required: false}
+  },
+  data() {
+    let app = this.app || {}
+    let defaults = this.defaults || {}
+    return {
+      isLoading: false,
+      errors: [],
+      fields: {
+        name: app.name || defaults.name || '',
+        redirect_uris: app.redirect_uris || defaults.redirect_uris || 'urn:ietf:wg:oauth:2.0:oob',
+        scopes: app.scopes || defaults.scopes || 'read'
+      },
+      scopes: [
+        {id: "profile", icon: 'user'},
+        {id: "libraries", icon: 'book'},
+        {id: "favorites", icon: 'heart'},
+        {id: "listenings", icon: 'music'},
+        {id: "follows", icon: 'users'},
+        {id: "playlists", icon: 'list'},
+        {id: "radios", icon: 'rss'},
+        {id: "filters", icon: 'eye slash'},
+        {id: "notifications", icon: 'bell'},
+        {id: "edits", icon: 'pencil alternate'},
+      ]
+    }
+  },
+  methods: {
+    submit () {
+      this.errors = []
+      let self = this
+      self.isLoading = true
+      let payload = this.fields
+      let event, promise, message
+      if (this.updating) {
+        event = 'updated'
+        promise = axios.patch(`oauth/apps/${this.app.client_id}/`, payload)
+      }  else {
+        event = 'created'
+        promise = axios.post(`oauth/apps/`, payload)
+      }
+      return promise.then(
+        response => {
+          self.isLoading = false
+          self.$emit(event, response.data)
+        },
+        error => {
+          self.isLoading = false
+          self.errors = error.backendErrors
+        }
+      )
+    },
+  },
+  computed: {
+    updating () {
+      return this.app
+    },
+    scopeArray: {
+      get () {
+        return this.fields.scopes.split(' ')
+      },
+      set (v) {
+        this.fields.scopes = _.uniq(v).join(' ')
+      }
+    },
+    allScopes () {
+      let self = this
+      let parents = [
+        {
+          id: 'read',
+          label: this.$pgettext('Content/OAuth Scopes/Label/Verb', 'Read'),
+          description: this.$pgettext('Content/OAuth Scopes/Help Text', 'Read-only access to user data'),
+          value: this.scopeArray.indexOf('read') > -1
+        },
+        {
+          id: 'write',
+          label: this.$pgettext('Content/OAuth Scopes/Label/Verb', 'Write'),
+          description: this.$pgettext('Content/OAuth Scopes/Help Text', 'Write-only access to user data'),
+          value: this.scopeArray.indexOf('write') > -1
+        },
+      ]
+      parents.forEach((p) => {
+        p.children = self.scopes.map(s => {
+          let id = `${p.id}:${s.id}`
+          return {
+            id,
+            value: this.scopeArray.indexOf(id) > -1,
+          }
+        })
+      })
+      return parents
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+.parent.checkbox {
+  margin: 1em 0;
+}
+.child.checkbox {
+  margin-left: 1em;
+}
+</style>
diff --git a/front/src/components/auth/ApplicationNew.vue b/front/src/components/auth/ApplicationNew.vue
new file mode 100644
index 0000000000000000000000000000000000000000..ba1a575fe79a95ae72d4c6f4611986bbc9efe9cb
--- /dev/null
+++ b/front/src/components/auth/ApplicationNew.vue
@@ -0,0 +1,46 @@
+<template>
+  <main class="main pusher" v-title="labels.title">
+    <div class="ui vertical stripe segment">
+      <section class="ui text container">
+        <router-link :to="{name: 'settings'}">
+          <translate translate-context="Content/Applications/Link">Back to settings</translate>
+        </router-link>
+        <h2 class="ui header">
+          <translate translate-context="Content/Applications/Title">Create a new application</translate>
+        </h2>
+        <application-form
+          :defaults="defaults"
+          @created="$router.push({name: 'settings.applications.edit', params: {id: $event.client_id}})" />
+      </section>
+    </div>
+  </main>
+</template>
+
+<script>
+import ApplicationForm from "@/components/auth/ApplicationForm"
+
+export default {
+  props: ['name', 'redirect_uris', 'scopes'],
+  components: {
+    ApplicationForm
+  },
+   data() {
+    return {
+      application: null,
+      isLoading: false,
+      defaults: {
+        name: this.name,
+        redirect_uris: this.redirect_uris,
+        scopes: this.scopes,
+      }
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('Content/Applications/Title', "Create a new application")
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/components/auth/Authorize.vue b/front/src/components/auth/Authorize.vue
new file mode 100644
index 0000000000000000000000000000000000000000..dd9bf6eebfddc2cc993401fdd31d94cce2892e40
--- /dev/null
+++ b/front/src/components/auth/Authorize.vue
@@ -0,0 +1,201 @@
+<template>
+  <main class="main pusher" v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <div class="ui small text container">
+        <h2><i class="lock open icon"></i><translate translate-context="Content/Auth/Title/Verb">Authorize third-party app</translate></h2>
+        <div v-if="errors.length > 0" class="ui negative message">
+          <div v-if="application" class="header"><translate translate-context="Popup/Moderation/Error message">Error while authorizing application</translate></div>
+          <div v-else class="header"><translate translate-context="Popup/Moderation/Error message">Error while fetching application data</translate></div>
+          <ul class="list">
+            <li v-for="error in errors">{{ error }}</li>
+          </ul>
+        </div>
+        <div v-if="isLoading" class="ui inverted active dimmer">
+          <div class="ui loader"></div>
+        </div>
+        <form v-else-if="application && !code" :class="['ui', {loading: isLoading}, 'form']" @submit.prevent="submit">
+          <h3><translate translate-context="Content/Auth/Title" :translate-params="{app: application.name}">%{ app } wants to access your Funkwhale account</translate></h3>
+
+          <h4 v-for="topic in topicScopes" class="ui header">
+            <span v-if="topic.write && !topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'label']">
+              <i class="pencil icon"></i>
+              <translate translate-context="Content/Auth/Label/Noun">Write-only</translate>
+            </span>
+            <span v-else-if="!topic.write && topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'label']">
+              <translate translate-context="Content/Auth/Label/Noun">Read-only</translate>
+            </span>
+            <span v-else-if="topic.write && topic.read" :class="['ui', 'basic', 'right floated', 'tiny', 'label']">
+              <i class="pencil icon"></i>
+              <translate translate-context="Content/Auth/Label/Noun">Full access</translate>
+            </span>
+            <i :class="[topic.icon, 'icon']"></i>
+            <div class="content">
+              {{ topic.label }}
+              <div class="sub header">
+                {{ topic.description }}
+              </div>
+            </div>
+          </h4>
+          <div v-if="unknownRequestedScopes.length > 0">
+            <p><strong><translate translate-context="Content/Auth/Paragraph">The application is also requesting the following unknown permissions:</translate></strong></p>
+            <ul v-for="scope in unknownRequestedScopes">
+              <li>{{ scope }}</li>
+            </ul>
+
+          </div>
+          <button class="ui green labeled icon button" type="submit">
+            <i class="lock open icon"></i>
+            <translate translate-context="Content/Signup/Button.Label/Verb" :translate-params="{app: application.name}">Authorize %{ app }</translate>
+          </button>
+          <p v-if="redirectUri === 'urn:ietf:wg:oauth:2.0:oob'" key="1" v-translate translate-context="Content/Auth/Paragraph">
+            You will be shown a code to copy-paste in the application.</p>
+          <p v-else key="2" v-translate="{url: redirectUri}" translate-context="Content/Auth/Paragraph" :translate-params="{url: redirectUri}">You will be redirected to <strong>%{ url }</strong></p>
+
+        </form>
+        <div v-else-if="code">
+          <p><strong><translate translate-context="Content/Auth/Paragraph">Copy-paste the following code in the application:</translate></strong></p>
+          <copy-input :value="code"></copy-input>
+        </div>
+      </div>
+    </section>
+  </main>
+</template>
+
+<script>
+import TranslationsMixin from "@/components/mixins/Translations"
+
+import axios from 'axios'
+
+export default {
+  mixins: [TranslationsMixin],
+  props: [
+    'clientId',
+    'redirectUri',
+    'scope',
+    'responseType',
+    'nonce',
+    'state',
+  ],
+  data() {
+    return {
+      application: null,
+      isLoading: false,
+      errors: [],
+      code: null,
+      knownScopes: [
+        {id: "profile", icon: 'user'},
+        {id: "libraries", icon: 'book'},
+        {id: "favorites", icon: 'heart'},
+        {id: "listenings", icon: 'music'},
+        {id: "follows", icon: 'users'},
+        {id: "playlists", icon: 'list'},
+        {id: "radios", icon: 'rss'},
+        {id: "filters", icon: 'eye slash'},
+        {id: "notifications", icon: 'bell'},
+        {id: "edits", icon: 'pencil alternate'},
+      ]
+    }
+  },
+  created () {
+    if (this.clientId) {
+      this.fetchApplication()
+    }
+  },
+  computed: {
+    labels () {
+      return {
+        title: this.$pgettext('Head/Authorize/Title', "Allow application")
+      }
+    },
+    requestedScopes () {
+      return (this.scope || '').split(' ')
+    },
+    supportedScopes () {
+      let supported = ['read', 'write']
+      this.knownScopes.forEach(s => {
+        supported.push(`read:${s.id}`)
+        supported.push(`write:${s.id}`)
+      })
+      return supported
+    },
+    unknownRequestedScopes () {
+      let self = this
+      return this.requestedScopes.filter(s => {
+        return self.supportedScopes.indexOf(s) < 0
+      })
+    },
+    topicScopes () {
+      let self = this
+      let requested = this.requestedScopes
+      let write = false
+      let read = false
+      if (requested.indexOf('read') > -1) {
+        read = true
+      }
+      if (requested.indexOf('write') > -1) {
+        write = true
+      }
+
+      return this.knownScopes.map(s => {
+        let id = s.id
+        return {
+          id: id,
+          icon: s.icon,
+          label: self.sharedLabels.scopes[s.id].label,
+          description: self.sharedLabels.scopes[s.id].description,
+          read: read || requested.indexOf(`read:${id}`) > -1,
+          write: write || requested.indexOf(`write:${id}`) > -1,
+        }
+      }).filter(c => {
+        return c.read || c.write
+      })
+    }
+  },
+  methods: {
+    fetchApplication () {
+      this.isLoading = true
+      let self = this
+      axios.get(`oauth/apps/${this.clientId}/`).then((response) => {
+        self.isLoading = false
+        self.application = response.data
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+    submit () {
+      this.isLoading = true
+      let self = this
+      let data = new FormData();
+      data.set('redirect_uri', this.redirectUri)
+      data.set('scope', this.scope)
+      data.set('allow', true)
+      data.set('client_id', this.clientId)
+      data.set('response_type', this.responseType)
+      data.set('state', this.state)
+      data.set('nonce', this.nonce)
+      axios.post(`oauth/authorize/`, data, {headers: {'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest'}}).then((response) => {
+        if (self.redirectUri === 'urn:ietf:wg:oauth:2.0:oob') {
+          self.isLoading = false
+          self.code = response.data.code
+        } else {
+          window.location.href = response.data.redirect_uri
+        }
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+.ui.header .content {
+  text-align: left;
+}
+.ui.header > .ui.label {
+  margin-top: 0.3em;
+}
+</style>
diff --git a/front/src/components/auth/Login.vue b/front/src/components/auth/Login.vue
index 09a9c6c29d5bb690b5c6eac3cbabd24883295b3d..20aff3236bd797e0c03a50ce9ec36b29287e20c9 100644
--- a/front/src/components/auth/Login.vue
+++ b/front/src/components/auth/Login.vue
@@ -2,20 +2,20 @@
   <main class="main pusher" v-title="labels.title">
     <section class="ui vertical stripe segment">
       <div class="ui small text container">
-        <h2><translate>Log in to your Funkwhale account</translate></h2>
+        <h2><translate translate-context="Content/Login/Title/Verb">Log in to your Funkwhale account</translate></h2>
         <form class="ui form" @submit.prevent="submit()">
           <div v-if="error" class="ui negative message">
-            <div class="header"><translate>We cannot log you in</translate></div>
+            <div class="header"><translate translate-context="Content/Login/Error message.Title">We cannot log you in</translate></div>
             <ul class="list">
-              <li v-if="error == 'invalid_credentials'"><translate>Please double-check your username/password couple is correct</translate></li>
-              <li v-else><translate>An unknown error happend, this can mean the server is down or cannot be reached</translate></li>
+              <li v-if="error == 'invalid_credentials'"><translate translate-context="Content/Login/Error message.List item/Call to action">Please double-check your username/password couple is correct</translate></li>
+              <li v-else><translate translate-context="Content/Login/Error message/List item">An unknown error happend, this can mean the server is down or cannot be reached</translate></li>
             </ul>
           </div>
           <div class="field">
             <label>
-              <translate>Username or email</translate> |
+              <translate translate-context="Content/Login/Input.Label/Noun">Username or email</translate> |
               <router-link :to="{path: '/signup'}">
-                <translate>Create an account</translate>
+                <translate translate-context="*/Signup/Link/Verb">Create an account</translate>
               </router-link>
             </label>
             <input
@@ -31,16 +31,16 @@
           </div>
           <div class="field">
             <label>
-              <translate>Password</translate> |
+              <translate translate-context="Content/*/Input.Label">Password</translate> |
               <router-link :to="{name: 'auth.password-reset', query: {email: credentials.username}}">
-                <translate>Reset your password</translate>
+                <translate translate-context="*/Login/*/Verb">Reset your password</translate>
               </router-link>
             </label>
             <password-input :index="2" required v-model="credentials.password" />
 
           </div>
           <button tabindex="3" :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']" type="submit">
-             <translate>Login</translate>
+             <translate translate-context="*/Login/*/Verb">Login</translate>
           </button>
         </form>
       </div>
@@ -80,8 +80,8 @@ export default {
   },
   computed: {
     labels() {
-      let usernamePlaceholder = this.$gettext("Enter your username or email")
-      let title = this.$gettext("Log In")
+      let usernamePlaceholder = this.$pgettext('Content/Login/Input.Placeholder', "Enter your username or email")
+      let title = this.$pgettext('Head/Login/Title', "Log In")
       return {
         usernamePlaceholder,
         title
@@ -97,7 +97,6 @@ export default {
         username: this.credentials.username,
         password: this.credentials.password
       }
-      console.log('NEXT', this.next)
       this.$store
         .dispatch("auth/login", {
           credentials,
diff --git a/front/src/components/auth/Logout.vue b/front/src/components/auth/Logout.vue
index 90495f5e0ed17fbb2485da7003a93d97a7bbf5a9..99fbc9da6ec7e8b11f64ff6dd4ec02af0ba080f1 100644
--- a/front/src/components/auth/Logout.vue
+++ b/front/src/components/auth/Logout.vue
@@ -3,10 +3,10 @@
     <section class="ui vertical stripe segment">
       <div class="ui small text container">
         <h2>
-          <translate>Are you sure you want to log out?</translate>
+          <translate translate-context="Content/Login/Title">Are you sure you want to log out?</translate>
         </h2>
-        <p v-translate="{username: $store.state.auth.username}">You are currently logged in as %{ username }</p>
-        <button class="ui button" @click="$store.dispatch('auth/logout')"><translate>Yes, log me out!</translate></button>
+        <p v-translate="{username: $store.state.auth.username}" translate-context="Content/Login/Paragraph">You are currently logged in as %{ username }</p>
+        <button class="ui button" @click="$store.dispatch('auth/logout')"><translate translate-context="Content/Login/Button.Label">Yes, log me out!</translate></button>
       </div>
     </section>
   </main>
@@ -17,7 +17,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Log Out")
+        title: this.$pgettext('Head/Login/Title', "Log Out")
       }
     }
   }
diff --git a/front/src/components/auth/Profile.vue b/front/src/components/auth/Profile.vue
index 73c9ab2d9c64950cd145c04cb70813a9e2671612..278f62ec0092492c733d524f6c4773c5b7575b9e 100644
--- a/front/src/components/auth/Profile.vue
+++ b/front/src/components/auth/Profile.vue
@@ -10,18 +10,18 @@
           <img class="ui big circular image" v-else v-lazy="$store.getters['instance/absoluteUrl'](profile.avatar.square_crop)" />
           <div class="content">
             {{ profile.username }}
-            <div class="sub header" v-translate="{date: signupDate}">Member since %{ date }</div>
+            <div class="sub header" v-translate="{date: signupDate}" translate-context="Content/Profile/Paragraph">Member since %{ date }</div>
           </div>
         </h2>
         <div class="ui basic green label">
-          <translate>This is you!</translate>
+          <translate translate-context="Content/Profile/Button.Paragraph">This is you!</translate>
         </div>
         <a v-if="profile.is_staff"
           class="ui yellow label"
           :href="$store.getters['instance/absoluteUrl']('/api/admin')"
           target="_blank">
           <i class="star icon"></i>
-          <translate>Staff member</translate>
+          <translate translate-context="Content/Profile/User role">Staff member</translate>
         </a>
       </div>
     </template>
@@ -43,7 +43,7 @@ export default {
       profile: state => state.auth.profile
     }),
     labels() {
-      let msg = this.$gettext("%{ username }'s profile")
+      let msg = this.$pgettext('Head/Profile/Title', "%{ username }'s profile")
       let usernameProfile = this.$gettextInterpolate(msg, {
         username: this.username
       })
diff --git a/front/src/components/auth/Settings.vue b/front/src/components/auth/Settings.vue
index 8305d0e05dd5b11553d842cc97b224261cf1859b..6e2516ed87156da3c31b360d6358d027ef3009cb 100644
--- a/front/src/components/auth/Settings.vue
+++ b/front/src/components/auth/Settings.vue
@@ -1,18 +1,18 @@
 <template>
   <main class="main pusher" v-title="labels.title">
     <div class="ui vertical stripe segment">
-      <section class="ui small text container">
+      <section class="ui text container">
         <h2 class="ui header">
-          <translate>Account settings</translate>
+          <translate translate-context="Content/Settings/Title">Account settings</translate>
         </h2>
         <form class="ui form" @submit.prevent="submitSettings()">
           <div v-if="settings.success" class="ui positive message">
             <div class="header">
-              <translate>Settings updated</translate>
+              <translate translate-context="Content/Settings/Message">Settings updated</translate>
             </div>
           </div>
           <div v-if="settings.errors.length > 0" class="ui negative message">
-            <div class="header"><translate>We cannot save your settings</translate></div>
+            <div class="header"><translate translate-context="Content/Settings/Error message.Title">Your settings can't be updateds</translate></div>
             <ul class="list">
               <li v-for="error in settings.errors">{{ error }}</li>
             </ul>
@@ -25,88 +25,248 @@
             </select>
           </div>
           <button :class="['ui', {'loading': isLoading}, 'button']" type="submit">
-            <translate>Update settings</translate>
+            <translate translate-context="Content/Settings/Button.Label/Verb">Update settings</translate>
           </button>
         </form>
       </section>
-      <div class="ui hidden divider"></div>
-      <section class="ui small text container">
+      <section class="ui text container">
+        <div class="ui hidden divider"></div>
         <h2 class="ui header">
-          <translate>Avatar</translate>
+          <translate translate-context="Content/Settings/Title">Avatar</translate>
         </h2>
         <div class="ui form">
           <div v-if="avatarErrors.length > 0" class="ui negative message">
-            <div class="header"><translate>We cannot save your avatar</translate></div>
+            <div class="header"><translate translate-context="Content/Settings/Error message.Title">Your avatar cannot be saved</translate></div>
             <ul class="list">
               <li v-for="error in avatarErrors">{{ error }}</li>
             </ul>
           </div>
           <div class="ui stackable grid">
             <div class="ui ten wide column">
-              <h3 class="ui header"><translate>Upload a new avatar</translate></h3>
-              <p><translate>PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px.</translate></p>
+              <h3 class="ui header"><translate translate-context="Content/Settings/Title/Verb">Upload a new avatar</translate></h3>
+              <p><translate translate-context="Content/Settings/Paragraph">PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px.</translate></p>
               <input class="ui input" ref="avatar" type="file" />
               <div class="ui hidden divider"></div>
               <button @click="submitAvatar" :class="['ui', {'loading': isLoadingAvatar}, 'button']">
-                <translate>Update avatar</translate>
+                <translate translate-context="Content/Settings/Button.Label/Verb">Update avatar</translate>
               </button>
             </div>
             <div class="ui six wide column">
-              <h3 class="ui header"><translate>Current avatar</translate></h3>
+              <h3 class="ui header"><translate translate-context="Content/Settings/Title/Noun">Current avatar</translate></h3>
               <img class="ui circular image" v-if="currentAvatar && currentAvatar.square_crop" v-lazy="$store.getters['instance/absoluteUrl'](currentAvatar.medium_square_crop)" />
               <div class="ui hidden divider"></div>
               <button @click="removeAvatar" v-if="currentAvatar && currentAvatar.square_crop" :class="['ui', {'loading': isLoadingAvatar}, ,'yellow', 'button']">
-                <translate>Remove avatar</translate>
+                <translate translate-context="Content/Settings/Button.Label/Verb">Remove avatar</translate>
               </button>
             </div>
           </div>
         </div>
       </section>
-      <div class="ui hidden divider"></div>
-      <section class="ui small text container">
+
+      <section class="ui text container">
+        <div class="ui hidden divider"></div>
         <h2 class="ui header">
-          <translate>Change my password</translate>
+          <translate translate-context="Content/Settings/Title/Verb">Change my password</translate>
         </h2>
         <div class="ui message">
-          <translate>Changing your password will also change your Subsonic API password if you have requested one.</translate>&nbsp;<translate>You will have to update your password on your clients that use this password.</translate>
+          <translate translate-context="Content/Settings/Paragraph'">Changing your password will also change your Subsonic API password if you have requested one.</translate>&nbsp;<translate translate-context="Content/Settings/Paragraph">You will have to update your password on your clients that use this password.</translate>
         </div>
         <form class="ui form" @submit.prevent="submitPassword()">
           <div v-if="passwordError" class="ui negative message">
             <div class="header">
-              <translate>Cannot change your password</translate>
+              <translate translate-context="Content/Settings/Error message.Title">Your password cannot be changed</translate>
             </div>
             <ul class="list">
-              <li v-if="passwordError == 'invalid_credentials'"><translate>Please double-check your password is correct</translate></li>
+              <li v-if="passwordError == 'invalid_credentials'"><translate translate-context="Content/Settings/Error message.List item/Call to action">Please double-check your password is correct</translate></li>
             </ul>
           </div>
           <div class="field">
-            <label><translate>Old password</translate></label>
+            <label><translate translate-context="Content/Settings/Input.Label">Old password</translate></label>
             <password-input required v-model="old_password" />
 
           </div>
           <div class="field">
-            <label><translate>New password</translate></label>
+            <label><translate translate-context="Content/Settings/Input.Label">New password</translate></label>
             <password-input required v-model="new_password" />
           </div>
           <dangerous-button
             color="yellow"
             :class="['ui', {'loading': isLoading}, 'button']"
             :action="submitPassword">
-            <translate>Change password</translate>
-            <p slot="modal-header"><translate>Change your password?</translate></p>
+            <translate translate-context="Content/Settings/Button.Label">Change password</translate>
+            <p slot="modal-header"><translate translate-context="Popup/Settings/Title">Change your password?</translate></p>
             <div slot="modal-content">
-              <p><translate>Changing your password will have the following consequences</translate></p>
+              <p><translate translate-context="Popup/Settings/Paragraph">Changing your password will have the following consequences:</translate></p>
               <ul>
-                <li><translate>You will be logged out from this session and have to log in with the new one</translate></li>
-                <li><translate>Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password</translate></li>
+                <li><translate translate-context="Popup/Settings/List item">You will be logged out from this session and have to log in with the new one</translate></li>
+                <li><translate translate-context="Popup/Settings/List item">Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password</translate></li>
               </ul>
             </div>
-            <p slot="modal-confirm"><translate>Disable access</translate></p>
+            <div slot="modal-confirm"><translate translate-context="Popup/Settings/Button.Label">Disable access</translate></div>
           </dangerous-button>
         </form>
         <div class="ui hidden divider" />
         <subsonic-token-form />
       </section>
+
+      <section class="ui text container" id="content-filters">
+        <div class="ui hidden divider"></div>
+        <h2 class="ui header">
+          <i class="eye slash outline icon"></i>
+          <div class="content">
+            <translate translate-context="Content/Settings/Title/Noun">Content filters</translate>
+          </div>
+        </h2>
+        <p><translate translate-context="Content/Settings/Paragraph">Content filters help you hide content you don't want to see on the service.</translate></p>
+
+        <button
+          @click="$store.dispatch('moderation/fetchContentFilters')"
+          class="ui basic icon button">
+          <i class="refresh icon"></i>&nbsp;
+          <translate translate-context="Content/*/Button.Label/Short, Verb">Refresh</translate>
+        </button>
+        <h3 class="ui header">
+          <translate translate-context="Content/Settings/Title">Hidden artists</translate>
+        </h3>
+        <table class="ui compact very basic unstackable table">
+          <thead>
+            <tr>
+              <th><translate translate-context="*/*/*/Noun">Name</translate></th>
+              <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+              <th></th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="filter in $store.getters['moderation/artistFilters']()" :key='filter.uuid'>
+              <td>
+                <router-link :to="{name: 'library.artists.detail', params: {id: filter.target.id }}">
+                  {{ filter.target.name }}
+                </router-link>
+              </td>
+              <td>
+                <human-date :date="filter.creation_date"></human-date>
+              </td>
+              <td>
+                <button @click="$store.dispatch('moderation/deleteContentFilter', filter.uuid)" class="ui basic tiny button">
+                  <translate translate-context="*/*/*/Verb">Delete</translate>
+                </button>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </section>
+      <section class="ui text container" id="grants">
+        <div class="ui hidden divider"></div>
+        <h2 class="ui header">
+          <i class="open lock icon"></i>
+          <div class="content">
+            <translate translate-context="Content/Settings/Title/Noun">Authorized apps</translate>
+          </div>
+        </h2>
+        <p><translate translate-context="Content/Settings/Paragraph">This is the list of applications that have access to your account data.</translate></p>
+        <button
+          @click="fetchApps()"
+          class="ui basic icon button">
+          <i class="refresh icon"></i>&nbsp;
+          <translate translate-context="Content/*/Button.Label/Short, Verb">Refresh</translate>
+        </button>
+        <table v-if="apps.length > 0" class="ui compact very basic unstackable table">
+          <thead>
+            <tr>
+              <th><translate translate-context="*/*/*/Noun">Application</translate></th>
+              <th><translate translate-context="Content/*/*/Noun">Permissions</translate></th>
+              <th></th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="app in apps" :key='app.client_id'>
+              <td>
+                {{ app.name }}
+              </td>
+              <td>
+                {{ app.scopes }}
+              </td>
+              <td>
+                <dangerous-button
+                  class="ui tiny basic button"
+                  @confirm="revokeApp(app.client_id)">
+                  <translate translate-context="*/*/*/Verb">Revoke</translate>
+                  <p slot="modal-header" v-translate="{application: app.name}" translate-context="Popup/Settings/Title">Revoke access for application "%{ application }"?</p>
+                  <p slot="modal-content"><translate translate-context="Popup/Settings/Paragraph">This will prevent this application from accessing the service on your behalf.</translate></p>
+                  <div slot="modal-confirm"><translate translate-context="*/Settings/Button.Label/Verb">Revoke access</translate></div>
+                </dangerous-button>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+        <empty-state v-else>
+          <translate slot="title" translate-context="Content/Applications/Paragraph">
+            You don't have any application connected with your account.
+          </translate>
+          <translate translate-context="Content/Applications/Paragraph">
+            If you authorize third-party applications to access your data, those applications will be listed here.
+          </translate>
+        </empty-state>
+      </section>
+      <section class="ui text container" id="apps">
+        <div class="ui hidden divider"></div>
+        <h2 class="ui header">
+          <i class="code icon"></i>
+          <div class="content">
+            <translate translate-context="Content/Settings/Title/Noun">Your applications</translate>
+          </div>
+        </h2>
+        <p><translate translate-context="Content/Settings/Paragraph">This is the list of applications that you have created.</translate></p>
+        <router-link class="ui basic green button" :to="{name: 'settings.applications.new'}">
+          <translate translate-context="Content/Settings/Button.Label">Create a new application</translate>
+        </router-link>
+        <table v-if="ownedApps.length > 0" class="ui compact very basic unstackable table">
+          <thead>
+            <tr>
+              <th><translate translate-context="*/*/*/Noun">Application</translate></th>
+              <th><translate translate-context="Content/*/*/Noun">Scopes</translate></th>
+              <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+              <th></th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="app in ownedApps" :key='app.client_id'>
+              <td>
+                <router-link :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
+                  {{ app.name }}
+                </router-link>
+              </td>
+              <td>
+                {{ app.scopes }}
+              </td>
+              <td>
+                <human-date :date="app.created" />
+              </td>
+              <td>
+                <router-link class="ui basic tiny green button" :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
+                  <translate translate-context="Content/Settings/Button.Label">Edit</translate>
+                </router-link>
+                <dangerous-button
+                  class="ui tiny basic button"
+                  @confirm="deleteApp(app.client_id)">
+                  <translate translate-context="*/*/*/Verb">Delete</translate>
+                  <p slot="modal-header" v-translate="{application: app.name}" translate-context="Popup/Settings/Title">Delete application "%{ application }"?</p>
+                  <p slot="modal-content"><translate translate-context="Popup/Settings/Paragraph">This will permanently delete the application and all the associated tokens.</translate></p>
+                  <div slot="modal-confirm"><translate translate-context="*/Settings/Button.Label/Verb">Delete application</translate></div>
+                </dangerous-button>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+        <empty-state v-else>
+          <translate slot="title" translate-context="Content/Applications/Paragraph">
+            You don't have any configured application yet.
+          </translate>
+          <translate translate-context="Content/Applications/Paragraph">
+            Create one to integrate Funkwhale with third-party applications.
+          </translate>
+        </empty-state>
+      </section>
     </div>
   </main>
 </template>
@@ -137,6 +297,8 @@ export default {
       isLoadingAvatar: false,
       avatarErrors: [],
       avatar: null,
+      apps: [],
+      ownedApps: [],
       settings: {
         success: false,
         errors: [],
@@ -156,6 +318,10 @@ export default {
     })
     return d
   },
+  created () {
+    this.fetchApps()
+    this.fetchOwnedApps()
+  },
   mounted() {
     $("select.dropdown").dropdown()
   },
@@ -181,6 +347,56 @@ export default {
         }
       )
     },
+    fetchApps() {
+      this.apps = []
+      let self = this
+      let url = `oauth/grants/`
+      return axios.get(url).then(
+        response => {
+          self.apps = response.data
+        },
+        error => {
+        }
+      )
+    },
+    fetchOwnedApps() {
+      this.ownedApps = []
+      let self = this
+      let url = `oauth/apps/`
+      return axios.get(url).then(
+        response => {
+          self.ownedApps = response.data.results
+        },
+        error => {
+        }
+      )
+    },
+    revokeApp (id) {
+      let self = this
+      let url = `oauth/grants/${id}/`
+      return axios.delete(url).then(
+        response => {
+          self.apps = self.apps.filter(a => {
+            return a.client_id != id
+          })
+        },
+        error => {
+        }
+      )
+    },
+    deleteApp (id) {
+      let self = this
+      let url = `oauth/apps/${id}/`
+      return axios.delete(url).then(
+        response => {
+          self.ownedApps = self.ownedApps.filter(a => {
+            return a.client_id != id
+          })
+        },
+        error => {
+        }
+      )
+    },
     submitAvatar() {
       this.isLoadingAvatar = true
       this.avatarErrors = []
@@ -260,7 +476,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Account Settings")
+        title: this.$pgettext('Head/Settings/Title', "Account Settings")
       }
     },
     orderedSettingsFields() {
diff --git a/front/src/components/auth/Signup.vue b/front/src/components/auth/Signup.vue
index 815f0253a72b697ea663801dff4ba43f5909988d..974d082bda98153009cc2e9f35cd4c0e67ab16fd 100644
--- a/front/src/components/auth/Signup.vue
+++ b/front/src/components/auth/Signup.vue
@@ -2,22 +2,22 @@
   <main class="main pusher" v-title="labels.title">
     <section class="ui vertical stripe segment">
       <div class="ui small text container">
-        <h2><translate>Create a funkwhale account</translate></h2>
+        <h2><translate translate-context="Content/Signup/Title">Create a funkwhale account</translate></h2>
         <form
           :class="['ui', {'loading': isLoadingInstanceSetting}, 'form']"
           @submit.prevent="submit()">
           <p class="ui message" v-if="!$store.state.instance.settings.users.registration_enabled.value">
-            <translate>Registration are closed on this instance, you will need an invitation code to signup.</translate>
+            <translate translate-context="Content/Signup/Form/Paragraph">Registration are closed on this instance, you will need an invitation code to signup.</translate>
           </p>
 
           <div v-if="errors.length > 0" class="ui negative message">
-            <div class="header"><translate>We cannot create your account</translate></div>
+            <div class="header"><translate translate-context="Content/Signup/Form/Paragraph">Your account cannot be created.</translate></div>
             <ul class="list">
               <li v-for="error in errors">{{ error }}</li>
             </ul>
           </div>
           <div class="field">
-            <label><translate>Username</translate></label>
+            <label><translate translate-context="Content/*/*">Username</translate></label>
             <input
             ref="username"
             name="username"
@@ -28,7 +28,7 @@
             v-model="username">
           </div>
           <div class="field">
-            <label><translate>Email</translate></label>
+            <label><translate translate-context="Content/*/*/Noun">Email</translate></label>
             <input
             ref="email"
             name="email"
@@ -38,11 +38,11 @@
             v-model="email">
           </div>
           <div class="field">
-            <label><translate>Password</translate></label>
+            <label><translate translate-context="Content/*/Input.Label">Password</translate></label>
             <password-input v-model="password" />
           </div>
           <div class="field" v-if="!$store.state.instance.settings.users.registration_enabled.value">
-            <label><translate>Invitation code</translate></label>
+            <label><translate translate-context="Content/*/Input.Label">Invitation code</translate></label>
             <input
             required
             type="text"
@@ -51,7 +51,7 @@
             v-model="invitation">
           </div>
           <button :class="['ui', 'green', {'loading': isLoading}, 'button']" type="submit">
-            <translate>Create my account</translate>
+            <translate translate-context="Content/Signup/Button.Label">Create my account</translate>
           </button>
         </form>
       </div>
@@ -94,12 +94,13 @@ export default {
   },
   computed: {
     labels() {
-      let title = this.$gettext("Sign Up")
-      let placeholder = this.$gettext(
+      let title = this.$pgettext("*/Signup/Title", "Sign Up")
+      let placeholder = this.$pgettext(
+        "Content/Signup/Form/Placeholder",
         "Enter your invitation code (case insensitive)"
       )
-      let usernamePlaceholder = this.$gettext("Enter your username")
-      let emailPlaceholder = this.$gettext("Enter your email")
+      let usernamePlaceholder = this.$pgettext("Content/Signup/Form/Placeholder", "Enter your username")
+      let emailPlaceholder = this.$pgettext("Content/Signup/Form/Placeholder", "Enter your email")
       return {
         title,
         usernamePlaceholder,
diff --git a/front/src/components/auth/SubsonicTokenForm.vue b/front/src/components/auth/SubsonicTokenForm.vue
index ac752d92166778d7135916709f33d68ad80370b5..0184074e294365a15e453db7184644d66d75796a 100644
--- a/front/src/components/auth/SubsonicTokenForm.vue
+++ b/front/src/components/auth/SubsonicTokenForm.vue
@@ -1,23 +1,23 @@
 <template>
   <form class="ui form" @submit.prevent="requestNewToken()">
-    <h2><translate>Subsonic API password</translate></h2>
+    <h2><translate translate-context="Content/Settings/Title">Subsonic API password</translate></h2>
     <p class="ui message" v-if="!subsonicEnabled">
-      <translate>The Subsonic API is not available on this Funkwhale instance.</translate>
+      <translate translate-context="Content/Settings/Paragraph">The Subsonic API is not available on this Funkwhale instance.</translate>
     </p>
     <p>
-      <translate>Funkwhale is compatible with other music players that support the Subsonic API.</translate>&nbsp;<translate>You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance.</translate>
+      <translate translate-context="Content/Settings/Paragraph'">Funkwhale is compatible with other music players that support the Subsonic API.</translate>&nbsp;<translate translate-context="Content/Settings/Paragraph">You can use those to enjoy your playlist and music in offline mode, on your smartphone or tablet, for instance.</translate>
     </p>
     <p>
-      <translate>However, accessing Funkwhale from those clients require a separate password you can set below.</translate>
+      <translate translate-context="Content/Settings/Paragraph">However, accessing Funkwhale from those clients require a separate password you can set below.</translate>
     </p>
     <p><a href="https://docs.funkwhale.audio/users/apps.html#subsonic-compatible-clients" target="_blank">
-      <translate>Discover how to use Funkwhale from other apps</translate>
+      <translate translate-context="Content/Settings/Link">Discover how to use Funkwhale from other apps</translate>
     </a></p>
     <div v-if="success" class="ui positive message">
       <div class="header">{{ successMessage }}</div>
     </div>
     <div v-if="subsonicEnabled && errors.length > 0" class="ui negative message">
-      <div class="header"><translate>Error</translate></div>
+      <div class="header"><translate translate-context="Content/*/Error message.Title">Error</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
@@ -31,25 +31,25 @@
         color="grey"
         :class="['ui', {'loading': isLoading}, 'button']"
         :action="requestNewToken">
-        <translate>Request a new password</translate>
-        <p slot="modal-header"><translate>Request a new Subsonic API password?</translate></p>
-        <p slot="modal-content"><translate>This will log you out from existing devices that use the current password.</translate></p>
-        <p slot="modal-confirm"><translate>Request a new password</translate></p>
+        <translate translate-context="*/Settings/Button.Label/Verb">Request a new password</translate>
+        <p slot="modal-header"><translate translate-context="Popup/Settings/Title">Request a new Subsonic API password?</translate></p>
+        <p slot="modal-content"><translate translate-context="Popup/Settings/Paragraph">This will log you out from existing devices that use the current password.</translate></p>
+        <div slot="modal-confirm"><translate translate-context="*/Settings/Button.Label/Verb">Request a new password</translate></div>
       </dangerous-button>
       <button
         v-else
         color="grey"
         :class="['ui', {'loading': isLoading}, 'button']"
-        @click="requestNewToken"><translate>Request a password</translate></button>
+        @click="requestNewToken"><translate translate-context="Content/Settings/Button.Label/Verb">Request a password</translate></button>
         <dangerous-button
           v-if="token"
           color="yellow"
           :class="['ui', {'loading': isLoading}, 'button']"
           :action="disable">
-          <translate>Disable Subsonic access</translate>
-          <p slot="modal-header"><translate>Disable Subsonic API access?</translate></p>
-          <p slot="modal-content"><translate>This will completely disable access to the Subsonic API using from account.</translate></p>
-          <p slot="modal-confirm"><translate>Disable access</translate></p>
+          <translate translate-context="Content/Settings/Button.Label/Verb">Disable Subsonic access</translate>
+          <p slot="modal-header"><translate translate-context="Popup/Settings/Title">Disable Subsonic API access?</translate></p>
+          <p slot="modal-content"><translate translate-context="Popup/Settings/Paragraph">This will completely disable access to the Subsonic API using from account.</translate></p>
+          <div slot="modal-confirm"><translate translate-context="Popup/Settings/Button.Label">Disable access</translate></div>
         </dangerous-button>
     </template>
   </form>
@@ -91,7 +91,7 @@ export default {
       })
     },
     requestNewToken () {
-      this.successMessage = this.$gettext('Password updated')
+      this.successMessage = this.$pgettext('Content/Settings/Message', 'Password updated')
       this.success = false
       this.errors = []
       this.isLoading = true
@@ -107,7 +107,7 @@ export default {
       })
     },
     disable () {
-      this.successMessage = this.$gettext('Access disabled')
+      this.successMessage = this.$pgettext('Content/Settings/Message', 'Access disabled')
       this.success = false
       this.errors = []
       this.isLoading = true
diff --git a/front/src/components/common/ActionTable.vue b/front/src/components/common/ActionTable.vue
index 5fcaceaacacf3c37629d4734e0fd700880463299..1a43a5f9ff1ba4ea1e87ff61992458e8c947f0b1 100644
--- a/front/src/components/common/ActionTable.vue
+++ b/front/src/components/common/ActionTable.vue
@@ -1,142 +1,145 @@
 <template>
-  <table class="ui compact very basic single line unstackable table">
-    <thead>
-      <tr>
-        <th colspan="1000">
-          <div v-if="refreshable" class="right floated">
-            <span v-if="needsRefresh">
-              <translate>Content have been updated, click refresh to see up-to-date content</translate>
-            </span>
-            <button
-              @click="$emit('refresh')"
-              class="ui basic icon button"
-              :title="labels.refresh"
-              :aria-label="labels.refresh">
-              <i class="refresh icon"></i>
-            </button>
-          </div>
+  <div class="table-wrapper">
+    <table class="ui compact very basic unstackable table">
+      <thead>
+        <tr>
+          <th colspan="1000">
+            <div v-if="refreshable" class="right floated">
+              <span v-if="needsRefresh">
+                <translate translate-context="Content/*/Button.Help text.Paragraph">Content have been updated, click refresh to see up-to-date content</translate>
+              </span>
+              <button
+                @click="$emit('refresh')"
+                class="ui basic icon button"
+                :title="labels.refresh"
+                :aria-label="labels.refresh">
+                <i class="refresh icon"></i>
+              </button>
+            </div>
 
-          <div class="ui small left floated form" v-if="actionUrl && actions.length > 0">
-            <div class="ui inline fields">
-              <div class="field">
-                <label><translate>Actions</translate></label>
-                <select class="ui dropdown" v-model="currentActionName">
-                  <option v-for="action in actions" :value="action.name">
-                    {{ action.label }}
-                  </option>
-                </select>
+            <div class="ui small left floated form" v-if="actionUrl && actions.length > 0">
+              <div class="ui inline fields">
+                <div class="field">
+                  <label><translate translate-context="Content/*/*/Noun">Actions</translate></label>
+                  <select class="ui dropdown" v-model="currentActionName">
+                    <option v-for="action in actions" :value="action.name">
+                      {{ action.label }}
+                    </option>
+                  </select>
+                </div>
+                <div class="field">
+                  <dangerous-button
+                    v-if="selectAll || currentAction.isDangerous" :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
+                    :confirm-color="currentAction.confirmColor || 'green'"
+                    color=""
+                    @confirm="launchAction">
+                    <translate translate-context="Content/*/Button.Label/Short, Verb">Go</translate>
+                    <p slot="modal-header">
+                      <translate translate-context="Modal/*/Title"
+                        key="1"
+                        :translate-n="affectedObjectsCount"
+                        :translate-params="{count: affectedObjectsCount, action: currentActionName}"
+                        translate-plural="Do you want to launch %{ action } on %{ count } elements?">
+                        Do you want to launch %{ action } on %{ count } element?
+                      </translate>
+                    </p>
+                    <p slot="modal-content">
+                      <template v-if="currentAction.confirmationMessage">{{ currentAction.confirmationMessage }}</template>
+                      <translate v-else translate-context="Modal/*/Paragraph">This may affect a lot of elements or have irreversible consequences, please double check this is really what you want.</translate>
+                    </p>
+                    <div slot="modal-confirm"><translate translate-context="Modal/*/Button.Label/Short, Verb">Launch</translate></div>
+                  </dangerous-button>
+                  <div
+                    v-else
+                    @click="launchAction"
+                    :disabled="checked.length === 0"
+                    :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']">
+                    <translate translate-context="Content/*/Button.Label/Short, Verb">Go</translate></div>
+                </div>
+                <div class="count field">
+                  <translate translate-context="Content/*/Paragraph"
+                    tag="span"
+                    v-if="selectAll"
+                    key="1"
+                    :translate-n="objectsData.count"
+                    :translate-params="{count: objectsData.count, total: objectsData.count}"
+                    translate-plural="All %{ count } elements selected">
+                    All %{ count } element selected
+                  </translate>
+                  <translate translate-context="Content/*/Paragraph"
+                    tag="span"
+                    v-else
+                    key="2"
+                    :translate-n="checked.length"
+                    :translate-params="{count: checked.length, total: objectsData.count}"
+                    translate-plural="%{ count } on %{ total } selected">
+                    %{ count } on %{ total } selected
+                  </translate>
+                  <template v-if="currentAction.allowAll && checkable.length > 0 && checkable.length === checked.length">
+                    <a @click="selectAll = true" v-if="!selectAll">
+                      <translate translate-context="Content/*/Link/Verb"
+                        key="3"
+                        :translate-n="objectsData.count"
+                        :translate-params="{total: objectsData.count}"
+                        translate-plural="Select all %{ total } elements">
+                        Select all %{ total } elements
+                      </translate>
+                    </a>
+                    <a @click="selectAll = false" v-else>
+                      <translate translate-context="Content/*/Link/Verb" key="4">Select only current page</translate>
+                    </a>
+                  </template>
+                </div>
               </div>
-              <div class="field">
-                <dangerous-button
-                  v-if="selectAll || currentAction.isDangerous" :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']"
-                  confirm-color="green"
-                  color=""
-                  @confirm="launchAction">
-                  <translate>Go</translate>
-                  <p slot="modal-header">
-                    <translate
-                      key="1"
-                      :translate-n="affectedObjectsCount"
-                      :translate-params="{count: affectedObjectsCount, action: currentActionName}"
-                      translate-plural="Do you want to launch %{ action } on %{ count } elements?">
-                      Do you want to launch %{ action } on %{ count } element?
-                    </translate>
-                  </p>
-                  <p slot="modal-content">
-                    <translate>This may affect a lot of elements or have irreversible consequences, please double check this is really what you want.</translate>
-                  </p>
-                  <p slot="modal-confirm"><translate>Launch</translate></p>
-                </dangerous-button>
-                <div
-                  v-else
-                  @click="launchAction"
-                  :disabled="checked.length === 0"
-                  :class="['ui', {disabled: checked.length === 0}, {'loading': actionLoading}, 'button']">
-                  <translate>Go</translate></div>
+              <div v-if="actionErrors.length > 0" class="ui negative message">
+                <div class="header"><translate translate-context="Content/*/Error message/Header">Error while applying action</translate></div>
+                <ul class="list">
+                  <li v-for="error in actionErrors">{{ error }}</li>
+                </ul>
               </div>
-              <div class="count field">
-                <translate
-                  tag="span"
-                  v-if="selectAll"
-                  key="1"
-                  :translate-n="objectsData.count"
-                  :translate-params="{count: objectsData.count, total: objectsData.count}"
-                  translate-plural="%{ count } on %{ total } selected">
-                  %{ count } on %{ total } selected
-                </translate>
-                <translate
-                  tag="span"
-                  v-else
-                  key="2"
-                  :translate-n="checked.length"
-                  :translate-params="{count: checked.length, total: objectsData.count}"
-                  translate-plural="%{ count } on %{ total } selected">
-                  %{ count } on %{ total } selected
-                </translate>
-                <template v-if="currentAction.allowAll && checkable.length > 0 && checkable.length === checked.length">
-                  <a @click="selectAll = true" v-if="!selectAll">
-                    <translate
-                      key="3"
-                      :translate-n="objectsData.count"
-                      :translate-params="{total: objectsData.count}"
-                      translate-plural="Select all %{ total } elements">
-                      Select all %{ total } elements
-                    </translate>
-                  </a>
-                  <a @click="selectAll = false" v-else>
-                    <translate key="4">Select only current page</translate>
-                  </a>
-                </template>
+              <div v-if="actionResult" class="ui positive message">
+                <p>
+                  <translate translate-context="Content/*/Paragraph"
+                    :translate-n="actionResult.updated"
+                    :translate-params="{count: actionResult.updated, action: actionResult.action}"
+                    translate-plural="Action %{ action } was launched successfully on %{ count } elements">
+                    Action %{ action } was launched successfully on %{ count } element
+                  </translate>
+                </p>
+
+                <slot name="action-success-footer" :result="actionResult">
+                </slot>
               </div>
             </div>
-            <div v-if="actionErrors.length > 0" class="ui negative message">
-              <div class="header"><translate>Error while applying action</translate></div>
-              <ul class="list">
-                <li v-for="error in actionErrors">{{ error }}</li>
-              </ul>
-            </div>
-            <div v-if="actionResult" class="ui positive message">
-              <p>
-                <translate
-                  :translate-n="actionResult.updated"
-                  :translate-params="{count: actionResult.updated, action: actionResult.action}"
-                  translate-plural="Action %{ action } was launched successfully on %{ count } elements">
-                  Action %{ action } was launched successfully on %{ count } element
-                </translate>
-              </p>
-
-              <slot name="action-success-footer" :result="actionResult">
-              </slot>
+          </th>
+        </tr>
+        <tr>
+          <th v-if="actions.length > 0">
+            <div class="ui checkbox">
+              <input
+                type="checkbox"
+                @change="toggleCheckAll"
+                :disabled="checkable.length === 0"
+                :checked="checkable.length > 0 && checked.length === checkable.length"><label>&nbsp;</label>
             </div>
-          </div>
-        </th>
-      </tr>
-      <tr>
-        <th v-if="actions.length > 0">
-          <div class="ui checkbox">
+          </th>
+          <slot name="header-cells"></slot>
+        </tr>
+      </thead>
+      <tbody v-if="objectsData.count > 0">
+        <tr v-for="(obj, index) in objects">
+          <td v-if="actions.length > 0" class="collapsing">
             <input
               type="checkbox"
-              @change="toggleCheckAll"
-              :disabled="checkable.length === 0"
-              :checked="checkable.length > 0 && checked.length === checkable.length"><label>&nbsp;</label>
-          </div>
-        </th>
-        <slot name="header-cells"></slot>
-      </tr>
-    </thead>
-    <tbody v-if="objectsData.count > 0">
-      <tr v-for="(obj, index) in objects">
-        <td v-if="actions.length > 0" class="collapsing">
-          <input
-            type="checkbox"
-            :disabled="checkable.indexOf(getId(obj)) === -1"
-            @click="toggleCheck($event, getId(obj), index)"
-            :checked="checked.indexOf(getId(obj)) > -1"><label>&nbsp;</label>
-        </td>
-        <slot name="row-cells" :obj="obj"></slot>
-      </tr>
-    </tbody>
-  </table>
+              :disabled="checkable.indexOf(getId(obj)) === -1"
+              @click="toggleCheck($event, getId(obj), index)"
+              :checked="checked.indexOf(getId(obj)) > -1"><label>&nbsp;</label>
+          </td>
+          <slot name="row-cells" :obj="obj"></slot>
+        </tr>
+      </tbody>
+    </table>
+  </div>
 </template>
 <script>
 import axios from 'axios'
@@ -269,7 +272,7 @@ export default {
     },
     labels () {
       return {
-        refresh: this.$gettext('Refresh table content')
+        refresh: this.$pgettext('Content/*/Button.Tooltip/Verb', 'Refresh table content')
       }
     },
     affectedObjectsCount () {
diff --git a/front/src/components/common/CopyInput.vue b/front/src/components/common/CopyInput.vue
index af82f2c661aec207bbae6208d192ca4376dc02b6..415b2fc9bcd88e84aa8e87b996c04808eb6a922b 100644
--- a/front/src/components/common/CopyInput.vue
+++ b/front/src/components/common/CopyInput.vue
@@ -1,12 +1,12 @@
 <template>
   <div class="ui fluid action input">
     <p class="message" v-if="copied">
-      <translate>Text copied to clipboard!</translate>
+      <translate translate-context="Content/*/Paragraph">Text copied to clipboard!</translate>
     </p>
     <input ref="input" :value="value" type="text">
     <button @click="copy" :class="['ui', buttonClasses, 'right', 'labeled', 'icon', 'button']">
       <i class="copy icon"></i>
-      <translate>Copy</translate>
+      <translate translate-context="*/*/Button.Label/Short, Verb">Copy</translate>
     </button>
   </div>
 </template>
diff --git a/front/src/components/common/DangerousButton.vue b/front/src/components/common/DangerousButton.vue
index e6139203a7c6f96e1eb1fc57ec498b7318643590..502accf0f9acc8813cfbd4587c199ac8a118b907 100644
--- a/front/src/components/common/DangerousButton.vue
+++ b/front/src/components/common/DangerousButton.vue
@@ -5,7 +5,7 @@
     <modal class="small" :show.sync="showModal">
       <div class="header">
         <slot name="modal-header">
-          <translate>Do you want to confirm this action?</translate>
+          <translate translate-context="Modal/*/Title">Do you want to confirm this action?</translate>
         </slot>
       </div>
       <div class="scrolling content">
@@ -15,11 +15,11 @@
       </div>
       <div class="actions">
         <div class="ui cancel button">
-          <translate>Cancel</translate>
+          <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
         </div>
         <div :class="['ui', 'confirm', confirmButtonColor, 'button']" @click="confirm">
           <slot name="modal-confirm">
-            <translate>Confirm</translate>
+            <translate translate-context="Modal/*/Button.Label/Short, Verb">Confirm</translate>
           </slot>
         </div>
       </div>
diff --git a/front/src/components/common/Duration.vue b/front/src/components/common/Duration.vue
index 85b070fcd4f18a121e6ce76bdc52bf6fd9762e51..4ee8ccfd168ead2571caaabc33094d3ce43b7d55 100644
--- a/front/src/components/common/Duration.vue
+++ b/front/src/components/common/Duration.vue
@@ -1,9 +1,9 @@
 <template>
   <span>
-    <translate
+    <translate translate-context="Content/*/Paragraph"
       v-if="durationData.hours > 0"
       :translate-params="{minutes: durationData.minutes, hours: durationData.hours}">%{ hours } h %{ minutes } min</translate>
-    <translate
+    <translate translate-context="Content/*/Paragraph"
       v-else
       :translate-params="{minutes: durationData.minutes}">%{ minutes } min</translate>
   </span>
diff --git a/front/src/components/common/EmptyState.vue b/front/src/components/common/EmptyState.vue
new file mode 100644
index 0000000000000000000000000000000000000000..862700679e2a5e9db60d756d26f6081fdb7d9b7a
--- /dev/null
+++ b/front/src/components/common/EmptyState.vue
@@ -0,0 +1,40 @@
+<template>
+  <div class="ui small placeholder segment">
+    <div class="ui header">
+      <div class="content">
+        <slot name="title">
+
+          <i class="search icon"></i>
+          <translate translate-context="Content/*/Paragraph">
+            No results were found.
+          </translate>
+        </slot>
+      </div>
+    </div>
+    <div class="inline">
+      <slot></slot>
+      <button v-if="refresh" class="ui button" @click="$emit('refresh')">
+        <translate translate-context="Content/*/Button.Label/Short, Verb">
+          Refresh
+        </translate></button>
+      </button>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    refresh: {type: Boolean, default: false}
+  }
+}
+</script>
+
+<style scoped>
+.ui.small.placeholder.segment {
+  min-height: auto;
+}
+.ui.header .content {
+  text-align: center;
+  display: block;
+}
+</style>
diff --git a/front/src/components/common/HumanDate.vue b/front/src/components/common/HumanDate.vue
index eed245ea6ce1538d9b0afcd9bcd6297e5695f3a7..fde04f141399428ff413154775ce51eada0d0623 100644
--- a/front/src/components/common/HumanDate.vue
+++ b/front/src/components/common/HumanDate.vue
@@ -1,10 +1,16 @@
 <template>
-  <time :datetime="date" :title="date | moment">{{ realDate | ago($store.state.ui.momentLocale) }}</time>
+  <time :datetime="date" :title="date | moment">
+    <i v-if="icon" class="outline clock icon"></i>
+    {{ realDate | ago($store.state.ui.momentLocale) }}
+  </time>
 </template>
 <script>
 import {mapState} from 'vuex'
 export default {
-  props: ['date'],
+  props: {
+    date: {required: true},
+    icon: {type: Boolean, required: false, default: false},
+  },
   computed: {
     ...mapState({
       lastDate: state => state.ui.lastDate
diff --git a/front/src/components/favorites/List.vue b/front/src/components/favorites/List.vue
index 8015b96762a634e85d4815d01e13b45fce908341..d1bde0935341934af4988c64d1ec766d8da22c9b 100644
--- a/front/src/components/favorites/List.vue
+++ b/front/src/components/favorites/List.vue
@@ -3,7 +3,7 @@
     <section class="ui vertical center aligned stripe segment">
       <div :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
         <div class="ui text loader">
-          <translate>Loading your favorites…</translate>
+          <translate translate-context="Content/Favorites/Message">Loading your favorites…</translate>
         </div>
       </div>
       <h2 v-if="results" class="ui center aligned icon header">
@@ -11,7 +11,8 @@
         <translate
           translate-plural="%{ count } favorites"
           :translate-n="$store.state.favorites.count"
-          :translate-params="{count: results.count}">
+          :translate-params="{count: results.count}"
+          translate-context="Content/Favorites/Title">
           1 favorite
         </translate>
       </h2>
@@ -21,7 +22,7 @@
       <div :class="['ui', {'loading': isLoading}, 'form']">
         <div class="fields">
           <div class="field">
-            <label><translate>Ordering</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
             <select class="ui dropdown" v-model="ordering">
               <option v-for="option in orderingOptions" :value="option[0]">
                 {{ sharedLabels.filters[option[1]] }}
@@ -29,14 +30,14 @@
             </select>
           </div>
           <div class="field">
-            <label><translate>Order</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Order</translate></label>
             <select class="ui dropdown" v-model="orderingDirection">
-              <option value="+"><translate>Ascending</translate></option>
-              <option value="-"><translate>Descending</translate></option>
+              <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+              <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
             </select>
           </div>
           <div class="field">
-            <label><translate>Results per page</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Results per page</translate></label>
             <select class="ui dropdown" v-model="paginateBy">
               <option :value="parseInt(12)">12</option>
               <option :value="parseInt(25)">25</option>
@@ -112,7 +113,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Your Favorites")
+        title: this.$pgettext('Head/Favorites/Title', 'Your Favorites')
       }
     }
   },
diff --git a/front/src/components/favorites/TrackFavoriteIcon.vue b/front/src/components/favorites/TrackFavoriteIcon.vue
index 690dab21b67f0f2e742ed236564331dbfabfcfca..e6cde2265390f99a9b8553951a3e896cd3e186f8 100644
--- a/front/src/components/favorites/TrackFavoriteIcon.vue
+++ b/front/src/components/favorites/TrackFavoriteIcon.vue
@@ -1,8 +1,8 @@
  <template>
-  <button @click="$store.dispatch('favorites/toggle', track.id)" v-if="button" :class="['ui', 'pink', {'inverted': isFavorite}, {'favorited': isFavorite}, 'button']">
+  <button @click="$store.dispatch('favorites/toggle', track.id)" v-if="button" :class="['ui', 'pink', {'inverted': isFavorite}, {'favorited': isFavorite}, 'icon', 'labeled', 'button']">
     <i class="heart icon"></i>
-    <translate v-if="isFavorite">In favorites</translate>
-    <translate v-else>Add to favorites</translate>
+    <translate v-if="isFavorite" translate-context="Content/Track/Button.Message">In favorites</translate>
+    <translate v-else translate-context="Content/Track/*/Verb">Add to favorites</translate>
   </button>
   <button
     v-else
@@ -23,9 +23,9 @@ export default {
   computed: {
     title () {
       if (this.isFavorite) {
-        return this.$gettext('Remove from favorites')
+        return this.$pgettext('Content/Track/Icon.Tooltip/Verb', 'Remove from favorites')
       } else {
-        return this.$gettext('Add to favorites')
+        return this.$pgettext('Content/Track/*/Verb', 'Add to favorites')
       }
     },
     isFavorite () {
diff --git a/front/src/components/federation/FetchButton.vue b/front/src/components/federation/FetchButton.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5c7f4b66e2638c7777d4d9783739bd6b11b7504c
--- /dev/null
+++ b/front/src/components/federation/FetchButton.vue
@@ -0,0 +1,157 @@
+<template>
+  <div @click="createFetch" role="button">
+    <div>
+      <slot></slot>
+    </div>
+    <modal class="small" :show.sync="showModal">
+      <h3 class="header">
+        <translate translate-context="Popup/*/Title">Refreshing object from remote…</translate>
+      </h3>
+      <div class="scrolling content">
+        <template v-if="fetch && fetch.status != 'pending'">
+          <div v-if="fetch.status === 'skipped'" class="ui message">
+            <div class="header"><translate translate-context="Popup/*/Message.Title">Refresh was skipped</translate></div>
+            <p><translate translate-context="Popup/*/Message.Content">The remote server answered, but returned data was unsupported by Funkwhale.</translate></p>
+          </div>
+          <div v-else-if="fetch.status === 'finished'" class="ui success message">
+            <div class="header"><translate translate-context="Popup/*/Message.Title">Refresh successful</translate></div>
+            <p><translate translate-context="Popup/*/Message.Content">Data was refreshed successfully from remote server.</translate></p>
+          </div>
+          <div v-else-if="fetch.status === 'errored'" class="ui error message">
+            <div class="header"><translate translate-context="Popup/*/Message.Title">Refresh error</translate></div>
+            <p><translate translate-context="Popup/*/Message.Content">An error occured while trying to refresh data:</translate></p>
+            <table class="ui very basic collapsing celled table">
+              <tbody>
+                <tr>
+                  <td>
+                    <translate translate-context="Popup/Import/Table.Label/Noun">Error type</translate>
+                  </td>
+                  <td>
+                    {{ fetch.detail.error_code }}
+                  </td>
+                </tr>
+                <tr>
+                  <td>
+                    <translate translate-context="Popup/Import/Table.Label/Noun">Error detail</translate>
+                  </td>
+                  <td>
+                    <translate
+                      v-if="fetch.detail.error_code === 'http' && fetch.detail.status_code"
+                      :translate-params="{status: fetch.detail.status_code}"
+                      translate-context="*/*/Error">The remote server answered with HTTP %{ status }</translate>
+                    <translate
+                      v-else-if="['http', 'request'].indexOf(fetch.detail.error_code) > -1"
+                      translate-context="*/*/Error">An HTTP error occured while contacting the remote server</translate>
+                    <translate
+                      v-else-if="fetch.detail.error_code === 'timeout'"
+                      translate-context="*/*/Error">The remote server didn't answered fast enough</translate>
+                    <translate
+                      v-else-if="fetch.detail.error_code === 'connection'"
+                      translate-context="*/*/Error">Impossible to connect to the remote server</translate>
+                    <translate
+                      v-else-if="['invalid_json', 'invalid_jsonld', 'missing_jsonld_type'].indexOf(fetch.detail.error_code) > -1"
+                      translate-context="*/*/Error">The return server returned invalid JSON or JSON-LD data</translate>
+                    <translate v-else-if="fetch.detail.error_code === 'validation'" translate-context="*/*/Error">Data returned by the remote server had invalid or missing attributes</translate>
+                    <translate v-else-if="fetch.detail.error_code === 'unhandled'" translate-context="*/*/Error">Unknowkn error</translate>
+                    <translate v-else translate-context="*/*/Error">Unknowkn error</translate>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+        </template>
+        <div v-else-if="isCreatingFetch" class="ui active inverted dimmer">
+          <div class="ui text loader">
+            <translate translate-context="Popup/*/Loading.Title">Requesting a fetch…</translate>
+          </div>
+        </div>
+        <div v-else-if="isWaitingFetch" class="ui active inverted dimmer">
+          <div class="ui text loader">
+            <translate translate-context="Popup/*/Loading.Title">Waiting for result…</translate>
+          </div>
+        </div>
+        <div v-if="errors.length > 0" class="ui negative message">
+          <div class="header"><translate translate-context="Content/*/Error message.Title">Error while saving settings</translate></div>
+          <ul class="list">
+            <li v-for="error in errors">{{ error }}</li>
+          </ul>
+        </div>
+        <div v-else-if="fetch && fetch.status === 'pending' && pollsCount >= maxPolls" class="ui warning message">
+          <div class="header"><translate translate-context="Popup/*/Message.Title">Refresh pending</translate></div>
+          <p><translate translate-context="Popup/*/Message.Content">Refresh request wasn't proceed in time by our server. It will be processed later.</translate></p>
+        </div>
+      </div>
+      <div class="actions">
+        <div role="button" class="ui cancel button">
+          <translate translate-context="*/*/Button.Label/Verb">Close</translate>
+        </div>
+        <div role="button" @click="showModal = false; $emit('refresh')" class="ui confirm green button" v-if="fetch && fetch.status === 'finished'">
+          <translate translate-context="*/*/Button.Label/Verb">Close and reload page</translate>
+        </div>
+      </div>
+    </modal>
+  </div>
+</template>
+
+<script>
+import axios from "axios"
+import Modal from '@/components/semantic/Modal'
+
+export default {
+  props: ['url'],
+  components: {
+    Modal
+  },
+  data () {
+    return {
+      fetch: null,
+      isCreatingFetch: false,
+      errors: [],
+      showModal: false,
+      isWaitingFetch: false,
+      maxPolls: 15,
+      pollsCount: 0,
+    }
+  },
+  methods: {
+    createFetch () {
+      let self = this
+      this.fetch = null
+      this.pollsCount = 0
+      this.errors = []
+      this.isCreatingFetch = true
+      this.isWaitingFetch = false
+      self.showModal = true
+      axios.post(this.url).then((response) => {
+        self.isCreatingFetch = false
+        self.fetch = response.data
+        self.pollFetch()
+      }, (error) => {
+        self.isCreatingFetch = false
+        self.errors = error.backendErrors
+      })
+    },
+    pollFetch () {
+      this.isWaitingFetch = true
+      this.pollsCount += 1
+      let url = `federation/fetches/${this.fetch.id}/`
+      let self = this
+      self.showModal = true
+      axios.get(url).then((response) => {
+        self.isCreatingFetch = false
+        self.fetch = response.data
+        if (self.fetch.status === 'pending' && self.pollsCount < self.maxPolls) {
+          setTimeout(() => {
+            self.pollFetch()
+          }, 1000)
+        } else {
+          self.isWaitingFetch = false
+        }
+      }, (error) => {
+        self.errors = error.backendErrors
+        self.isWaitingFetch = false
+      })
+    }
+  }
+}
+</script>
diff --git a/front/src/components/federation/LibraryWidget.vue b/front/src/components/federation/LibraryWidget.vue
index b9554d01ff36b235456dcf467647683ae769992b..7d24180879a70222cfefd18d4789953270af0f22 100644
--- a/front/src/components/federation/LibraryWidget.vue
+++ b/front/src/components/federation/LibraryWidget.vue
@@ -4,7 +4,7 @@
       <slot name="title"></slot>
     </h3>
     <p v-if="!isLoading && libraries.length > 0" class="ui subtitle"><slot name="subtitle"></slot></p>
-    <p v-if="!isLoading && libraries.length === 0" class="ui subtitle"><translate>No matching library.</translate></p>
+    <p v-if="!isLoading && libraries.length === 0" class="ui subtitle"><translate translate-context="Content/Federation/Paragraph">No matching library.</translate></p>
     <i @click="fetchData(previousPage)" :disabled="!previousPage" :class="['ui', {disabled: !previousPage}, 'circular', 'angle left', 'icon']">
     </i>
     <i @click="fetchData(nextPage)" :disabled="!nextPage" :class="['ui', {disabled: !nextPage}, 'circular', 'angle right', 'icon']">
diff --git a/front/src/components/forms/PasswordInput.vue b/front/src/components/forms/PasswordInput.vue
index 26454048e41ff328bf26e9288af6091fe9c8e050..d57e3017f3010000e6e45932e25e2092982ef246 100644
--- a/front/src/components/forms/PasswordInput.vue
+++ b/front/src/components/forms/PasswordInput.vue
@@ -23,7 +23,7 @@ export default {
   computed: {
     labels () {
       return {
-        title: this.$gettext('Show/hide password')
+        title: this.$pgettext('Content/Settings/Button.Tooltip/Verb', 'Show/hide password')
       }
     },
     passwordInputType () {
diff --git a/front/src/components/globals.js b/front/src/components/globals.js
index 99e57095c0735a96c55d99e8fd00827203eaa929..711b227ae956a8943c8085087b0215029a50499d 100644
--- a/front/src/components/globals.js
+++ b/front/src/components/globals.js
@@ -44,5 +44,8 @@ import Tooltip from '@/components/common/Tooltip'
 
 Vue.component('tooltip', Tooltip)
 
+import EmptyState from '@/components/common/EmptyState'
+
+Vue.component('empty-state', EmptyState)
 
 export default {}
diff --git a/front/src/components/instance/Stats.vue b/front/src/components/instance/Stats.vue
index 78632f6d23fa38702d1edefd78527bfd2d762f22..9b08d2f3718537ec025d17c3f1350986e5745089 100644
--- a/front/src/components/instance/Stats.vue
+++ b/front/src/components/instance/Stats.vue
@@ -3,7 +3,7 @@
     <div v-if="stats" class="ui stackable two column grid">
       <div class="column">
         <h3 class="ui left aligned header">
-          <translate>User activity</translate>
+          <translate translate-context="Content/About/Title/Noun">User activity</translate>
         </h3>
         <div v-if="stats" class="ui mini horizontal statistics">
           <div class="statistic">
@@ -11,48 +11,48 @@
               <i class="green user icon"></i>
               {{ stats.users }}
             </div>
-            <div class="label"><translate>users</translate></div>
+            <div class="label"><translate translate-context="Content/About/Paragraph/Unit">users</translate></div>
           </div>
           <div class="statistic">
             <div class="value">
               <i class="orange sound icon"></i> {{ stats.listenings }}
             </div>
-            <div class="label"><translate>tracks listened</translate></div>
+            <div class="label"><translate translate-context="Content/About/Paragraph/Unit">tracks listened</translate></div>
           </div>
           <div class="statistic">
             <div class="value">
               <i class="pink heart icon"></i> {{ stats.trackFavorites }}
             </div>
-            <div class="label"><translate>Tracks favorited</translate></div>
+            <div class="label"><translate translate-context="Content/About/Paragraph/Unit">Tracks favorited</translate></div>
           </div>
         </div>
       </div>
       <div class="column">
-        <h3 class="ui left aligned header"><translate>Library</translate></h3>
+        <h3 class="ui left aligned header"><translate translate-context="*/*/*">Library</translate></h3>
         <div class="ui mini horizontal statistics">
           <div class="statistic">
             <div class="value">
               {{ parseInt(stats.musicDuration) }}
             </div>
-            <div class="label"><translate>Hours of music</translate></div>
+            <div class="label"><translate translate-context="Content/About/Paragraph/Unit">Hours of music</translate></div>
           </div>
           <div class="statistic">
             <div class="value">
               {{ stats.artists }}
             </div>
-            <div class="label"><translate>Artists</translate></div>
+            <div class="label"><translate translate-context="*/*/*/Noun">Artists</translate></div>
           </div>
           <div class="statistic">
             <div class="value">
               {{ stats.albums }}
             </div>
-            <div class="label"><translate>Albums</translate></div>
+            <div class="label"><translate translate-context="*/*/*">Albums</translate></div>
           </div>
           <div class="statistic">
             <div class="value">
               {{ stats.tracks }}
             </div>
-            <div class="label"><translate>tracks</translate></div>
+            <div class="label"><translate translate-context="*/*/*/Noun">Tracks</translate></div>
           </div>
         </div>
       </div>
diff --git a/front/src/components/library/Album.vue b/front/src/components/library/Album.vue
deleted file mode 100644
index bb33b7e7fa52c1eaf6c4ed0f630788faf0a25e6e..0000000000000000000000000000000000000000
--- a/front/src/components/library/Album.vue
+++ /dev/null
@@ -1,197 +0,0 @@
-<template>
-  <main>
-    <div v-if="isLoading" class="ui vertical segment" v-title="">
-      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
-    </div>
-    <template v-if="album">
-      <section :class="['ui', 'head', {'with-background': album.cover.original}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle" v-title="album.title">
-        <div class="segment-content">
-          <h2 class="ui center aligned icon header">
-            <i class="circular inverted sound yellow icon"></i>
-            <div class="content">
-              {{ album.title }}
-              <div v-html="subtitle"></div>
-            </div>
-            <div class="ui buttons">
-              <router-link class="ui button" :to="{name: 'library.artists.detail', params: {id: album.artist.id }}">
-                <translate>Artist page</translate>
-              </router-link>
-            </div>
-          </h2>
-          <div class="ui hidden divider"></div>
-          <play-button class="orange" :tracks="album.tracks">
-            <translate>Play all</translate>
-          </play-button>
-
-          <a :href="wikipediaUrl" target="_blank" class="ui button">
-            <i class="wikipedia w icon"></i>
-            <translate>Search on Wikipedia</translate>
-          </a>
-          <a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" class="ui button">
-            <i class="external icon"></i>
-            <translate>View on MusicBrainz</translate>
-          </a>
-          <template v-if="publicLibraries.length > 0">
-            <button
-              @click="showEmbedModal = !showEmbedModal"
-              class="ui button">
-              <i class="code icon"></i>
-              <translate>Embed</translate>
-            </button>
-            <modal :show.sync="showEmbedModal">
-              <div class="header">
-                <translate>Embed this album on your website</translate>
-              </div>
-              <div class="content">
-                <div class="description">
-                  <embed-wizard type="album" :id="album.id" />
-
-                </div>
-              </div>
-              <div class="actions">
-                <div class="ui deny button">
-                  <translate>Cancel</translate>
-                </div>
-              </div>
-            </modal>
-          </template>
-        </div>
-      </section>
-      <template v-if="discs && discs.length > 1">
-        <section v-for="(tracks, disc_number) in discs" class="ui vertical stripe segment">
-          <translate
-            tag="h2"
-            class="left floated"
-            :translate-params="{number: disc_number + 1}"
-          >Volume %{ number }</translate>
-          <play-button class="right floated orange" :tracks="tracks">
-            <translate>Play all</translate>
-          </play-button>
-          <track-table :artist="album.artist" :display-position="true" :tracks="tracks"></track-table>
-        </section>
-      </template>
-      <template v-else>
-        <section class="ui vertical stripe segment">
-          <h2>
-            <translate>Tracks</translate>
-          </h2>
-          <track-table v-if="album" :artist="album.artist" :display-position="true" :tracks="album.tracks"></track-table>
-        </section>
-      </template>
-      <section class="ui vertical stripe segment">
-        <h2>
-          <translate>User libraries</translate>
-        </h2>
-        <library-widget @loaded="libraries = $event" :url="'albums/' + id + '/libraries/'">
-          <translate slot="subtitle">This album is present in the following libraries:</translate>
-        </library-widget>
-      </section>
-    </template>
-  </main>
-</template>
-
-<script>
-import axios from "axios"
-import logger from "@/logging"
-import backend from "@/audio/backend"
-import PlayButton from "@/components/audio/PlayButton"
-import TrackTable from "@/components/audio/track/Table"
-import LibraryWidget from "@/components/federation/LibraryWidget"
-import EmbedWizard from "@/components/audio/EmbedWizard"
-import Modal from '@/components/semantic/Modal'
-
-const FETCH_URL = "albums/"
-
-function groupByDisc(acc, track) {
-  var dn = track.disc_number - 1
-  if (dn < 0) dn = 0
-  if (acc[dn] == undefined) {
-    acc.push([track])
-  } else {
-    acc[dn].push(track)
-  }
-  return acc
-}
-
-export default {
-  props: ["id"],
-  components: {
-    PlayButton,
-    TrackTable,
-    LibraryWidget,
-    EmbedWizard,
-    Modal
-  },
-  data() {
-    return {
-      isLoading: true,
-      album: null,
-      discs: [],
-      libraries: [],
-      showEmbedModal: false
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      var self = this
-      this.isLoading = true
-      let url = FETCH_URL + this.id + "/"
-      logger.default.debug('Fetching album "' + this.id + '"')
-      axios.get(url).then(response => {
-        self.album = backend.Album.clean(response.data)
-        self.discs = self.album.tracks.reduce(groupByDisc, [])
-        self.isLoading = false
-      })
-    }
-  },
-  computed: {
-    labels() {
-      return {
-        title: this.$gettext("Album")
-      }
-    },
-    publicLibraries () {
-      return this.libraries.filter(l => {
-        return l.privacy_level === 'everyone'
-      })
-    },
-    wikipediaUrl() {
-      return (
-        "https://en.wikipedia.org/w/index.php?search=" +
-        encodeURI(this.album.title + " " + this.album.artist.name)
-      )
-    },
-    musicbrainzUrl() {
-      if (this.album.mbid) {
-        return "https://musicbrainz.org/release/" + this.album.mbid
-      }
-    },
-    headerStyle() {
-      if (!this.album.cover.original) {
-        return ""
-      }
-      return (
-        "background-image: url(" +
-        this.$store.getters["instance/absoluteUrl"](this.album.cover.original) +
-        ")"
-      )
-    },
-    subtitle () {
-      let msg = this.$ngettext('Album containing %{ count } track, by %{ artist }', 'Album containing %{ count } tracks, by %{ artist }', this.album.tracks.length)
-      return this.$gettextInterpolate(msg, {count: this.album.tracks.length, artist: this.album.artist.name})
-    }
-  },
-  watch: {
-    id() {
-      this.fetchData()
-    }
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="scss">
-</style>
diff --git a/front/src/components/library/AlbumBase.vue b/front/src/components/library/AlbumBase.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1f89bef8898f9a1a496545688ff818a10e071e2a
--- /dev/null
+++ b/front/src/components/library/AlbumBase.vue
@@ -0,0 +1,193 @@
+<template>
+  <main>
+    <div v-if="isLoading" class="ui vertical segment" v-title="labels.title">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object">
+      <section :class="['ui', 'head', {'with-background': object.cover.original}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle" v-title="object.title">
+        <div class="segment-content">
+          <h2 class="ui center aligned icon header">
+            <i class="circular inverted sound yellow icon"></i>
+            <div class="content">
+              {{ object.title }}
+              <div v-html="subtitle"></div>
+            </div>
+          </h2>
+          <div class="ui hidden divider"></div>
+          <div class="header-buttons">
+
+            <div class="ui buttons">
+              <play-button class="orange" :tracks="object.tracks">
+                <translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
+              </play-button>
+            </div>
+
+            <modal v-if="publicLibraries.length > 0" :show.sync="showEmbedModal">
+              <div class="header">
+                <translate translate-context="Popup/Album/Title/Verb">Embed this album on your website</translate>
+              </div>
+              <div class="content">
+                <div class="description">
+                  <embed-wizard type="album" :id="object.id" />
+
+                </div>
+              </div>
+              <div class="actions">
+                <div class="ui deny button">
+                  <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
+                </div>
+              </div>
+            </modal>
+            <div class="ui buttons">
+              <button class="ui button" @click="$refs.dropdown.click()">
+                <translate translate-context="*/*/Button.Label/Noun">More…</translate>
+              </button>
+              <div class="ui floating dropdown icon button" ref="dropdown" v-dropdown>
+                <i class="dropdown icon"></i>
+                <div class="menu">
+                  <div
+                    role="button"
+                    v-if="publicLibraries.length > 0"
+                    @click="showEmbedModal = !showEmbedModal"
+                    class="basic item">
+                    <i class="code icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Embed</translate>
+                  </div>
+                  <a :href="wikipediaUrl" target="_blank" rel="noreferrer noopener" class="basic item">
+                    <i class="wikipedia w icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Search on Wikipedia</translate>
+                  </a>
+                  <a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" rel="noreferrer noopener" class="basic item">
+                    <i class="external icon"></i>
+                    <translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
+                  </a>
+                  <router-link
+                    v-if="object.is_local"
+                    :to="{name: 'library.albums.edit', params: {id: object.id }}"
+                    class="basic item">
+                    <i class="edit icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
+                  </router-link>
+                  <div class="divider"></div>
+                  <router-link class="basic item" v-if="$store.state.auth.availablePermissions['library']" :to="{name: 'manage.library.albums.detail', params: {id: object.id}}">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link">Open in moderation interface</translate>
+                  </router-link>
+                  <a
+                    v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="basic item"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/album/${object.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <router-view v-if="object" :discs="discs" @libraries-loaded="libraries = $event" :object="object" object-type="album" :key="$route.fullPath"></router-view>
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+import backend from "@/audio/backend"
+import PlayButton from "@/components/audio/PlayButton"
+import EmbedWizard from "@/components/audio/EmbedWizard"
+import Modal from '@/components/semantic/Modal'
+
+const FETCH_URL = "albums/"
+
+
+function groupByDisc(acc, track) {
+  var dn = track.disc_number - 1
+  if (dn < 0) dn = 0
+  if (acc[dn] == undefined) {
+    acc.push([track])
+  } else {
+    acc[dn].push(track)
+  }
+  return acc
+}
+
+export default {
+  props: ["id"],
+  components: {
+    PlayButton,
+    EmbedWizard,
+    Modal
+  },
+  data() {
+    return {
+      isLoading: true,
+      object: null,
+      discs: [],
+      libraries: [],
+      showEmbedModal: false
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoading = true
+      let url = FETCH_URL + this.id + "/"
+      logger.default.debug('Fetching album "' + this.id + '"')
+      axios.get(url).then(response => {
+        self.object = backend.Album.clean(response.data)
+        self.discs = self.object.tracks.reduce(groupByDisc, [])
+        self.isLoading = false
+      })
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Album')
+      }
+    },
+    publicLibraries () {
+      return this.libraries.filter(l => {
+        return l.privacy_level === 'everyone'
+      })
+    },
+    wikipediaUrl() {
+      return (
+        "https://en.wikipedia.org/w/index.php?search=" +
+        encodeURI(this.object.title + " " + this.object.artist.name)
+      )
+    },
+    musicbrainzUrl() {
+      if (this.object.mbid) {
+        return "https://musicbrainz.org/release/" + this.object.mbid
+      }
+    },
+    headerStyle() {
+      if (!this.object.cover.original) {
+        return ""
+      }
+      return (
+        "background-image: url(" +
+        this.$store.getters["instance/absoluteUrl"](this.object.cover.original) +
+        ")"
+      )
+    },
+    subtitle () {
+      let route = this.$router.resolve({name: 'library.artists.detail', params: {id: this.object.artist.id }})
+      let msg = this.$npgettext('Content/Album/Header.Title', 'Album containing %{ count } track, by <a class="internal" href="%{ artistUrl }">%{ artist }</a>', 'Album containing %{ count } tracks, by <a class="internal" href="%{ artistUrl }">%{ artist }</a>', this.object.tracks.length)
+      return this.$gettextInterpolate(msg, {count: this.object.tracks.length, artist: this.object.artist.name, artistUrl: route.location.path})
+    }
+  },
+  watch: {
+    id() {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/AlbumDetail.vue b/front/src/components/library/AlbumDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..d695b6e596b3d46de95774d8191f18e7309bb277
--- /dev/null
+++ b/front/src/components/library/AlbumDetail.vue
@@ -0,0 +1,62 @@
+<template>
+  <div v-if="object">
+    <template v-if="discs && discs.length > 1">
+      <section v-for="(tracks, disc_number) in discs" class="ui vertical stripe segment">
+        <translate
+          tag="h2"
+          class="left floated"
+          :translate-params="{number: disc_number + 1}"
+          translate-context="Content/Album/"
+        >Volume %{ number }</translate>
+        <play-button class="right floated orange" :tracks="tracks">
+          <translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
+        </play-button>
+        <track-table :artist="object.artist" :display-position="true" :tracks="tracks"></track-table>
+      </section>
+    </template>
+    <template v-else>
+      <section class="ui vertical stripe segment">
+        <h2>
+          <translate translate-context="*/*/*/Noun">Tracks</translate>
+        </h2>
+        <track-table v-if="object" :artist="object.artist" :display-position="true" :tracks="object.tracks"></track-table>
+      </section>
+    </template>
+    <section class="ui vertical stripe segment">
+      <h2>
+        <translate translate-context="Content/*/Title/Noun">User libraries</translate>
+      </h2>
+      <library-widget @loaded="$emit('libraries-loaded', $event)" :url="'albums/' + object.id + '/libraries/'">
+        <translate slot="subtitle" translate-context="Content/Album/Paragraph">This album is present in the following libraries:</translate>
+      </library-widget>
+    </section>
+  </div>
+</template>
+
+<script>
+
+import time from "@/utils/time"
+import axios from "axios"
+import url from "@/utils/url"
+import logger from "@/logging"
+import LibraryWidget from "@/components/federation/LibraryWidget"
+import TrackTable from "@/components/audio/track/Table"
+
+export default {
+  props: ["object", "libraries", "discs"],
+  components: {
+    LibraryWidget,
+    TrackTable
+  },
+  data() {
+    return {
+      time,
+      id: this.object.id,
+    }
+  },
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+</style>
diff --git a/front/src/components/library/AlbumEdit.vue b/front/src/components/library/AlbumEdit.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b7c24737c1dd5e07b737dd1a6e088f1edc179920
--- /dev/null
+++ b/front/src/components/library/AlbumEdit.vue
@@ -0,0 +1,41 @@
+<template>
+
+  <section class="ui vertical stripe segment">
+    <div class="ui text container">
+      <h2>
+        <translate v-if="canEdit" key="1" translate-context="Content/*/Title">Edit this album</translate>
+        <translate v-else key="2" translate-context="Content/*/Title">Suggest an edit on this album</translate>
+      </h2>
+      <div class="ui message" v-if="!object.is_local">
+        <translate translate-context="Content/*/Message">This object is managed by another server, you cannot edit it.</translate>
+      </div>
+      <edit-form
+        v-else
+        :object-type="objectType"
+        :object="object"
+        :can-edit="canEdit"></edit-form>
+    </div>
+  </section>
+</template>
+
+<script>
+import axios from "axios"
+
+import EditForm from '@/components/library/EditForm'
+export default {
+  props: ["objectType", "object", "libraries"],
+  data() {
+    return {
+      id: this.object.id,
+    }
+  },
+  components: {
+    EditForm
+  },
+  computed: {
+    canEdit () {
+      return true
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/Albums.vue b/front/src/components/library/Albums.vue
new file mode 100644
index 0000000000000000000000000000000000000000..9817af830770142065f1e84f4253cbdda23c41e6
--- /dev/null
+++ b/front/src/components/library/Albums.vue
@@ -0,0 +1,189 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <h2 class="ui header">
+        <translate translate-context="Content/Album/Title">Browsing albums</translate>
+      </h2>
+      <div :class="['ui', {'loading': isLoading}, 'form']">
+        <div class="fields">
+          <div class="field">
+            <label>
+              <translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
+            </label>
+            <input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
+          </div>
+          <div class="field">
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
+            <select class="ui dropdown" v-model="ordering">
+              <option v-for="option in orderingOptions" :value="option[0]">
+                {{ sharedLabels.filters[option[1]] }}
+              </option>
+            </select>
+          </div>
+          <div class="field">
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
+            <select class="ui dropdown" v-model="orderingDirection">
+              <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+              <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
+            </select>
+          </div>
+          <div class="field">
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Results per page</translate></label>
+            <select class="ui dropdown" v-model="paginateBy">
+              <option :value="parseInt(12)">12</option>
+              <option :value="parseInt(25)">25</option>
+              <option :value="parseInt(50)">50</option>
+            </select>
+          </div>
+        </div>
+      </div>
+      <div class="ui hidden divider"></div>
+      <div
+        v-if="result"
+        transition-duration="0"
+        item-selector=".column"
+        percent-position="true"
+        stagger="0"
+        class="ui stackable three column doubling grid">
+        <div
+          v-if="result.results.length > 0"
+          class="ui cards">
+          <album-card
+            :mode="'simple'"
+            v-masonry-tile
+            v-for="album in result.results"
+            :key="album.id"
+            :album="album"></album-card>
+        </div>
+      </div>
+      <div class="ui center aligned basic segment">
+        <pagination
+          v-if="result && result.count > paginateBy"
+          @page-changed="selectPage"
+          :current="page"
+          :paginate-by="paginateBy"
+          :total="result.count"
+          ></pagination>
+      </div>
+    </section>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import _ from "@/lodash"
+import $ from "jquery"
+
+import logger from "@/logging"
+
+import OrderingMixin from "@/components/mixins/Ordering"
+import PaginationMixin from "@/components/mixins/Pagination"
+import TranslationsMixin from "@/components/mixins/Translations"
+import AlbumCard from "@/components/audio/album/Card"
+import Pagination from "@/components/Pagination"
+
+const FETCH_URL = "albums/"
+
+export default {
+  mixins: [OrderingMixin, PaginationMixin, TranslationsMixin],
+  props: {
+    defaultQuery: { type: String, required: false, default: "" }
+  },
+  components: {
+    AlbumCard,
+    Pagination
+  },
+  data() {
+    let defaultOrdering = this.getOrderingFromString(
+      this.defaultOrdering || "-creation_date"
+    )
+    return {
+      isLoading: true,
+      result: null,
+      page: parseInt(this.defaultPage),
+      query: this.defaultQuery,
+      paginateBy: parseInt(this.defaultPaginateBy || 25),
+      orderingDirection: defaultOrdering.direction || "+",
+      ordering: defaultOrdering.field,
+      orderingOptions: [["creation_date", "creation_date"], ["title", "album_title"]]
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  mounted() {
+    $(".ui.dropdown").dropdown()
+  },
+  computed: {
+    labels() {
+      let searchPlaceholder = this.$pgettext('Content/Search/Input.Placeholder', "Enter album title...")
+      let title = this.$pgettext('*/*/*', "Albums")
+      return {
+        searchPlaceholder,
+        title
+      }
+    }
+  },
+  methods: {
+    updateQueryString: _.debounce(function() {
+      this.$router.replace({
+        query: {
+          query: this.query,
+          page: this.page,
+          paginateBy: this.paginateBy,
+          ordering: this.getOrderingAsString()
+        }
+      })
+    }, 500),
+    fetchData: _.debounce(function() {
+      var self = this
+      this.isLoading = true
+      let url = FETCH_URL
+      let params = {
+        page: this.page,
+        page_size: this.paginateBy,
+        q: this.query,
+        ordering: this.getOrderingAsString(),
+        playable: "true"
+      }
+      logger.default.debug("Fetching albums")
+      axios.get(url, { params: params }).then(response => {
+        self.result = response.data
+        self.isLoading = false
+      })
+    }, 500),
+    selectPage: function(page) {
+      this.page = page
+    }
+  },
+  watch: {
+    page() {
+      this.updateQueryString()
+      this.fetchData()
+    },
+    paginateBy() {
+      this.updateQueryString()
+      this.fetchData()
+    },
+    ordering() {
+      this.updateQueryString()
+      this.fetchData()
+    },
+    orderingDirection() {
+      this.updateQueryString()
+      this.fetchData()
+    },
+    query() {
+      this.updateQueryString()
+      this.fetchData()
+    },
+    "$store.state.moderation.lastUpdate": function () {
+      this.fetchData()
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/front/src/components/library/Artist.vue b/front/src/components/library/Artist.vue
deleted file mode 100644
index dd2be35ae1b00abba1077e3896d8368213c3f6ae..0000000000000000000000000000000000000000
--- a/front/src/components/library/Artist.vue
+++ /dev/null
@@ -1,195 +0,0 @@
-<template>
-  <main v-title="labels.title">
-    <div v-if="isLoading" class="ui vertical segment">
-      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
-    </div>
-    <template v-if="artist">
-      <section :class="['ui', 'head', {'with-background': cover}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle" v-title="artist.name">
-        <div class="segment-content">
-          <h2 class="ui center aligned icon header">
-            <i class="circular inverted users violet icon"></i>
-            <div class="content">
-              {{ artist.name }}
-              <div class="sub header" v-if="albums">
-                <translate
-                  tag="div"
-                  translate-plural="%{ count } tracks in %{ albumsCount } albums"
-                  :translate-n="totalTracks"
-                  :translate-params="{count: totalTracks, albumsCount: totalAlbums}">
-                  %{ count } track in %{ albumsCount } albums
-                </translate>
-              </div>
-            </div>
-          </h2>
-          <div class="ui hidden divider"></div>
-          <radio-button type="artist" :object-id="artist.id"></radio-button>
-          <play-button :is-playable="isPlayable" class="orange" :artist="artist.id">
-            <translate>Play all albums</translate>
-          </play-button>
-
-          <a :href="wikipediaUrl" target="_blank" class="ui button">
-            <i class="wikipedia w icon"></i>
-            <translate>Search on Wikipedia</translate>
-          </a>
-          <a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" class="ui button">
-            <i class="external icon"></i>
-            <translate>View on MusicBrainz</translate>
-          </a>
-        </div>
-      </section>
-      <section v-if="isLoadingAlbums" class="ui vertical stripe segment">
-        <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
-      </section>
-      <section v-else-if="albums && albums.length > 0" class="ui vertical stripe segment">
-        <h2>
-          <translate>Albums by this artist</translate>
-        </h2>
-        <div class="ui cards" >
-          <album-card :mode="'rich'" :album="album" :key="album.id" v-for="album in albums"></album-card>
-        </div>
-      </section>
-      <section v-if="tracks.length > 0" class="ui vertical stripe segment">
-        <h2>
-          <translate>Tracks by this artist</translate>
-        </h2>
-        <track-table :display-position="true" :tracks="tracks"></track-table>
-      </section>
-      <section class="ui vertical stripe segment">
-        <h2>
-          <translate>User libraries</translate>
-        </h2>
-        <library-widget :url="'artists/' + id + '/libraries/'">
-          <translate slot="subtitle">This artist is present in the following libraries:</translate>
-        </library-widget>
-      </section>
-    </template>
-  </main>
-</template>
-
-<script>
-import _ from "@/lodash"
-import axios from "axios"
-import logger from "@/logging"
-import backend from "@/audio/backend"
-import AlbumCard from "@/components/audio/album/Card"
-import RadioButton from "@/components/radios/Button"
-import PlayButton from "@/components/audio/PlayButton"
-import TrackTable from "@/components/audio/track/Table"
-import LibraryWidget from "@/components/federation/LibraryWidget"
-
-export default {
-  props: ["id"],
-  components: {
-    AlbumCard,
-    RadioButton,
-    PlayButton,
-    TrackTable,
-    LibraryWidget
-  },
-  data() {
-    return {
-      isLoading: true,
-      isLoadingAlbums: true,
-      artist: null,
-      albums: null,
-      totalTracks: 0,
-      totalAlbums: 0,
-      tracks: []
-    }
-  },
-  created() {
-    this.fetchData()
-  },
-  methods: {
-    fetchData() {
-      var self = this
-      this.isLoading = true
-      logger.default.debug('Fetching artist "' + this.id + '"')
-      axios.get("tracks/", { params: { artist: this.id } }).then(response => {
-        self.tracks = response.data.results
-        self.totalTracks = response.data.count
-      })
-      axios.get("artists/" + this.id + "/").then(response => {
-        self.artist = response.data
-        self.isLoading = false
-        self.isLoadingAlbums = true
-        axios
-          .get("albums/", {
-            params: { artist: self.id, ordering: "-release_date" }
-          })
-          .then(response => {
-            self.totalAlbums = response.data.count
-            let parsed = JSON.parse(JSON.stringify(response.data.results))
-            self.albums = parsed.map(album => {
-              return backend.Album.clean(album)
-            })
-
-            self.isLoadingAlbums = false
-          })
-      })
-    }
-  },
-  computed: {
-    labels() {
-      return {
-        title: this.$gettext("Artist")
-      }
-    },
-    isPlayable() {
-      return (
-        this.artist.albums.filter(a => {
-          return a.is_playable
-        }).length > 0
-      )
-    },
-    wikipediaUrl() {
-      return (
-        "https://en.wikipedia.org/w/index.php?search=" +
-        encodeURI(this.artist.name)
-      )
-    },
-    musicbrainzUrl() {
-      if (this.artist.mbid) {
-        return "https://musicbrainz.org/artist/" + this.artist.mbid
-      }
-    },
-    allTracks() {
-      let tracks = []
-      this.albums.forEach(album => {
-        album.tracks.forEach(track => {
-          tracks.push(track)
-        })
-      })
-      return tracks
-    },
-    cover() {
-      return this.artist.albums
-        .filter(album => {
-          return album.cover
-        })
-        .map(album => {
-          return album.cover
-        })[0]
-    },
-    headerStyle() {
-      if (!this.cover || !this.cover.original) {
-        return ""
-      }
-      return (
-        "background-image: url(" +
-        this.$store.getters["instance/absoluteUrl"](this.cover.original) +
-        ")"
-      )
-    }
-  },
-  watch: {
-    id() {
-      this.fetchData()
-    }
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-</style>
diff --git a/front/src/components/library/ArtistBase.vue b/front/src/components/library/ArtistBase.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5da7370bacf5fba3abe0c44aa10eb82d421c4a46
--- /dev/null
+++ b/front/src/components/library/ArtistBase.vue
@@ -0,0 +1,246 @@
+<template>
+  <main v-title="labels.title">
+    <div v-if="isLoading" class="ui vertical segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object && !isLoading">
+      <section :class="['ui', 'head', {'with-background': cover}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle" v-title="object.name">
+        <div class="segment-content">
+          <h2 class="ui center aligned icon header">
+            <i class="circular inverted users violet icon"></i>
+            <div class="content">
+              {{ object.name }}
+              <div class="sub header" v-if="albums">
+                <translate translate-context="Content/Artist/Paragraph"
+                  tag="div"
+                  translate-plural="%{ count } tracks in %{ albumsCount } albums"
+                  :translate-n="totalTracks"
+                  :translate-params="{count: totalTracks, albumsCount: totalAlbums}">
+                  %{ count } track in %{ albumsCount } albums
+                </translate>
+              </div>
+            </div>
+          </h2>
+          <div class="ui hidden divider"></div>
+          <div class="header-buttons">
+            <div class="ui buttons">
+              <radio-button type="artist" :object-id="object.id"></radio-button>
+
+            </div>
+            <div class="ui buttons">
+              <play-button :is-playable="isPlayable" class="orange" :artist="object">
+                <translate translate-context="Content/Artist/Button.Label/Verb">Play all albums</translate>
+              </play-button>
+            </div>
+
+            <modal :show.sync="showEmbedModal" v-if="publicLibraries.length > 0">
+              <div class="header">
+                <translate translate-context="Popup/Artist/Title/Verb">Embed this artist work on your website</translate>
+              </div>
+              <div class="content">
+                <div class="description">
+                  <embed-wizard type="artist" :id="object.id" />
+
+                </div>
+              </div>
+              <div class="actions">
+                <div class="ui deny button">
+                  <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
+                </div>
+              </div>
+            </modal>
+            <div class="ui buttons">
+              <button class="ui button" @click="$refs.dropdown.click()">
+                <translate translate-context="*/*/Button.Label/Noun">More…</translate>
+              </button>
+              <div class="ui floating dropdown icon button" ref="dropdown" v-dropdown>
+                <i class="dropdown icon"></i>
+                <div class="menu">
+                  <div
+                    role="button"
+                    v-if="publicLibraries.length > 0"
+                    @click="showEmbedModal = !showEmbedModal"
+                    class="basic item">
+                    <i class="code icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Embed</translate>
+                  </div>
+                  <a :href="wikipediaUrl" target="_blank" rel="noreferrer noopener" class="basic item">
+                    <i class="wikipedia w icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Search on Wikipedia</translate>
+                  </a>
+                  <a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" rel="noreferrer noopener" class="basic item">
+                    <i class="external icon"></i>
+                    <translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
+                  </a>
+                  <router-link
+                    v-if="object.is_local"
+                    :to="{name: 'library.artists.edit', params: {id: object.id }}"
+                    class="basic item">
+                    <i class="edit icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
+                  </router-link>
+                  <div class="divider"></div>
+                  <router-link class="basic item" v-if="$store.state.auth.availablePermissions['library']" :to="{name: 'manage.library.artists.detail', params: {id: object.id}}">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link">Open in moderation interface</translate>
+                  </router-link>
+                  <a
+                    v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="basic item"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/artist/${object.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <router-view
+        :tracks="tracks"
+        :next-tracks-url="nextTracksUrl"
+        :next-albums-url="nextAlbumsUrl"
+        :albums="albums"
+        :is-loading-albums="isLoadingAlbums"
+        @libraries-loaded="libraries = $event"
+        :object="object" object-type="artist"
+        :key="$route.fullPath"></router-view>
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+import backend from "@/audio/backend"
+import PlayButton from "@/components/audio/PlayButton"
+import EmbedWizard from "@/components/audio/EmbedWizard"
+import Modal from '@/components/semantic/Modal'
+import RadioButton from "@/components/radios/Button"
+
+const FETCH_URL = "albums/"
+
+
+export default {
+  props: ["id"],
+  components: {
+    PlayButton,
+    EmbedWizard,
+    Modal,
+    RadioButton
+  },
+  data() {
+    return {
+      isLoading: true,
+      isLoadingAlbums: true,
+      object: null,
+      albums: null,
+      libraries: [],
+      showEmbedModal: false,
+      tracks: [],
+      nextAlbumsUrl: null,
+      nextTracksUrl: null,
+      totalAlbums: null,
+      totalTracks: null,
+    }
+  },
+  async created() {
+    await this.fetchData()
+  },
+  methods: {
+    async fetchData() {
+      var self = this
+      this.isLoading = true
+      logger.default.debug('Fetching artist "' + this.id + '"')
+      let trackPromise = axios.get("tracks/", { params: { artist: this.id, hidden: '' } }).then(response => {
+        self.tracks = response.data.results
+        self.nextTracksUrl = response.data.next
+        self.totalTracks = response.data.count
+      })
+      let albumPromise = axios.get("albums/", {
+        params: { artist: self.id, ordering: "-release_date", hidden: '' }
+      }).then(response => {
+        self.nextAlbumsUrl = response.data.next
+        self.totalAlbums = response.data.count
+        let parsed = JSON.parse(JSON.stringify(response.data.results))
+        self.albums = parsed.map(album => {
+          return backend.Album.clean(album)
+        })
+
+      })
+
+      let artistPromise = axios.get("artists/" + this.id + "/").then(response => {
+        self.object = response.data
+      })
+      await trackPromise
+      await albumPromise
+      await artistPromise
+      self.isLoadingAlbums = false
+      self.isLoading = false
+    }
+  },
+  computed: {
+    isPlayable() {
+      return (
+        this.object.albums.filter(a => {
+          return a.is_playable
+        }).length > 0
+      )
+    },
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Album')
+      }
+    },
+    wikipediaUrl() {
+      return (
+        "https://en.wikipedia.org/w/index.php?search=" +
+        encodeURI(this.object.name)
+      )
+    },
+    musicbrainzUrl() {
+      if (this.object.mbid) {
+        return "https://musicbrainz.org/artist/" + this.object.mbid
+      }
+    },
+    cover() {
+      return this.object.albums
+        .filter(album => {
+          return album.cover
+        })
+        .map(album => {
+          return album.cover
+        })[0]
+    },
+
+    publicLibraries () {
+      return this.libraries.filter(l => {
+        return l.privacy_level === 'everyone'
+      })
+    },
+    headerStyle() {
+      if (!this.cover || !this.cover.original) {
+        return ""
+      }
+      return (
+        "background-image: url(" +
+        this.$store.getters["instance/absoluteUrl"](this.cover.original) +
+        ")"
+      )
+    },
+    contentFilter () {
+      let self = this
+      return this.$store.getters['moderation/artistFilters']().filter((e) => {
+        return e.target.id === this.object.id
+      })[0]
+    }
+  },
+  watch: {
+    id() {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/ArtistDetail.vue b/front/src/components/library/ArtistDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1dfbdd0d244720ec21fe731ae01e9629c30f6ffb
--- /dev/null
+++ b/front/src/components/library/ArtistDetail.vue
@@ -0,0 +1,102 @@
+<template>
+  <div v-if="object">
+    <div class="ui small text container" v-if="contentFilter">
+      <div class="ui hidden divider"></div>
+      <div class="ui message">
+        <p>
+          <translate translate-context="Content/Artist/Paragraph">You are currently hiding content related to this artist.</translate>
+        </p>
+        <router-link class="right floated" :to="{name: 'settings'}">
+          <translate translate-context="Content/Moderation/Link">Review my filters</translate>
+        </router-link>
+        <button @click="$store.dispatch('moderation/deleteContentFilter', contentFilter.uuid)" class="ui basic tiny button">
+          <translate translate-context="Content/Moderation/Button.Label">Remove filter</translate>
+        </button>
+      </div>
+    </div>
+    <section v-if="isLoadingAlbums" class="ui vertical stripe segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </section>
+    <section v-else-if="albums && albums.length > 0" class="ui vertical stripe segment">
+      <h2>
+        <translate translate-context="Content/Artist/Title">Albums by this artist</translate>
+      </h2>
+      <div class="ui cards">
+        <album-card :mode="'rich'" :album="album" :key="album.id" v-for="album in allAlbums"></album-card>
+      </div>
+      <div class="ui hidden divider"></div>
+      <button :class="['ui', {loading: isLoadingMoreAlbums}, 'button']" v-if="nextAlbumsUrl && loadMoreAlbumsUrl" @click="loadMoreAlbums(loadMoreAlbumsUrl)">
+        <translate translate-context="Content/*/Button.Label">Load more…</translate>
+      </button>
+    </section>
+    <section v-if="tracks.length > 0" class="ui vertical stripe segment">
+      <h2>
+        <translate translate-context="Content/Artist/Title">Tracks by this artist</translate>
+      </h2>
+      <track-table :display-position="true" :tracks="tracks" :next-url="nextTracksUrl"></track-table>
+    </section>
+    <section class="ui vertical stripe segment">
+      <h2>
+        <translate translate-context="Content/*/Title/Noun">User libraries</translate>
+      </h2>
+      <library-widget @loaded="$emit('libraries-loaded', $event)" :url="'artists/' + object.id + '/libraries/'">
+        <translate translate-context="Content/Artist/Paragraph" slot="subtitle">This artist is present in the following libraries:</translate>
+      </library-widget>
+    </section>
+  </div>
+</template>
+
+<script>
+import _ from "@/lodash"
+import axios from "axios"
+import logger from "@/logging"
+import backend from "@/audio/backend"
+import AlbumCard from "@/components/audio/album/Card"
+import TrackTable from "@/components/audio/track/Table"
+import LibraryWidget from "@/components/federation/LibraryWidget"
+
+export default {
+  props: ["object", "tracks", "albums", "isLoadingAlbums", "nextTracksUrl", "nextAlbumsUrl"],
+  components: {
+    AlbumCard,
+    TrackTable,
+    LibraryWidget,
+  },
+  data () {
+    return {
+      loadMoreAlbumsUrl: this.nextAlbumsUrl,
+      additionalAlbums: [],
+      isLoadingMoreAlbums: false
+    }
+  },
+  computed: {
+    contentFilter () {
+      let self = this
+      return this.$store.getters['moderation/artistFilters']().filter((e) => {
+        return e.target.id === this.object.id
+      })[0]
+    },
+     allAlbums () {
+      return this.albums.concat(this.additionalAlbums)
+    }
+  },
+  methods: {
+    loadMoreAlbums (url) {
+      let self = this
+      self.isLoadingMoreAlbums = true
+      axios.get(url).then((response) => {
+        self.additionalAlbums = self.additionalAlbums.concat(response.data.results)
+        self.loadMoreAlbumsUrl = response.data.next
+        self.isLoadingMoreAlbums = false
+      }, (error) => {
+        self.isLoadingMoreAlbums = false
+
+      })
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/front/src/components/library/ArtistEdit.vue b/front/src/components/library/ArtistEdit.vue
new file mode 100644
index 0000000000000000000000000000000000000000..80a9ae0c3ce130720f62b389b6dac3a2c3c1baf9
--- /dev/null
+++ b/front/src/components/library/ArtistEdit.vue
@@ -0,0 +1,41 @@
+<template>
+
+  <section class="ui vertical stripe segment">
+    <div class="ui text container">
+      <h2>
+        <translate v-if="canEdit" key="1" translate-context="Content/*/Title">Edit this artist</translate>
+        <translate v-else key="2" translate-context="Content/*/Title">Suggest an edit on this artist</translate>
+      </h2>
+      <div class="ui message" v-if="!object.is_local">
+        <translate translate-context="Content/*/Message">This object is managed by another server, you cannot edit it.</translate>
+      </div>
+      <edit-form
+        v-else
+        :object-type="objectType"
+        :object="object"
+        :can-edit="canEdit"></edit-form>
+    </div>
+  </section>
+</template>
+
+<script>
+import axios from "axios"
+
+import EditForm from '@/components/library/EditForm'
+export default {
+  props: ["objectType", "object", "libraries"],
+  data() {
+    return {
+      id: this.object.id,
+    }
+  },
+  components: {
+    EditForm
+  },
+  computed: {
+    canEdit () {
+      return true
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/Artists.vue b/front/src/components/library/Artists.vue
index 41b3b2c6fbe080e23e7ffc661b4c5d8b28f6e4bb..5f4102ab1c269cc6610bf8cec3fa95b33b9d5b83 100644
--- a/front/src/components/library/Artists.vue
+++ b/front/src/components/library/Artists.vue
@@ -2,18 +2,18 @@
   <main v-title="labels.title">
     <section class="ui vertical stripe segment">
       <h2 class="ui header">
-        <translate>Browsing artists</translate>
+        <translate translate-context="Content/Artist/Title">Browsing artists</translate>
       </h2>
       <div :class="['ui', {'loading': isLoading}, 'form']">
         <div class="fields">
           <div class="field">
             <label>
-              <translate>Search</translate>
+              <translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
             </label>
             <input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
           </div>
           <div class="field">
-            <label><translate>Ordering</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
             <select class="ui dropdown" v-model="ordering">
               <option v-for="option in orderingOptions" :value="option[0]">
                 {{ sharedLabels.filters[option[1]] }}
@@ -21,14 +21,14 @@
             </select>
           </div>
           <div class="field">
-            <label><translate>Ordering direction</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
             <select class="ui dropdown" v-model="orderingDirection">
-              <option value="+"><translate>Ascending</translate></option>
-              <option value="-"><translate>Descending</translate></option>
+              <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+              <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
             </select>
           </div>
           <div class="field">
-            <label><translate>Results per page</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Results per page</translate></label>
             <select class="ui dropdown" v-model="paginateBy">
               <option :value="parseInt(12)">12</option>
               <option :value="parseInt(25)">25</option>
@@ -113,8 +113,8 @@ export default {
   },
   computed: {
     labels() {
-      let searchPlaceholder = this.$gettext("Enter artist name…")
-      let title = this.$gettext("Artists")
+      let searchPlaceholder = this.$pgettext('Content/Search/Input.Placeholder', "Enter artist name…")
+      let title = this.$pgettext('*/*/*/Noun', "Artists")
       return {
         searchPlaceholder,
         title
@@ -173,6 +173,9 @@ export default {
     query() {
       this.updateQueryString()
       this.fetchData()
+    },
+    "$store.state.moderation.lastUpdate": function () {
+      this.fetchData()
     }
   }
 }
diff --git a/front/src/components/library/EditCard.vue b/front/src/components/library/EditCard.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e72823aa74d7aa406e14bb7e87eea1d7ff3c0179
--- /dev/null
+++ b/front/src/components/library/EditCard.vue
@@ -0,0 +1,209 @@
+<template>
+  <div class="ui fluid card">
+    <div class="content">
+      <div class="header">
+        <router-link :to="detailUrl">
+          <translate translate-context="Content/Library/Card/Short" :translate-params="{id: obj.uuid.substring(0, 8)}">Modification %{ id }</translate>
+        </router-link>
+      </div>
+      <div class="meta">
+        <router-link
+          v-if="obj.target && obj.target.type === 'track'"
+          :to="{name: 'library.tracks.detail', params: {id: obj.target.id }}">
+          <i class="music icon"></i>
+          <translate translate-context="Content/Library/Card/Short" :translate-params="{id: obj.target.id, name: obj.target.repr}">Track #%{ id } - %{ name }</translate>
+        </router-link>
+        <br>
+        <human-date :date="obj.creation_date" :icon="true"></human-date>
+
+        <span class="right floated">
+          <span v-if="obj.is_approved && obj.is_applied">
+            <i class="green check icon"></i>
+            <translate translate-context="Content/Library/Card/Short">Approved and applied</translate>
+          </span>
+          <span v-else-if="obj.is_approved">
+            <i class="green check icon"></i>
+            <translate translate-context="Content/*/*/Short">Approved</translate>
+          </span>
+          <span v-else-if="obj.is_approved === null">
+            <i class="yellow hourglass icon"></i>
+            <translate translate-context="Content/Admin/*/Noun">Pending review</translate>
+          </span>
+          <span v-else-if="obj.is_approved === false">
+            <i class="red x icon"></i>
+            <translate translate-context="Content/Library/*/Short">Rejected</translate>
+          </span>
+        </span>
+      </div>
+    </div>
+    <div v-if="obj.summary" class="content">
+      {{ obj.summary }}
+    </div>
+    <div class="content">
+      <table v-if="obj.type === 'update'" class="ui celled very basic fixed stacking table">
+        <thead>
+          <tr>
+            <th><translate translate-context="Content/Library/Card.Table.Header/Short">Field</translate></th>
+            <th><translate translate-context="Content/Library/Card.Table.Header/Short">Old value</translate></th>
+            <th><translate translate-context="Content/Library/Card.Table.Header/Short">New value</translate></th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr v-for="field in getUpdatedFields(obj.payload, previousState)" :key="field.id">
+            <td>{{ field.id }}</td>
+
+            <td v-if="field.diff">
+              <span v-if="!part.added" v-for="part in field.diff" :class="['diff', {removed: part.removed}]">
+                {{ part.value }}
+              </span>
+            </td>
+            <td v-else>
+              <translate translate-context="*/*/*">N/A</translate>
+            </td>
+
+            <td v-if="field.diff">
+              <span v-if="!part.removed" v-for="part in field.diff" :class="['diff', {added: part.added}]">
+                {{ part.value }}
+              </span>
+            </td>
+            <td v-else>{{ field.new }}</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+    <div v-if="obj.created_by" class="extra content">
+      <actor-link :actor="obj.created_by" />
+    </div>
+    <div v-if="canDelete || canApprove" class="ui bottom attached buttons">
+      <button
+        v-if="canApprove && obj.is_approved !== true"
+        @click="approve(true)"
+        :class="['ui', {loading: isLoading}, 'green', 'basic', 'button']">
+        <translate translate-context="Content/*/Button.Label/Verb">Approve</translate>
+      </button>
+      <button
+        v-if="canApprove && obj.is_approved === null"
+        @click="approve(false)"
+        :class="['ui', {loading: isLoading}, 'yellow', 'basic', 'button']">
+        <translate translate-context="Content/Library/Button.Label">Reject</translate>
+      </button>
+      <dangerous-button
+        v-if="canDelete"
+        :class="['ui', {loading: isLoading}, 'basic button']"
+        :action="remove">
+        <translate translate-context="*/*/*/Verb">Delete</translate>
+        <p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this suggestion?</translate></p>
+        <div slot="modal-content">
+          <p><translate translate-context="Popup/Library/Paragraph">The suggestion will be completely removed, this action is irreversible.</translate></p>
+        </div>
+        <p slot="modal-confirm"><translate translate-context="*/*/*/Verb">Delete</translate></p>
+      </dangerous-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import { diffWordsWithSpace } from 'diff'
+
+import edits from '@/edits'
+
+function castValue (value) {
+  if (value === null || value === undefined) {
+    return ''
+  }
+  return String(value)
+}
+
+export default {
+  props: {
+    obj: {required: true},
+    currentState: {required: false}
+  },
+  data () {
+    return {
+      isLoading: false
+    }
+  },
+  computed: {
+    canApprove: edits.getCanApprove,
+    canDelete: edits.getCanDelete,
+    previousState () {
+      if (this.obj.is_applied) {
+        // mutation was applied, we use the previous state that is stored
+        // on the mutation itself
+        return this.obj.previous_state
+      }
+      // mutation is not applied yet, so we use the current state that was
+      // passed to the component, if any
+      return this.currentState
+    },
+    detailUrl () {
+      if (!this.obj.target) {
+        return ''
+      }
+      let namespace
+      let id = this.obj.target.id
+      if (this.obj.target.type === 'track') {
+        namespace = 'library.tracks.edit.detail'
+      }
+      if (this.obj.target.type === 'album') {
+        namespace = 'library.albums.edit.detail'
+      }
+      if (this.obj.target.type === 'artist') {
+        namespace = 'library.artists.edit.detail'
+      }
+      return this.$router.resolve({name: namespace, params: {id, editId: this.obj.uuid}}).href
+    }
+  },
+  methods: {
+    remove () {
+      let self = this
+      this.isLoading = true
+      axios.delete(`mutations/${this.obj.uuid}/`).then((response) => {
+        self.$emit('deleted')
+        self.isLoading = false
+      }, error => {
+        self.isLoading = false
+      })
+    },
+    approve (approved) {
+      let url
+      if (approved) {
+        url = `mutations/${this.obj.uuid}/approve/`
+      } else {
+        url = `mutations/${this.obj.uuid}/reject/`
+      }
+      let self = this
+      this.isLoading = true
+      axios.post(url).then((response) => {
+        self.$emit('approved', approved)
+        self.isLoading = false
+        self.$store.commit('ui/incrementNotifications', {count: -1, type: 'pendingReviewEdits'})
+      }, error => {
+        self.isLoading = false
+      })
+    },
+    getUpdatedFields (payload, previousState) {
+      let fields = Object.keys(payload)
+      return fields.map((f) => {
+        let d = {
+          id: f,
+        }
+        if (previousState && previousState[f]) {
+          d.old = previousState[f]
+        }
+        d.new = payload[f]
+        if (d.old) {
+          // we compute the diffs between the old and new values
+
+          let oldValue = castValue(d.old.value)
+          let newValue = castValue(d.new)
+          d.diff = diffWordsWithSpace(oldValue, newValue)
+        }
+        return d
+      })
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/EditDetail.vue b/front/src/components/library/EditDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..4a0c89434de8797d37022d0d9916df1fd719647a
--- /dev/null
+++ b/front/src/components/library/EditDetail.vue
@@ -0,0 +1,52 @@
+<template>
+
+  <section :class="['ui', 'vertical', 'stripe', {loading: isLoading}, 'segment']">
+    <div class="ui text container">
+      <edit-card v-if="obj" :obj="obj" :current-state="currentState" />
+    </div>
+  </section>
+</template>
+
+<script>
+import axios from "axios"
+import edits from '@/edits'
+import EditCard from '@/components/library/EditCard'
+export default {
+  props: ["object", "objectType", "editId"],
+  components: {
+    EditCard
+  },
+  data () {
+    return {
+      isLoading: true,
+      obj: null,
+    }
+  },
+  created () {
+    this.fetchData()
+  },
+  computed: {
+    configs: edits.getConfigs,
+    config: edits.getConfig,
+    currentState: edits.getCurrentState,
+    currentState () {
+      let self = this
+      let s = {}
+      this.config.fields.forEach(f => {
+        s[f.id] = {value: f.getValue(self.object)}
+      })
+      return s
+    }
+  },
+  methods: {
+    fetchData () {
+      var self = this
+      this.isLoading = true
+      axios.get(`mutations/${this.editId}/`).then(response => {
+        self.obj = response.data
+        self.isLoading = false
+      })
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/EditForm.vue b/front/src/components/library/EditForm.vue
new file mode 100644
index 0000000000000000000000000000000000000000..617917c6812f03924934c48ec0e7d92079f95a72
--- /dev/null
+++ b/front/src/components/library/EditForm.vue
@@ -0,0 +1,229 @@
+<template>
+  <div v-if="submittedMutation">
+    <div class="ui positive message">
+      <div class="header"><translate translate-context="Content/Library/Paragraph">Your edit was successfully submitted.</translate></div>
+    </div>
+    <edit-card :obj="submittedMutation" :current-state="currentState" />
+    <button class="ui button" @click.prevent="submittedMutation = null">
+      <translate translate-context="Content/Library/Button.Label">
+        Submit another edit
+      </translate>
+    </button>
+  </div>
+  <div v-else>
+
+    <edit-list :filters="editListFilters" :url="mutationsUrl" :obj="object" :currentState="currentState">
+      <div slot="title">
+        <template v-if="showPendingReview">
+          <translate translate-context="Content/Library/Paragraph">
+            Recent edits awaiting review
+          </translate>
+          <button class="ui tiny basic right floated button" @click.prevent="showPendingReview = false">
+            <translate translate-context="Content/Library/Button.Label">
+              Show all edits
+            </translate>
+          </button>
+        </template>
+        <template v-else>
+          <translate translate-context="Content/Library/Paragraph">
+            Recent edits
+          </translate>
+          <button class="ui tiny basic right floated button" @click.prevent="showPendingReview = true">
+            <translate translate-context="Content/Library/Button.Label">
+              Retrict to unreviewed edits
+            </translate>
+          </button>
+        </template>
+      </div>
+      <empty-state slot="empty-state">
+        <translate translate-context="Content/Library/Paragraph">
+          Suggest a change using the form below.
+        </translate>
+      </empty-state>
+    </edit-list>
+    <form class="ui form" @submit.prevent="submit()">
+      <div class="ui hidden divider"></div>
+      <div v-if="errors.length > 0" class="ui negative message">
+        <div class="header"><translate translate-context="Content/Library/Error message.Title">Error while submitting edit</translate></div>
+        <ul class="list">
+          <li v-for="error in errors">{{ error }}</li>
+        </ul>
+      </div>
+      <div v-if="!canEdit" class="ui message">
+        <translate translate-context="Content/Library/Paragraph">
+          You don't have the permission to edit this object, but you can suggest changes. Once submitted, suggestions will be reviewed before approval.
+        </translate>
+      </div>
+      <div v-if="values" v-for="fieldConfig in config.fields" :key="fieldConfig.id" class="ui field">
+        <template v-if="fieldConfig.type === 'text'">
+          <label :for="fieldConfig.id">{{ fieldConfig.label }}</label>
+          <input :type="fieldConfig.inputType || 'text'" v-model="values[fieldConfig.id]" :required="fieldConfig.required" :name="fieldConfig.id" :id="fieldConfig.id">
+        </template>
+        <template v-else-if="fieldConfig.type === 'license'">
+          <label :for="fieldConfig.id">{{ fieldConfig.label }}</label>
+
+          <select
+            ref="license"
+            v-model="values[fieldConfig.id]"
+            :required="fieldConfig.required"
+            :id="fieldConfig.id"
+            class="ui fluid search dropdown">
+              <option :value="null"><translate translate-context="*/*/*">N/A</translate></option>
+              <option v-for="license in licenses" :key="license.code" :value="license.code">{{ license.name}}</option>
+          </select>
+          <button class="ui tiny basic left floated button" form="noop" @click.prevent="values[fieldConfig.id] = null">
+            <i class="x icon"></i>
+            <translate translate-context="Content/Library/Button.Label">Clear</translate>
+          </button>
+
+        </template>
+        <div v-if="values[fieldConfig.id] != initialValues[fieldConfig.id]">
+          <button class="ui tiny basic right floated reset button" form="noop" @click.prevent="values[fieldConfig.id] = initialValues[fieldConfig.id]">
+            <i class="undo icon"></i>
+            <translate translate-context="Content/Library/Button.Label" :translate-params="{value: initialValues[fieldConfig.id] || ''}">Reset to initial value: %{ value }</translate>
+          </button>
+        </div>
+      </div>
+      <div class="field">
+        <label for="summary"><translate translate-context="*/*/*">Summary (optional)</translate></label>
+        <textarea name="change-summary" v-model="summary" id="change-summary" rows="3" :placeholder="labels.summaryPlaceholder"></textarea>
+      </div>
+      <router-link
+        class="ui left floated button"
+        v-if="objectType === 'track'"
+        :to="{name: 'library.tracks.detail', params: {id: object.id }}"
+      >
+        <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
+      </router-link>
+      <button :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']" type="submit" :disabled="isLoading || !mutationPayload">
+        <translate v-if="canEdit" key="1" translate-context="Content/Library/Button.Label/Verb">Submit and apply edit</translate>
+        <translate v-else key="2" translate-context="Content/Library/Button.Label/Verb">Submit suggestion</translate>
+      </button>
+      </form>
+    </div>
+  </div>
+</template>
+
+<script>
+import $ from 'jquery'
+import _ from '@/lodash'
+import axios from "axios"
+import EditList from '@/components/library/EditList'
+import EditCard from '@/components/library/EditCard'
+import edits from '@/edits'
+
+export default {
+  props: ["objectType", "object", "licenses"],
+  components: {
+    EditList,
+    EditCard
+  },
+  data() {
+    return {
+      isLoading: false,
+      errors: [],
+      values: {},
+      initialValues: {},
+      summary: '',
+      submittedMutation: null,
+      showPendingReview: true,
+    }
+  },
+  created () {
+    this.setValues()
+  },
+  mounted() {
+    $(".ui.dropdown").dropdown({fullTextSearch: true})
+  },
+  computed: {
+    configs: edits.getConfigs,
+    config: edits.getConfig,
+    currentState: edits.getCurrentState,
+    canEdit: edits.getCanEdit,
+    labels () {
+      return {
+        summaryPlaceholder: this.$pgettext('*/*/Placeholder', 'A short summary describing your changes.'),
+      }
+    },
+    mutationsUrl () {
+      if (this.objectType === 'track') {
+        return `tracks/${this.object.id}/mutations/`
+      }
+      if (this.objectType === 'album') {
+        return `albums/${this.object.id}/mutations/`
+      }
+      if (this.objectType === 'artist') {
+        return `artists/${this.object.id}/mutations/`
+      }
+    },
+    mutationPayload () {
+      let self = this
+      let changedFields = this.config.fields.filter(f => {
+        return self.values[f.id] != self.initialValues[f.id]
+      })
+      if (changedFields.length === 0) {
+        return null
+      }
+      let payload = {
+        type: 'update',
+        payload: {},
+        summary: this.summary,
+      }
+      changedFields.forEach((f) => {
+        payload.payload[f.id] = self.values[f.id]
+      })
+      return payload
+    },
+    editListFilters () {
+      if (this.showPendingReview) {
+        return {is_approved: 'null'}
+      } else {
+        return {}
+      }
+    },
+  },
+
+  methods: {
+    setValues () {
+      let self = this
+      this.config.fields.forEach(f => {
+        self.$set(self.values, f.id, f.getValue(self.object))
+        self.$set(self.initialValues, f.id, self.values[f.id])
+      })
+    },
+    submit() {
+      let self = this
+      self.isLoading = true
+      self.errors = []
+      let payload = _.clone(this.mutationPayload || {})
+      if (this.canEdit) {
+        payload.is_approved = true
+      }
+      return axios.post(this.mutationsUrl, payload).then(
+        response => {
+          self.isLoading = false
+          self.submittedMutation = response.data
+        },
+        error => {
+          self.errors = error.backendErrors
+          self.isLoading = false
+        }
+      )
+    }
+  },
+  watch: {
+    'values.license' (newValue) {
+      if (newValue === null) {
+        $(this.$refs.license).dropdown('clear')
+      } else {
+        $(this.$refs.license).dropdown('set selected', newValue)
+      }
+    }
+  }
+}
+</script>
+<style>
+.reset.button {
+  margin-top: 0.5em;
+}
+</style>
diff --git a/front/src/components/library/EditList.vue b/front/src/components/library/EditList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2ff1fc72a0661e0e9a21c3e97e17fe73aabd1b39
--- /dev/null
+++ b/front/src/components/library/EditList.vue
@@ -0,0 +1,74 @@
+<template>
+  <div class="wrapper">
+    <h3 class="ui header">
+      <slot name="title"></slot>
+    </h3>
+    <slot v-if="!isLoading && objects.length === 0" name="empty-state"></slot>
+    <button v-if="nextPage || previousPage" :disabled="!previousPage" @click="fetchData(previousPage)" :class="['ui', {disabled: !previousPage}, 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'angle left', 'icon']"></i></button>
+    <button v-if="nextPage || previousPage" :disabled="!nextPage" @click="fetchData(nextPage)" :class="['ui', {disabled: !nextPage}, 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'angle right', 'icon']"></i></button>
+    <div class="ui hidden divider"></div>
+    <div v-if="isLoading" class="ui inverted active dimmer">
+      <div class="ui loader"></div>
+    </div>
+    <edit-card @updated="fetchData(url)" @deleted="fetchData(url)" v-for="obj in objects" :key="obj.uuid" :obj="obj" :current-state="currentState" />
+  </div>
+</template>
+
+<script>
+import _ from '@/lodash'
+import axios from 'axios'
+
+import EditCard from '@/components/library/EditCard'
+
+export default {
+  props: {
+    url: {type: String, required: true},
+    filters: {type: Object, required: false, default: () => {return {}}},
+    currentState: {required: false},
+  },
+  components: {
+    EditCard
+  },
+  data () {
+    return {
+      objects: [],
+      limit: 5,
+      isLoading: false,
+      errors: null,
+      previousPage: null,
+      nextPage: null
+    }
+  },
+  created () {
+    this.fetchData(this.url)
+  },
+  methods: {
+    fetchData (url) {
+      if (!url) {
+        return
+      }
+      this.isLoading = true
+      let self = this
+      let params = _.clone(this.filters)
+      params.page_size = this.limit
+      axios.get(url, {params: params}).then((response) => {
+        self.previousPage = response.data.previous
+        self.nextPage = response.data.next
+        self.isLoading = false
+        self.objects = response.data.results
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+  },
+  watch: {
+    filters: {
+      handler () {
+        this.fetchData(this.url)
+      },
+      deep: true
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/FileUpload.vue b/front/src/components/library/FileUpload.vue
index 7b7673b5abb5c6b7d429cdca5ed5edb92172dfdc..a8a5d2f374e0eb4ce0c51f4c134fac28ed78c0b2 100644
--- a/front/src/components/library/FileUpload.vue
+++ b/front/src/components/library/FileUpload.vue
@@ -1,9 +1,9 @@
   <template>
   <div>
     <div class="ui top attached tabular menu">
-      <a :class="['item', {active: currentTab === 'summary'}]" @click="currentTab = 'summary'"><translate>Summary</translate></a>
+      <a :class="['item', {active: currentTab === 'summary'}]" @click="currentTab = 'summary'"><translate translate-context="Content/Library/Tab.Title/Short">Summary</translate></a>
       <a :class="['item', {active: currentTab === 'uploads'}]" @click="currentTab = 'uploads'">
-        <translate>Uploading</translate>
+        <translate translate-context="Content/Library/Tab.Title/Short">Uploading</translate>
         <div v-if="files.length === 0" class="ui label">
           0
         </div>
@@ -15,7 +15,7 @@
         </div>
       </a>
       <a :class="['item', {active: currentTab === 'processing'}]" @click="currentTab = 'processing'">
-        <translate>Processing</translate>
+        <translate translate-context="Content/Library/Tab.Title/Short">Processing</translate>
         <div v-if="processableFiles === 0" class="ui label">
           0
         </div>
@@ -27,21 +27,20 @@
         </div>
       </a>
     </div>
-
     <div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'summary'}]">
-      <h2 class="ui header"><translate>Upload new tracks</translate></h2>
+      <h2 class="ui header"><translate translate-context="Content/Library/Title/Verb">Upload new tracks</translate></h2>
       <div class="ui message">
-        <p><translate>You are about to upload music to your library. Before proceeding, please ensure that:</translate></p>
+        <p><translate translate-context="Content/Library/Paragraph">You are about to upload music to your library. Before proceeding, please ensure that:</translate></p>
         <ul>
           <li v-if="library.privacy_level != 'me'">
-            You are not uploading copyrighted content in a public library, otherwise you may be infringing the law
+            <translate translate-context="Content/Library/List item">You are not uploading copyrighted content in a public library, otherwise you may be infringing the law</translate>
           </li>
           <li>
-            <translate>The music files you are uploading are tagged properly:</translate>
-            <a href="http://picard.musicbrainz.org/" target='_blank'><translate>We recommend using Picard for that purpose.</translate></a>
+            <translate translate-context="Content/Library/List item">The music files you are uploading are tagged properly.</translate>&nbsp;
+            <a href="http://picard.musicbrainz.org/" target='_blank'><translate translate-context="Content/Library/Link">We recommend using Picard for that purpose.</translate></a>
           </li>
           <li>
-            <translate>The uploaded music files are in OGG, Flac or MP3 format</translate>
+            <translate translate-context="Content/Library/List item">The uploaded music files are in OGG, Flac or MP3 format</translate>
           </li>
         </ul>
       </div>
@@ -49,17 +48,25 @@
       <div class="ui form">
         <div class="fields">
           <div class="ui four wide field">
-            <label><translate>Import reference</translate></label>
-            <p><translate>This reference will be used to group imported files together.</translate></p>
+            <label><translate translate-context="Content/Library/Input.Label/Noun">Import reference</translate></label>
+            <p><translate translate-context="Content/Library/Paragraph">This reference will be used to group imported files together.</translate></p>
             <input name="import-ref" type="text" v-model="importReference" />
           </div>
         </div>
 
       </div>
-      <div class="ui green button" @click="currentTab = 'uploads'"><translate>Proceed</translate></div>
+      <div class="ui green button" @click="currentTab = 'uploads'"><translate translate-context="Content/Library/Button.Label">Proceed</translate></div>
     </div>
     <div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'uploads'}]">
-      <div class="ui container">
+      <div :class="['ui', {loading: isLoadingQuota}, 'container']">
+        <div :class="['ui', {red: remainingSpace === 0}, {yellow: remainingSpace > 0 && remainingSpace <= 50}, 'small', 'statistic']">
+          <div class="label">
+            <translate translate-context="Content/Library/Paragraph">Remaining storage space</translate>
+          </div>
+          <div class="value">
+            {{ remainingSpace * 1000 * 1000 | humanSize}}
+          </div>
+        </div>
         <file-upload-widget
           :class="['ui', 'icon', 'basic', 'button']"
           :post-action="uploadUrl"
@@ -73,45 +80,48 @@
           @input-file="inputFile"
           ref="upload">
           <i class="upload icon"></i>&nbsp;
-          <translate>Click to select files to upload or drag and drop files or directories</translate>
+          <translate translate-context="Content/Library/Paragraph/Call to action">Click to select files to upload or drag and drop files or directories</translate>
           <br />
           <br />
-          <i><translate :translate-params="{extensions: supportedExtensions.join(', ')}">  Supported extensions: %{ extensions }</translate></i>
+          <i><translate translate-context="Content/Library/Paragraph" :translate-params="{extensions: supportedExtensions.join(', ')}">Supported extensions: %{ extensions }</translate></i>
         </file-upload-widget>
       </div>
-      <table v-if="files.length > 0" class="ui single line table">
-        <thead>
-          <tr>
-            <th><translate>Filename</translate></th>
-            <th><translate>Size</translate></th>
-            <th><translate>Status</translate></th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr v-for="(file, index) in sortedFiles" :key="file.id">
-            <td :title="file.name">{{ file.name | truncate(60) }}</td>
-            <td>{{ file.size | humanSize }}</td>
-            <td>
-              <span v-if="file.error" class="ui tooltip" :data-tooltip="labels.tooltips[file.error]">
-                <span class="ui red icon label">
-                  <i class="question circle outline icon" /> {{ file.error }}
+      <div v-if="files.length > 0" class="table-wrapper">
+        <div class="ui hidden divider"></div>
+        <table class="ui unstackable table">
+          <thead>
+            <tr>
+              <th><translate translate-context="Content/Library/Table.Label">Filename</translate></th>
+              <th><translate translate-context="Content/Library/*/in MB">Size</translate></th>
+              <th><translate translate-context="Content/Library/Table.Label (Value is Uploading/Uploaded/Error)">Status</translate></th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="(file, index) in sortedFiles" :key="file.id">
+              <td :title="file.name">{{ file.name | truncate(60) }}</td>
+              <td>{{ file.size | humanSize }}</td>
+              <td>
+                <span v-if="file.error" class="ui tooltip" :data-tooltip="labels.tooltips[file.error]">
+                  <span class="ui red icon label">
+                    <i class="question circle outline icon" /> {{ file.error }}
+                  </span>
                 </span>
-              </span>
-              <span v-else-if="file.success" class="ui green label">
-                <translate key="1">Uploaded</translate>
-              </span>
-              <span v-else-if="file.active" class="ui yellow label">
-                <translate key="2">Uploading…</translate>
-                ({{ parseInt(file.progress) }}%)
-              </span>
-              <template v-else>
-                <span class="ui label"><translate key="3">Pending</translate></span>
-                <button class="ui tiny basic red icon button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
-              </template>
-            </td>
-          </tr>
-        </tbody>
-      </table>
+                <span v-else-if="file.success" class="ui green label">
+                  <translate translate-context="Content/Library/Table" key="1">Uploaded</translate>
+                </span>
+                <span v-else-if="file.active" class="ui yellow label">
+                  <translate translate-context="Content/Library/Table" key="2">Uploading…</translate>
+                  ({{ parseInt(file.progress) }}%)
+                </span>
+                <template v-else>
+                  <span class="ui label"><translate translate-context="Content/Library/*/Short" key="3">Pending</translate></span>
+                  <button class="ui tiny basic red icon button" @click.prevent="$refs.upload.remove(file)"><i class="delete icon"></i></button>
+                </template>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
 
     </div>
     <div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'processing'}]">
@@ -149,6 +159,8 @@ export default {
       uploadUrl: this.$store.getters['instance/absoluteUrl']("/api/v1/uploads/"),
       importReference,
       supportedExtensions: ["flac", "ogg", "mp3", "opus"],
+      isLoadingQuota: false,
+      quotaStatus: null,
       uploads: {
         pending: 0,
         finished: 0,
@@ -161,6 +173,7 @@ export default {
   },
   created() {
     this.fetchStatus();
+    this.fetchQuota();
     this.$store.commit("ui/addWebsocketEventHandler", {
       eventName: "import.status_updated",
       id: "fileUpload",
@@ -184,8 +197,23 @@ export default {
       });
       return returnValue;
     },
+    fetchQuota () {
+      let self = this
+      self.isLoadingQuota = true
+      axios.get('users/users/me/').then((response) => {
+        self.quotaStatus = response.data.quota_status
+        self.isLoadingQuota = false
+      })
+    },
     inputFile(newFile, oldFile) {
-      this.$refs.upload.active = true;
+      if (!newFile) {
+        return
+      }
+      if (this.remainingSpace < newFile.size / (1000 * 1000)) {
+        newFile.error = 'denied'
+      } else {
+        this.$refs.upload.active = true;
+      }
     },
     fetchStatus() {
       let self = this;
@@ -227,17 +255,17 @@ export default {
   },
   computed: {
     labels() {
-      let denied = this.$gettext(
+      let denied = this.$pgettext('Content/Library/Help text',
         "Upload denied, ensure the file is not too big and that you have not reached your quota"
       );
-      let server = this.$gettext(
+      let server = this.$pgettext('Content/Library/Help text',
         "Cannot upload this file, ensure it is not too big"
       );
-      let network = this.$gettext(
+      let network = this.$pgettext('Content/Library/Help text',
         "A network error occured while uploading this file"
       );
-      let timeout = this.$gettext("Upload timeout, please try again");
-      let extension = this.$gettext(
+      let timeout = this.$pgettext('Content/Library/Help text', "Upload timeout, please try again");
+      let extension = this.$pgettext('Content/Library/Help text',
         "Invalid file type, ensure you are uploading an audio file. Supported file extensions are %{ extensions }"
       );
       return {
@@ -304,6 +332,19 @@ export default {
     },
     hasActiveUploads () {
       return this.sortedFiles.filter((f) => { return f.active }).length > 0
+    },
+    remainingSpace () {
+      if (!this.quotaStatus) {
+        return 0
+      }
+      return Math.max(0, this.quotaStatus.remaining - (this.uploadedSize / (1000 * 1000)))
+    },
+    uploadedSize () {
+      let uploaded = 0
+      this.files.forEach((f) => {
+        uploaded += f.size * (f.progress / 100)
+      })
+      return uploaded
     }
   },
   watch: {
@@ -315,7 +356,12 @@ export default {
     },
     importReference: _.debounce(function() {
       this.$router.replace({ query: { import: this.importReference } });
-    }, 500)
+    }, 500),
+    remainingSpace (newValue) {
+      if (newValue <= 0) {
+        this.$refs.upload.active = false;
+      }
+    }
   }
 };
 </script>
diff --git a/front/src/components/library/Home.vue b/front/src/components/library/Home.vue
index 19b667335fe14228118650a44bc080b1ab8fae57..eea8f22c5eb8bdf00b6c539455ace0603c2a3d42 100644
--- a/front/src/components/library/Home.vue
+++ b/front/src/components/library/Home.vue
@@ -4,17 +4,17 @@
       <div class="ui stackable three column grid">
         <div class="column">
           <track-widget :url="'history/listenings/'" :filters="{scope: 'user', ordering: '-creation_date'}">
-            <template slot="title"><translate>Recently listened</translate></template>
+            <template slot="title"><translate translate-context="Content/Home/Title">Recently listened</translate></template>
           </track-widget>
         </div>
         <div class="column">
           <track-widget :url="'favorites/tracks/'" :filters="{scope: 'user', ordering: '-creation_date'}">
-            <template slot="title"><translate>Recently favorited</translate></template>
+            <template slot="title"><translate translate-context="Content/Home/Title">Recently favorited</translate></template>
           </track-widget>
         </div>
         <div class="column">
           <playlist-widget :url="'playlists/'" :filters="{scope: 'user', playable: true, ordering: '-creation_date'}">
-            <template slot="title"><translate>Playlists</translate></template>
+            <template slot="title"><translate translate-context="*/*/*">Playlists</translate></template>
           </playlist-widget>
         </div>
       </div>
@@ -22,7 +22,7 @@
       <div class="ui stackable one column grid">
         <div class="column">
           <album-widget :filters="{playable: true, ordering: '-creation_date'}">
-            <template slot="title"><translate>Recently added</translate></template>
+            <template slot="title"><translate translate-context="Content/Home/Title">Recently added</translate></template>
           </album-widget>
         </div>
       </div>
@@ -62,7 +62,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Home")
+        title: this.$pgettext('Head/Home/Title', "Home")
       }
     }
   },
diff --git a/front/src/components/library/ImportStatusModal.vue b/front/src/components/library/ImportStatusModal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5632e95943cb78571ed55af3a458ab788e7bceca
--- /dev/null
+++ b/front/src/components/library/ImportStatusModal.vue
@@ -0,0 +1,164 @@
+<template>
+
+  <modal :show.sync="showModal">
+    <div class="header">
+      <translate translate-context="Popup/Import/Title">Import detail</translate>
+    </div>
+    <div class="content" v-if="upload">
+      <div class="description">
+        <div class="ui message" v-if="upload.import_status === 'pending'">
+          <translate translate-context="Popup/Import/Message">Upload is still pending and will soon be processed by the server.</translate>
+        </div>
+        <div class="ui success message" v-if="upload.import_status === 'finished'">
+          <translate translate-context="Popup/Import/Message">Upload was successfully processed by the server.</translate>
+        </div>
+        <div class="ui warning message" v-if="upload.import_status === 'skipped'">
+          <translate translate-context="Popup/Import/Message">Upload was skipped because a similar one is already available in one of your libraries.</translate>
+        </div>
+        <div class="ui error message" v-if="upload.import_status === 'errored'">
+          <translate translate-context="Popup/Import/Message">An error occured during upload processing. You will find more information below.</translate>
+        </div>
+        <template v-if="upload.import_status === 'errored'">
+          <table class="ui very basic collapsing celled table">
+            <tbody>
+              <tr>
+                <td>
+                  <translate translate-context="Popup/Import/Table.Label/Noun">Error type</translate>
+                </td>
+                <td>
+                  {{ getErrorData(upload).label }}
+                </td>
+              </tr>
+              <tr>
+                <td>
+                  <translate translate-context="Popup/Import/Table.Label/Noun">Error detail</translate>
+                </td>
+                <td>
+                  {{ getErrorData(upload).detail }}
+                  <ul v-if="getErrorData(upload).errorRows.length > 0">
+                    <li v-for="row in getErrorData(upload).errorRows">
+                      {{ row.key}}: {{ row.value}}
+                    </li>
+                  </ul>
+                </td>
+              </tr>
+              <tr>
+                <td>
+                  <translate translate-context="Popup/Import/Table.Label/Noun">Getting help</translate>
+                </td>
+                <td>
+                  <ul>
+                    <li>
+                      <a :href="getErrorData(upload).documentationUrl" target="_blank">
+                        <translate translate-context="Popup/Import/Table.Label/Value">Read our documentation for this error</translate>
+                      </a>
+                    </li>
+                    <li>
+                      <a :href="getErrorData(upload).supportUrl" target="_blank">
+                        <translate translate-context="Popup/Import/Table.Label/Value">Open a support thread (include the debug information below in your message)</translate>
+                      </a>
+                    </li>
+                  </ul>
+                </td>
+              </tr>
+              <tr>
+                <td>
+                  <translate translate-context="Popup/Import/Table.Label/Noun">Debug information</translate>
+                </td>
+                <td>
+                  <div class="ui form">
+                    <textarea class="ui textarea" rows="10" :value="getErrorData(upload).debugInfo"></textarea>
+                  </div>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </template>
+      </div>
+    </div>
+    <div class="actions">
+      <div class="ui deny button">
+        <translate translate-context="*/*/Button.Label/Verb">Close</translate>
+      </div>
+    </div>
+  </modal>
+</template>
+<script>
+import Modal from '@/components/semantic/Modal'
+
+function getErrors(payload) {
+  let errors = []
+  for (var k in payload) {
+    if (payload.hasOwnProperty(k)) {
+      let value = payload[k]
+      if (Array.isArray(value)) {
+        errors.push({
+          key: k,
+          value: value.join(', ')
+        })
+      } else {
+        // possibly artists, so nested errors
+        if (typeof value === 'object') {
+          getErrors(value).forEach((e) => {
+            errors.push({
+              key: `${k} / ${e.key}`,
+              value: e.value
+            })
+          })
+        }
+      }
+    }
+  }
+  return errors
+}
+
+export default {
+  props: ['upload', "show"],
+  components: {
+    Modal
+  },
+  data () {
+    return {
+      showModal: this.show
+    }
+  },
+  methods: {
+    getErrorData (upload) {
+      let payload = upload.import_details || {}
+      let d = {
+        supportUrl: 'https://governance.funkwhale.audio/g/246YOJ1m/funkwhale-support',
+        errorRows: []
+      }
+      if (!payload.error_code) {
+        d.errorCode = 'unknown_error'
+      } else {
+        d.errorCode = payload.error_code
+      }
+      d.documentationUrl = `https://docs.funkwhale.audio/users/upload.html#${d.errorCode}`
+      if (d.errorCode === 'invalid_metadata') {
+        d.label = this.$pgettext('Popup/Import/Error.Label', 'Invalid metadata')
+        d.detail = this.$pgettext('Popup/Import/Error.Label', 'The metadata included in the file is invalid or some mandatory fields are missing.')
+        let detail = payload.detail || {}
+        d.errorRows = getErrors(detail)
+      } else {
+        d.label = this.$pgettext('Popup/Import/Error.Label', 'Unkwown error')
+        d.detail = this.$pgettext('Popup/Import/Error.Label', 'An unkwown error occured')
+      }
+      let debugInfo = {
+        source: upload.source,
+        ...payload,
+      }
+      d.debugInfo = JSON.stringify(debugInfo, null, 4)
+      return d
+    }
+  },
+  watch: {
+    showModal (v) {
+      this.$emit('update:show', v)
+    },
+    show (v) {
+      this.showModal = v
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/Library.vue b/front/src/components/library/Library.vue
index c0371fe58800145856eaf18c30192565184a183f..ea4d98e6543e7382ead061577fc660d01e8a341d 100644
--- a/front/src/components/library/Library.vue
+++ b/front/src/components/library/Library.vue
@@ -2,16 +2,19 @@
   <div class="main library pusher">
     <nav class="ui secondary pointing menu" role="navigation" :aria-label="labels.secondaryMenu">
       <router-link class="ui item" to="/library" exact>
-        <translate>Browse</translate>
+        <translate translate-context="*/Library/*/Verb">Browse</translate>
+      </router-link>
+      <router-link class="ui item" to="/library/albums" exact>
+        <translate translate-context="*/*/*">Albums</translate>
       </router-link>
       <router-link class="ui item" to="/library/artists" exact>
-        <translate>Artists</translate>
+        <translate translate-context="*/*/*/Noun">Artists</translate>
       </router-link>
       <router-link class="ui item" to="/library/radios" exact>
-        <translate>Radios</translate>
+        <translate translate-context="*/*/*">Radios</translate>
       </router-link>
       <router-link class="ui item" to="/library/playlists" exact>
-        <translate>Playlists</translate>
+        <translate translate-context="*/*/*">Playlists</translate>
       </router-link>
     </nav>
     <router-view :key="$route.fullPath"></router-view>
@@ -29,7 +32,7 @@ export default {
     },
     labels() {
       return {
-        secondaryMenu: this.$gettext("Secondary menu")
+        secondaryMenu: this.$pgettext('Menu/*/Hidden text', "Secondary menu")
       }
     }
   }
diff --git a/front/src/components/library/Radios.vue b/front/src/components/library/Radios.vue
index 5b433dcb2d3da801b819c7171ff5f3859b70268e..9b2f7bf82010bc1eed389ca072468a5c51c62ff0 100644
--- a/front/src/components/library/Radios.vue
+++ b/front/src/components/library/Radios.vue
@@ -2,36 +2,36 @@
   <main v-title="labels.title">
     <section class="ui vertical stripe segment">
       <h2 class="ui header">
-        <translate>Browsing radios</translate>
+        <translate translate-context="Content/Radio/Title">Browsing radios</translate>
       </h2>
       <div class="ui hidden divider"></div>
       <div class="ui row">
         <h3 class="ui header">
-          <translate>Instance radios</translate>
+          <translate translate-context="Content/Radio/Title">Instance radios</translate>
         </h3>
         <div class="ui cards">
-          <radio-card :type="'favorites'"></radio-card>
+          <radio-card v-if="$store.state.auth.authenticated" :type="'favorites'"></radio-card>
           <radio-card :type="'random'"></radio-card>
-          <radio-card :type="'less-listened'"></radio-card>
+          <radio-card v-if="$store.state.auth.authenticated" :type="'less-listened'"></radio-card>
         </div>
       </div>
 
       <div class="ui hidden divider"></div>
       <h3 class="ui header">
-        <translate>User radios</translate>
+        <translate translate-context="Content/Radio/Title">User radios</translate>
       </h3>
       <router-link class="ui green basic button" to="/library/radios/build" exact>
-        <translate>Create your own radio</translate>
+        <translate translate-context="Content/Radio/Button.Label/Verb">Create your own radio</translate>
       </router-link>
       <div class="ui hidden divider"></div>
       <div :class="['ui', {'loading': isLoading}, 'form']">
         <div class="fields">
           <div class="field">
-            <label><translate>Search</translate></label>
+            <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
             <input name="search" type="text" v-model="query" :placeholder="labels.searchPlaceholder"/>
           </div>
           <div class="field">
-            <label><translate>Ordering</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
             <select class="ui dropdown" v-model="ordering">
               <option v-for="option in orderingOptions" :value="option[0]">
                 {{ sharedLabels.filters[option[1]] }}
@@ -39,18 +39,18 @@
             </select>
           </div>
           <div class="field">
-            <label><translate>Order</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Order</translate></label>
             <select class="ui dropdown" v-model="orderingDirection">
               <option value="+">
-                <translate>Ascending</translate>
+                <translate translate-context="Content/Search/Dropdown">Ascending</translate>
               </option>
               <option value="-">
-                <translate>Descending</translate>
+                <translate translate-context="Content/Search/Dropdown">Descending</translate>
               </option>
             </select>
           </div>
           <div class="field">
-            <label><translate>Results per page</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Results per page</translate></label>
             <select class="ui dropdown" v-model="paginateBy">
               <option :value="parseInt(12)">12</option>
               <option :value="parseInt(25)">25</option>
@@ -138,8 +138,8 @@ export default {
   },
   computed: {
     labels() {
-      let searchPlaceholder = this.$gettext("Enter a radio name…")
-      let title = this.$gettext("Radios")
+      let searchPlaceholder = this.$pgettext('Content/Search/Input.Placeholder', "Enter a radio name…")
+      let title = this.$pgettext('*/*/*', "Radios")
       return {
         searchPlaceholder,
         title
diff --git a/front/src/components/library/Track.vue b/front/src/components/library/Track.vue
deleted file mode 100644
index 4e0faaeece2e0073538319a74c69ed68ac7df34e..0000000000000000000000000000000000000000
--- a/front/src/components/library/Track.vue
+++ /dev/null
@@ -1,339 +0,0 @@
-<template>
-  <main>
-    <div v-if="isLoadingTrack" class="ui vertical segment" v-title="labels.title">
-      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
-    </div>
-    <template v-if="track">
-      <section
-        :class="['ui', 'head', {'with-background': cover}, 'vertical', 'center', 'aligned', 'stripe', 'segment']"
-        :style="headerStyle"
-        v-title="track.title"
-      >
-        <div class="segment-content">
-          <h2 class="ui center aligned icon header">
-            <i class="circular inverted music orange icon"></i>
-            <div class="content">
-              {{ track.title }}
-              <div class="sub header">
-                <span
-                  v-translate="{album: track.album.title, artist: track.artist.name}"
-                  :translate-params="{album: track.album.title, artist: track.artist.name}"
-                >From album %{ album } by %{ artist }</span>
-              </div>
-              <br>
-              <div class="ui basic buttons">
-                <router-link
-                  class="ui button"
-                  :to="{name: 'library.albums.detail', params: {id: track.album.id }}"
-                >
-                  <translate>Album page</translate>
-                </router-link>
-                <router-link
-                  class="ui button"
-                  :to="{name: 'library.artists.detail', params: {id: track.artist.id }}"
-                >
-                  <translate>Artist page</translate>
-                </router-link>
-              </div>
-            </div>
-          </h2>
-
-          <play-button class="orange" :track="track">
-            <translate>Play</translate>
-          </play-button>
-          <track-favorite-icon :track="track" :button="true"></track-favorite-icon>
-          <track-playlist-icon :button="true" v-if="$store.state.auth.authenticated" :track="track"></track-playlist-icon>
-
-          <a :href="wikipediaUrl" target="_blank" class="ui button">
-            <i class="wikipedia w icon"></i>
-            <translate>Search on Wikipedia</translate>
-          </a>
-          <a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" class="ui button">
-            <i class="external icon"></i>
-            <translate>View on MusicBrainz</translate>
-          </a>
-          <a v-if="upload" :href="downloadUrl" target="_blank" class="ui button">
-            <i class="download icon"></i>
-            <translate>Download</translate>
-          </a>
-          <template v-if="publicLibraries.length > 0">
-            <button
-              @click="showEmbedModal = !showEmbedModal"
-              class="ui button">
-              <i class="code icon"></i>
-              <translate>Embed</translate>
-            </button>
-            <modal :show.sync="showEmbedModal">
-              <div class="header">
-                <translate>Embed this track on your website</translate>
-              </div>
-              <div class="content">
-                <div class="description">
-                  <embed-wizard type="track" :id="track.id" />
-
-                </div>
-              </div>
-              <div class="actions">
-                <div class="ui deny button">
-                  <translate>Cancel</translate>
-                </div>
-              </div>
-            </modal>
-          </template>
-        </div>
-      </section>
-      <section class="ui vertical stripe center aligned segment">
-        <h2 class="ui header">
-          <translate>Track information</translate>
-        </h2>
-        <table class="ui very basic collapsing celled center aligned table">
-          <tbody>
-            <tr>
-              <td>
-                <translate>Copyright</translate>
-              </td>
-              <td v-if="track.copyright" :title="track.copyright">{{ track.copyright|truncate(50) }}</td>
-              <td v-else>
-                <translate>We don't have any copyright information for this track</translate>
-              </td>
-            </tr>
-            <tr>
-              <td>
-                <translate>License</translate>
-              </td>
-              <td v-if="license">
-                <a :href="license.url" target="_blank" rel="noopener noreferrer">{{ license.name }}</a>
-              </td>
-              <td v-else>
-                <translate>We don't have any licensing information for this track</translate>
-              </td>
-            </tr>
-            <tr>
-              <td>
-                <translate>Duration</translate>
-              </td>
-              <td v-if="upload && upload.duration">{{ time.parse(upload.duration) }}</td>
-              <td v-else>
-                <translate>N/A</translate>
-              </td>
-            </tr>
-            <tr>
-              <td>
-                <translate>Size</translate>
-              </td>
-              <td v-if="upload && upload.size">{{ upload.size | humanSize }}</td>
-              <td v-else>
-                <translate>N/A</translate>
-              </td>
-            </tr>
-            <tr>
-              <td>
-                <translate>Bitrate</translate>
-              </td>
-              <td v-if="upload && upload.bitrate">{{ upload.bitrate | humanSize }}/s</td>
-              <td v-else>
-                <translate>N/A</translate>
-              </td>
-            </tr>
-            <tr>
-              <td>
-                <translate>Type</translate>
-              </td>
-              <td v-if="upload && upload.extension">{{ upload.extension }}</td>
-              <td v-else>
-                <translate>N/A</translate>
-              </td>
-            </tr>
-          </tbody>
-        </table>
-      </section>
-      <section class="ui vertical stripe center aligned segment">
-        <h2>
-          <translate>Lyrics</translate>
-        </h2>
-        <div v-if="isLoadingLyrics" class="ui vertical segment">
-          <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
-        </div>
-        <div v-if="lyrics" v-html="lyrics.content_rendered"></div>
-        <template v-if="!isLoadingLyrics & !lyrics">
-          <p>
-            <translate>No lyrics available for this track.</translate>
-          </p>
-          <a class="ui button" target="_blank" :href="lyricsSearchUrl">
-            <i class="search icon"></i>
-            <translate>Search on lyrics.wikia.com</translate>
-          </a>
-        </template>
-      </section>
-      <section class="ui vertical stripe segment">
-        <h2>
-          <translate>User libraries</translate>
-        </h2>
-        <library-widget @loaded="libraries = $event" :url="'tracks/' + id + '/libraries/'">
-          <translate slot="subtitle">This track is present in the following libraries:</translate>
-        </library-widget>
-      </section>
-    </template>
-  </main>
-</template>
-
-<script>
-import time from "@/utils/time"
-import axios from "axios"
-import url from "@/utils/url"
-import logger from "@/logging"
-import PlayButton from "@/components/audio/PlayButton"
-import TrackFavoriteIcon from "@/components/favorites/TrackFavoriteIcon"
-import TrackPlaylistIcon from "@/components/playlists/TrackPlaylistIcon"
-import LibraryWidget from "@/components/federation/LibraryWidget"
-import Modal from '@/components/semantic/Modal'
-import EmbedWizard from "@/components/audio/EmbedWizard"
-
-const FETCH_URL = "tracks/"
-
-export default {
-  props: ["id"],
-  components: {
-    PlayButton,
-    TrackPlaylistIcon,
-    TrackFavoriteIcon,
-    LibraryWidget,
-    Modal,
-    EmbedWizard
-  },
-  data() {
-    return {
-      time,
-      isLoadingTrack: true,
-      isLoadingLyrics: true,
-      track: null,
-      lyrics: null,
-      licenseData: null,
-      libraries: [],
-      showEmbedModal: false
-    }
-  },
-  created() {
-    this.fetchData()
-    this.fetchLyrics()
-  },
-  methods: {
-    fetchData() {
-      var self = this
-      this.isLoadingTrack = true
-      let url = FETCH_URL + this.id + "/"
-      logger.default.debug('Fetching track "' + this.id + '"')
-      axios.get(url).then(response => {
-        self.track = response.data
-        self.isLoadingTrack = false
-      })
-    },
-    fetchLicenseData(licenseId) {
-      var self = this
-      let url = `licenses/${licenseId}/`
-      axios.get(url).then(response => {
-        self.licenseData = response.data
-      })
-    },
-    fetchLyrics() {
-      var self = this
-      this.isLoadingLyrics = true
-      let url = FETCH_URL + this.id + "/lyrics/"
-      logger.default.debug('Fetching lyrics for track "' + this.id + '"')
-      axios.get(url).then(
-        response => {
-          self.lyrics = response.data
-          self.isLoadingLyrics = false
-        },
-        response => {
-          console.error("No lyrics available")
-          self.isLoadingLyrics = false
-        }
-      )
-    }
-  },
-  computed: {
-    publicLibraries () {
-      return this.libraries.filter(l => {
-        return l.privacy_level === 'everyone'
-      })
-    },
-    labels() {
-      return {
-        title: this.$gettext("Track")
-      }
-    },
-    upload() {
-      if (this.track.uploads) {
-        return this.track.uploads[0]
-      }
-    },
-    wikipediaUrl() {
-      return (
-        "https://en.wikipedia.org/w/index.php?search=" +
-        encodeURI(this.track.title + " " + this.track.artist.name)
-      )
-    },
-    musicbrainzUrl() {
-      if (this.track.mbid) {
-        return "https://musicbrainz.org/recording/" + this.track.mbid
-      }
-    },
-    downloadUrl() {
-      let u = this.$store.getters["instance/absoluteUrl"](
-        this.upload.listen_url
-      )
-      if (this.$store.state.auth.authenticated) {
-        u = url.updateQueryString(
-          u,
-          "jwt",
-          encodeURI(this.$store.state.auth.token)
-        )
-      }
-      return u
-    },
-    lyricsSearchUrl() {
-      let base = "http://lyrics.wikia.com/wiki/Special:Search?query="
-      let query = this.track.artist.name + ":" + this.track.title
-      return base + encodeURI(query)
-    },
-    cover() {
-      return null
-    },
-    headerStyle() {
-      if (!this.cover) {
-        return ""
-      }
-      return (
-        "background-image: url(" +
-        this.$store.getters["instance/absoluteUrl"](this.cover) +
-        ")"
-      )
-    },
-    license() {
-      if (!this.track || !this.track.license) {
-        return null
-      }
-      return this.licenseData
-    }
-  },
-  watch: {
-    id() {
-      this.fetchData()
-    },
-    track (v) {
-      if (v && v.license) {
-        this.fetchLicenseData(v.license)
-      }
-    }
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="scss">
-.table.center.aligned {
-  margin-left: auto;
-  margin-right: auto;
-}
-</style>
diff --git a/front/src/components/library/TrackBase.vue b/front/src/components/library/TrackBase.vue
new file mode 100644
index 0000000000000000000000000000000000000000..639c8f51b83c63166d1ec4d70d668a82352e48a1
--- /dev/null
+++ b/front/src/components/library/TrackBase.vue
@@ -0,0 +1,228 @@
+<template>
+  <main>
+    <div v-if="isLoadingTrack" class="ui vertical segment" v-title="labels.title">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="track">
+      <section
+        :class="['ui', 'head', {'with-background': cover}, 'vertical', 'center', 'aligned', 'stripe', 'segment']"
+        :style="headerStyle"
+        v-title="track.title"
+      >
+        <div class="segment-content">
+          <h2 class="ui center aligned icon header">
+            <i class="circular inverted music orange icon"></i>
+            <div class="content">
+              {{ track.title }}
+              <div class="sub header">
+                <div translate-context="Content/Track/Paragraph"
+                  v-translate="{album: track.album.title, artist: track.artist.name, albumUrl: albumUrl, artistUrl: artistUrl}"
+                >From album <a class="internal" href="%{ albumUrl }">%{ album }</a> by <a class="internal" href="%{ artistUrl }">%{ artist }</a></div>
+              </div>
+            </div>
+          </h2>
+          <div class="header-buttons">
+            <div class="ui buttons">
+              <play-button class="orange" :track="track">
+                <translate translate-context="*/Queue/Button.Label/Short, Verb">Play</translate>
+              </play-button>
+            </div>
+            <div class="ui buttons">
+              <track-favorite-icon :track="track" :button="true"></track-favorite-icon>
+            </div>
+            <div class="ui buttons">
+              <track-playlist-icon :button="true" v-if="$store.state.auth.authenticated" :track="track"></track-playlist-icon>
+            </div>
+
+            <div class="ui buttons">
+              <a v-if="upload" :href="downloadUrl" target="_blank" class="ui icon labeled button">
+                <i class="download icon"></i>
+                <translate translate-context="Content/Track/Link/Verb">Download</translate>
+              </a>
+            </div>
+
+            <modal v-if="publicLibraries.length > 0" :show.sync="showEmbedModal">
+              <div class="header">
+                <translate translate-context="Popup/Track/Title">Embed this track on your website</translate>
+              </div>
+              <div class="content">
+                <div class="description">
+                  <embed-wizard type="track" :id="track.id" />
+
+                </div>
+              </div>
+              <div class="actions">
+                <div class="ui deny button">
+                  <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
+                </div>
+              </div>
+            </modal>
+            <div class="ui buttons">
+              <button class="ui button" @click="$refs.dropdown.click()">
+                <translate translate-context="*/*/Button.Label/Noun">More…</translate>
+              </button>
+              <div class="ui floating dropdown icon button" ref="dropdown" v-dropdown>
+                <i class="dropdown icon"></i>
+                <div class="menu">
+                  <div
+                    role="button"
+                    v-if="publicLibraries.length > 0"
+                    @click="showEmbedModal = !showEmbedModal"
+                    class="basic item">
+                    <i class="code icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Embed</translate>
+                  </div>
+                  <a :href="wikipediaUrl" target="_blank" rel="noreferrer noopener" class="basic item">
+                    <i class="wikipedia w icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Search on Wikipedia</translate>
+                  </a>
+                  <a v-if="musicbrainzUrl" :href="musicbrainzUrl" target="_blank" rel="noreferrer noopener" class="basic item">
+                    <i class="external icon"></i>
+                    <translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
+                  </a>
+                  <router-link
+                    v-if="track.is_local"
+                    :to="{name: 'library.tracks.edit', params: {id: track.id }}"
+                    class="basic item">
+                    <i class="edit icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
+                  </router-link>
+                  <div class="divider"></div>
+                  <router-link class="basic item" v-if="$store.state.auth.availablePermissions['library']" :to="{name: 'manage.library.tracks.detail', params: {id: track.id}}">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link">Open in moderation interface</translate>
+                  </router-link>
+                  <a
+                    v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="basic item"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/track/${track.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <router-view v-if="track" @libraries-loaded="libraries = $event" :track="track" :object="track" object-type="track" :key="$route.fullPath"></router-view>
+    </template>
+  </main>
+</template>
+
+<script>
+import time from "@/utils/time"
+import axios from "axios"
+import url from "@/utils/url"
+import logger from "@/logging"
+import PlayButton from "@/components/audio/PlayButton"
+import TrackFavoriteIcon from "@/components/favorites/TrackFavoriteIcon"
+import TrackPlaylistIcon from "@/components/playlists/TrackPlaylistIcon"
+import Modal from '@/components/semantic/Modal'
+import EmbedWizard from "@/components/audio/EmbedWizard"
+
+const FETCH_URL = "tracks/"
+
+export default {
+  props: ["id"],
+  components: {
+    PlayButton,
+    TrackPlaylistIcon,
+    TrackFavoriteIcon,
+    Modal,
+    EmbedWizard
+  },
+  data() {
+    return {
+      time,
+      isLoadingTrack: true,
+      track: null,
+      showEmbedModal: false,
+      libraries: []
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoadingTrack = true
+      let url = FETCH_URL + this.id + "/"
+      logger.default.debug('Fetching track "' + this.id + '"')
+      axios.get(url).then(response => {
+        self.track = response.data
+        self.isLoadingTrack = false
+      })
+    },
+  },
+  computed: {
+    publicLibraries () {
+      return this.libraries.filter(l => {
+        return l.privacy_level === 'everyone'
+      })
+    },
+    upload() {
+      if (this.track.uploads) {
+        return this.track.uploads[0]
+      }
+    },
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*/Noun', "Track")
+      }
+    },
+    wikipediaUrl() {
+      return (
+        "https://en.wikipedia.org/w/index.php?search=" +
+        encodeURI(this.track.title + " " + this.track.artist.name)
+      )
+    },
+    musicbrainzUrl() {
+      if (this.track.mbid) {
+        return "https://musicbrainz.org/recording/" + this.track.mbid
+      }
+    },
+    downloadUrl() {
+      let u = this.$store.getters["instance/absoluteUrl"](
+        this.upload.listen_url
+      )
+      if (this.$store.state.auth.authenticated) {
+        u = url.updateQueryString(
+          u,
+          "jwt",
+          encodeURI(this.$store.state.auth.token)
+        )
+      }
+      return u
+    },
+    cover() {
+      return null
+    },
+    albumUrl () {
+      let route = this.$router.resolve({name: 'library.albums.detail', params: {id: this.track.album.id }})
+      return route.location.path
+    },
+    artistUrl () {
+      let route = this.$router.resolve({name: 'library.artists.detail', params: {id: this.track.artist.id }})
+      return route.location.path
+    },
+    headerStyle() {
+      if (!this.cover) {
+        return ""
+      }
+      return (
+        "background-image: url(" +
+        this.$store.getters["instance/absoluteUrl"](this.cover) +
+        ")"
+      )
+    },
+  },
+  watch: {
+    id() {
+      this.fetchData()
+    },
+  }
+}
+</script>
diff --git a/front/src/components/library/TrackDetail.vue b/front/src/components/library/TrackDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2eb9a0009b0bbf813b19a1affdcd2d4f129c6a7c
--- /dev/null
+++ b/front/src/components/library/TrackDetail.vue
@@ -0,0 +1,159 @@
+<template>
+
+  <div v-if="track">
+    <section class="ui vertical stripe center aligned segment">
+      <h2 class="ui header">
+        <translate translate-context="Content/Track/Title/Noun">Track information</translate>
+      </h2>
+      <table class="ui very basic collapsing celled center aligned table">
+        <tbody>
+          <tr>
+            <td>
+              <translate translate-context="Content/Track/Table.Label/Noun">Copyright</translate>
+            </td>
+            <td v-if="track.copyright" :title="track.copyright">{{ track.copyright|truncate(50) }}</td>
+            <td v-else>
+              <translate translate-context="Content/Track/Table.Paragraph">No copyright information available for this track</translate>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <translate translate-context="Content/*/*/Noun">License</translate>
+            </td>
+            <td v-if="license">
+              <a :href="license.url" target="_blank" rel="noopener noreferrer">{{ license.name }}</a>
+            </td>
+            <td v-else>
+              <translate translate-context="Content/Track/Table.Paragraph">No licensing information for this track</translate>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <translate translate-context="Content/*/*">Duration</translate>
+            </td>
+            <td v-if="upload && upload.duration">{{ time.parse(upload.duration) }}</td>
+            <td v-else>
+              <translate translate-context="*/*/*">N/A</translate>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <translate translate-context="Content/Library/*/in MB">Size</translate>
+            </td>
+            <td v-if="upload && upload.size">{{ upload.size | humanSize }}</td>
+            <td v-else>
+              <translate translate-context="*/*/*">N/A</translate>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <translate translate-context="Content/Track/*/Noun">Bitrate</translate>
+            </td>
+            <td v-if="upload && upload.bitrate">{{ upload.bitrate | humanSize }}/s</td>
+            <td v-else>
+              <translate translate-context="*/*/*">N/A</translate>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <translate translate-context="Content/Track/Table.Label/Noun">Type</translate>
+            </td>
+            <td v-if="upload && upload.extension">{{ upload.extension }}</td>
+            <td v-else>
+              <translate translate-context="*/*/*">N/A</translate>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <translate translate-context="Content/*/*/Noun">Federation ID</translate>
+            </td>
+            <td :title="track.fid">
+              <a :href="track.fid" target="_blank" rel="noopener noreferrer">
+                {{ track.fid|truncate(65)}}
+              </a>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </section>
+    <section class="ui vertical stripe segment">
+      <h2>
+        <translate translate-context="Content/*/Title/Noun">User libraries</translate>
+      </h2>
+      <library-widget @loaded="$emit('libraries-loaded', $event)" :url="'tracks/' + id + '/libraries/'">
+        <translate translate-context="Content/Track/Paragraph" slot="subtitle">This track is present in the following libraries:</translate>
+      </library-widget>
+    </section>
+  </div>
+</template>
+
+<script>
+import time from "@/utils/time"
+import axios from "axios"
+import url from "@/utils/url"
+import logger from "@/logging"
+import LibraryWidget from "@/components/federation/LibraryWidget"
+
+const FETCH_URL = "tracks/"
+
+export default {
+  props: ["track", "libraries"],
+  components: {
+    LibraryWidget,
+  },
+  data() {
+    return {
+      time,
+      id: this.track.id,
+      licenseData: null
+    }
+  },
+  created() {
+    if (this.track && this.track.license) {
+      this.fetchLicenseData(this.track.license)
+    }
+  },
+  methods: {
+    fetchLicenseData(licenseId) {
+      var self = this
+      let url = `licenses/${licenseId}/`
+      axios.get(url).then(response => {
+        self.licenseData = response.data
+      })
+    },
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*/Noun', "Track")
+      }
+    },
+    upload() {
+      if (this.track.uploads) {
+        return this.track.uploads[0]
+      }
+    },
+    license() {
+      if (!this.track || !this.track.license) {
+        return null
+      }
+      return this.licenseData
+    }
+  },
+  watch: {
+    track (v) {
+      if (v && v.license) {
+        this.fetchLicenseData(v.license)
+      }
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped lang="scss">
+.table.center.aligned {
+  margin-left: auto;
+  margin-right: auto;
+}
+</style>
diff --git a/front/src/components/library/TrackEdit.vue b/front/src/components/library/TrackEdit.vue
new file mode 100644
index 0000000000000000000000000000000000000000..18e71e8fa62ea25884ff72819699c2dafbba591d
--- /dev/null
+++ b/front/src/components/library/TrackEdit.vue
@@ -0,0 +1,60 @@
+<template>
+
+  <section class="ui vertical stripe segment">
+    <div class="ui text container">
+      <h2>
+        <translate v-if="canEdit" key="1" translate-context="Content/*/Title">Edit this track</translate>
+        <translate v-else key="2" translate-context="Content/*/Title">Suggest an edit on this track</translate>
+      </h2>
+      <div class="ui message" v-if="!object.is_local">
+        <translate translate-context="Content/*/Message">This object is managed by another server, you cannot edit it.</translate>
+      </div>
+      <edit-form
+        v-else-if="!isLoadingLicenses"
+        :object-type="objectType"
+        :object="object"
+        :can-edit="canEdit"
+        :licenses="licenses"></edit-form>
+      <div v-else class="ui inverted active dimmer">
+        <div class="ui loader"></div>
+      </div>
+    </div>
+  </section>
+</template>
+
+<script>
+import axios from "axios"
+
+import EditForm from '@/components/library/EditForm'
+export default {
+  props: ["objectType", "object", "libraries"],
+  data() {
+    return {
+      id: this.object.id,
+      isLoadingLicenses: false,
+      licenses: []
+    }
+  },
+  components: {
+    EditForm
+  },
+  created () {
+    this.fetchLicenses()
+  },
+  methods: {
+    fetchLicenses () {
+      let self = this
+      self.isLoadingLicenses = true
+      axios.get('licenses/').then((response) => {
+        self.isLoadingLicenses = false
+        self.licenses = response.data.results
+      })
+    }
+  },
+  computed: {
+    canEdit () {
+      return true
+    }
+  }
+}
+</script>
diff --git a/front/src/components/library/radios/Builder.vue b/front/src/components/library/radios/Builder.vue
index 77a63b86d8af952cf6eb01db8a43622ac9cd8d6e..c6101a3200b0def3a9b3249dbba6bdbb70e740c1 100644
--- a/front/src/components/library/radios/Builder.vue
+++ b/front/src/components/library/radios/Builder.vue
@@ -3,52 +3,53 @@
     <div>
       <section>
         <h2 class="ui header">
-          <translate>Builder</translate>
+          <translate translate-context="Content/Radio/Title">Builder</translate>
         </h2>
-        <p><translate>You can use this interface to build your own custom radio, which will play tracks according to your criteria.</translate></p>
+        <p><translate translate-context="Content/Radio/Paragraph">You can use this interface to build your own custom radio, which will play tracks according to your criteria.</translate></p>
         <div class="ui form">
           <div v-if="success" class="ui positive message">
             <div class="header">
               <template v-if="radioName">
-                <translate>Radio updated</translate>
+                <translate translate-context="Content/Radio/Message">Radio updated</translate>
               </template>
               <template v-else>
-                <translate>Radio created</translate>
+                <translate translate-context="Content/Radio/Message">Radio created</translate>
               </template>
             </div>
           </div>
           <div class="">
             <div class="field">
-              <label for="name"><translate>Radio name</translate></label>
+              <label for="name"><translate translate-context="Content/Radio/Input.Label/Noun">Radio name</translate></label>
               <input id="name" name="name" type="text" v-model="radioName" :placeholder="labels.placeholder.name" />
             </div>
             <div class="field">
-              <label for="description"><translate>Description</translate></label>
+              <label for="description"><translate translate-context="Content/*/Input.Label/Noun">Description</translate></label>
               <textarea rows="2" id="description" type="text" v-model="radioDesc" :placeholder="labels.placeholder.description" />
             </div>
-            <div class="inline field">
+            <div class="ui toggle checkbox">
               <input id="public" type="checkbox" v-model="isPublic" />
-              <label for="public"><translate>Display publicly</translate></label>
+              <label for="public"><translate translate-context="Content/Radio/Checkbox.Label/Verb">Display publicly</translate></label>
             </div>
+            <div class="ui hidden divider"></div>
             <button :disabled="!canSave" @click="save" :class="['ui', 'green', {loading: isLoading}, 'button']">
-              <translate>Save</translate>
+              <translate translate-context="Content/*/Button.Label/Verb">Save</translate>
             </button>
             <radio-button v-if="id" type="custom" :custom-radio-id="id"></radio-button>
           </div>
         </div>
         <div class="ui form">
           <p>
-            <translate>Add filters to customize your radio</translate>
+            <translate translate-context="Content/Radio/Paragraph">Add filters to customize your radio</translate>
           </p>
           <div class="inline field">
             <select class="ui dropdown" v-model="currentFilterType">
               <option value="">
-                <translate>Select a filter</translate>
+                <translate translate-context="Content/Radio/Dropdown.Placeholder/Verb">Select a filter</translate>
               </option>
               <option v-for="f in availableFilters" :value="f.type">{{ f.label }}</option>
             </select>
             <button :disabled="!currentFilterType" @click="add" class="ui button">
-              <translate>Add filter</translate>
+              <translate translate-context="Content/Radio/Button.Label/Verb">Add filter</translate>
             </button>
           </div>
           <p v-if="currentFilter">
@@ -58,11 +59,11 @@
         <table class="ui table">
           <thead>
             <tr>
-              <th class="two wide"><translate>Filter name</translate></th>
-              <th class="one wide"><translate>Exclude</translate></th>
-              <th class="six wide"><translate>Config</translate></th>
-              <th class="five wide"><translate>Candidates</translate></th>
-              <th class="two wide"><translate>Actions</translate></th>
+              <th class="two wide"><translate translate-context="Content/Radio/Table.Label/Noun">Filter name</translate></th>
+              <th class="one wide"><translate translate-context="Content/Radio/Table.Label/Verb">Exclude</translate></th>
+              <th class="six wide"><translate translate-context="Content/Radio/Table.Label/Verb (Value is a List of Parameters)">Config</translate></th>
+              <th class="five wide"><translate translate-context="Content/Radio/Table.Label/Noun (Value is a number of Tracks)">Candidates</translate></th>
+              <th class="two wide"><translate translate-context="Content/*/*/Noun">Actions</translate></th>
             </tr>
           </thead>
           <tbody>
@@ -82,7 +83,8 @@
             class="ui header"
             v-translate="{count: checkResult.candidates.count}"
             :translate-n="checkResult.candidates.count"
-            translate-plural="%{ count } tracks matching combined filters">
+            translate-plural="%{ count } tracks matching combined filters"
+            translate-context="Content/Radio/Table.Paragraph/Short">
             %{ count } track matching combined filters
           </h3>
           <track-table v-if="checkResult.candidates.sample" :tracks="checkResult.candidates.sample" :playable="true"></track-table>
@@ -230,10 +232,10 @@ export default {
   },
   computed: {
     labels() {
-      let title = this.$gettext("Radio Builder")
+      let title = this.$pgettext('Head/Radio/Title', "Radio Builder")
       let placeholder = {
-        name: this.$gettext("My awesome radio"),
-        description: this.$gettext("My awesome description")
+        name: this.$pgettext('Content/Radio/Input.Placeholder', "My awesome radio"),
+        description: this.$pgettext('Content/Radio/Input.Placeholder', "My awesome description")
       }
       return {
         title,
diff --git a/front/src/components/library/radios/Filter.vue b/front/src/components/library/radios/Filter.vue
index fcf5efb8de7d8eb751c702ae0c8c410219e63dd4..b0eabbd6e6054f5be4a6afbee00e16fb2d423a26 100644
--- a/front/src/components/library/radios/Filter.vue
+++ b/front/src/components/library/radios/Filter.vue
@@ -42,7 +42,7 @@
       </span>
       <modal v-if="checkResult" :show.sync="showCandidadesModal">
         <div class="header">
-          <translate>Track matching filter</translate>
+          <translate translate-context="Popup/Radio/Title/Noun">Tracks matching filter</translate>
         </div>
         <div class="content">
           <div class="description">
@@ -51,13 +51,13 @@
         </div>
         <div class="actions">
           <div class="ui black deny button">
-            <translate>Cancel</translate>
+            <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
           </div>
         </div>
       </modal>
     </td>
     <td>
-      <button @click="$emit('delete', index)" class="ui basic red button"><translate>Remove</translate></button>
+      <button @click="$emit('delete', index)" class="ui basic red button"><translate translate-context="Content/Radio/Button.Label/Verb">Remove</translate></button>
     </td>
   </tr>
 </template>
diff --git a/front/src/components/manage/library/AlbumsTable.vue b/front/src/components/manage/library/AlbumsTable.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3af2da4db9bccd1d5d691f2b0ee9152fe9d2b7e1
--- /dev/null
+++ b/front/src/components/manage/library/AlbumsTable.vue
@@ -0,0 +1,218 @@
+<template>
+  <div>
+    <div class="ui inline form">
+      <div class="fields">
+        <div class="ui six wide field">
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
+          <form @submit.prevent="search.query = $refs.search.value">
+            <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
+          </form>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
+          <select class="ui dropdown" v-model="ordering">
+            <option v-for="option in orderingOptions" :value="option[0]">
+              {{ sharedLabels.filters[option[1]] }}
+            </option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
+          <select class="ui dropdown" v-model="orderingDirection">
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
+          </select>
+        </div>
+      </div>
+      </div>
+    <div class="dimmable">
+      <div v-if="isLoading" class="ui active inverted dimmer">
+          <div class="ui loader"></div>
+      </div>
+      <action-table
+        v-if="result"
+        @action-launched="fetchData"
+        :objects-data="result"
+        :actions="actions"
+        action-url="manage/library/albums/action/"
+        :filters="actionFilters">
+        <template slot="header-cells">
+          <th><translate translate-context="*/*/*">Title</translate></th>
+          <th><translate translate-context="*/*/*">Artist</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
+          <th><translate translate-context="*/*/*">Tracks</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Release date</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+        </template>
+        <template slot="row-cells" slot-scope="scope">
+          <td>
+            <router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.id }}">{{ scope.obj.title }}</router-link>
+          </td>
+          <td>
+            <router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
+              <i class="wrench icon"></i>
+            </router-link>
+            <span role="button" class="discrete link" @click="addSearchToken('artist', scope.obj.artist.name)" :title="scope.obj.artist.name">{{ scope.obj.artist.name }}</span>
+          </td>
+          <td>
+            <template v-if="!scope.obj.is_local">
+              <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
+                <i class="wrench icon"></i>
+              </router-link>
+              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+            </template>
+            <span role="button" v-else class="ui tiny teal icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+              <i class="home icon"></i>
+              <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+            </span>
+          </td>
+          <td>
+            {{ scope.obj.tracks.length }}
+          </td>
+          <td>
+            <human-date v-if="scope.obj.release_date" :date="scope.obj.release_date"></human-date>
+            <translate v-else translate-context="*/*/*">N/A</translate>
+
+          </td>
+          <td>
+            <human-date :date="scope.obj.creation_date"></human-date>
+          </td>
+        </template>
+      </action-table>
+    </div>
+    <div>
+      <pagination
+        v-if="result && result.count > paginateBy"
+        @page-changed="selectPage"
+        :compact="true"
+        :current="page"
+        :paginate-by="paginateBy"
+        :total="result.count"
+        ></pagination>
+
+      <span v-if="result && result.results.length > 0">
+        <translate translate-context="Content/*/Paragraph"
+          :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
+          Showing results %{ start }-%{ end } on %{ total }
+        </translate>
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import _ from '@/lodash'
+import time from '@/utils/time'
+import {normalizeQuery, parseTokens} from '@/search'
+import Pagination from '@/components/Pagination'
+import ActionTable from '@/components/common/ActionTable'
+import OrderingMixin from '@/components/mixins/Ordering'
+import TranslationsMixin from '@/components/mixins/Translations'
+import SmartSearchMixin from '@/components/mixins/SmartSearch'
+
+
+export default {
+  mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
+  props: {
+    filters: {type: Object, required: false},
+  },
+  components: {
+    Pagination,
+    ActionTable
+  },
+  data () {
+    let defaultOrdering = this.getOrderingFromString(this.defaultOrdering || '-creation_date')
+    return {
+      time,
+      isLoading: false,
+      result: null,
+      page: 1,
+      paginateBy: 50,
+      search: {
+        query: this.defaultQuery,
+        tokens: parseTokens(normalizeQuery(this.defaultQuery))
+      },
+      orderingDirection: defaultOrdering.direction || '+',
+      ordering: defaultOrdering.field,
+      orderingOptions: [
+        ['creation_date', 'creation_date'],
+        ['release_date', 'release_date'],
+        ["name", "name"],
+      ]
+    }
+  },
+  created () {
+    this.fetchData()
+  },
+  methods: {
+    fetchData () {
+      let params = _.merge({
+        'page': this.page,
+        'page_size': this.paginateBy,
+        'q': this.search.query,
+        'ordering': this.getOrderingAsString()
+      }, this.filters)
+      let self = this
+      self.isLoading = true
+      self.checked = []
+      axios.get('/manage/library/albums/', {params: params}).then((response) => {
+        self.result = response.data
+        self.isLoading = false
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+    selectPage: function (page) {
+      this.page = page
+    },
+  },
+  computed: {
+    labels () {
+      return {
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by domain, title, artist, MusicBrainz ID…')
+      }
+    },
+    actionFilters () {
+      var currentFilters = {
+        q: this.search.query
+      }
+      if (this.filters) {
+        return _.merge(currentFilters, this.filters)
+      } else {
+        return currentFilters
+      }
+    },
+    actions () {
+      let deleteLabel = this.$pgettext('*/*/*/Verb', 'Delete')
+      let confirmationMessage = this.$pgettext('Popup/*/Paragraph', 'The selected albums will be removed, as well as associated tracks, uploads, favorites and listening history. This action is irreversible.')
+      return [
+        {
+          name: 'delete',
+          label: deleteLabel,
+          confirmationMessage: confirmationMessage,
+          isDangerous: true,
+          allowAll: false,
+          confirmColor: 'red',
+        },
+      ]
+    }
+  },
+  watch: {
+    search (newValue) {
+      this.page = 1
+      this.fetchData()
+    },
+    page () {
+      this.fetchData()
+    },
+    ordering () {
+      this.fetchData()
+    },
+    orderingDirection () {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/manage/library/FilesTable.vue b/front/src/components/manage/library/ArtistsTable.vue
similarity index 52%
rename from front/src/components/manage/library/FilesTable.vue
rename to front/src/components/manage/library/ArtistsTable.vue
index 23f33d0f350922d450a56944f976f077a0063648..84c873832d5f3429565b4fd55caec6e03c1501bf 100644
--- a/front/src/components/manage/library/FilesTable.vue
+++ b/front/src/components/manage/library/ArtistsTable.vue
@@ -2,12 +2,14 @@
   <div>
     <div class="ui inline form">
       <div class="fields">
-        <div class="ui field">
-          <label><translate>Search</translate></label>
-          <input name="search" type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
+        <div class="ui six wide field">
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
+          <form @submit.prevent="search.query = $refs.search.value">
+            <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
+          </form>
         </div>
         <div class="field">
-          <label><translate>Ordering</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
           <select class="ui dropdown" v-model="ordering">
             <option v-for="option in orderingOptions" :value="option[0]">
               {{ sharedLabels.filters[option[1]] }}
@@ -15,10 +17,10 @@
           </select>
         </div>
         <div class="field">
-          <label><translate>Order</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
           <select class="ui dropdown" v-model="orderingDirection">
-            <option value="+"><translate>Ascending</translate></option>
-            <option value="-"><translate>Descending</translate></option>
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
           </select>
         </div>
       </div>
@@ -32,54 +34,39 @@
         @action-launched="fetchData"
         :objects-data="result"
         :actions="actions"
-        :action-url="'manage/library/uploads/action/'"
+        action-url="manage/library/artists/action/"
         :filters="actionFilters">
         <template slot="header-cells">
-          <th><translate>Title</translate></th>
-          <th><translate>Artist</translate></th>
-          <th><translate>Album</translate></th>
-          <th><translate>Import date</translate></th>
-          <th><translate>Type</translate></th>
-          <th><translate>Bitrate</translate></th>
-          <th><translate>Duration</translate></th>
-          <th><translate>Size</translate></th>
+          <th><translate translate-context="*/*/*/Noun">Name</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
+          <th><translate translate-context="*/*/*">Albums</translate></th>
+          <th><translate translate-context="*/*/*">Tracks</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
         </template>
         <template slot="row-cells" slot-scope="scope">
           <td>
-            <span :title="scope.obj.track.title">{{ scope.obj.track.title|truncate(30) }}</span>
+            <router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.id }}">{{ scope.obj.name }}</router-link>
           </td>
           <td>
-            <span :title="scope.obj.track.artist.name">{{ scope.obj.track.artist.name|truncate(30) }}</span>
+            <template v-if="!scope.obj.is_local">
+              <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
+                <i class="wrench icon"></i>
+              </router-link>
+              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+            </template>
+            <span role="button" v-else class="ui tiny teal icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+              <i class="home icon"></i>
+              <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+            </span>
           </td>
           <td>
-            <span :title="scope.obj.track.album.title">{{ scope.obj.track.album.title|truncate(20) }}</span>
+            {{ scope.obj.albums.length }}
           </td>
           <td>
-            <human-date :date="scope.obj.creation_date"></human-date>
-          </td>
-          <td v-if="scope.obj.mimetype">
-            {{ scope.obj.mimetype }}
-          </td>
-          <td v-else>
-            <translate>N/A</translate>
-          </td>
-          <td v-if="scope.obj.bitrate">
-            {{ scope.obj.bitrate | humanSize }}/s
-          </td>
-          <td v-else>
-            <translate>N/A</translate>
-          </td>
-          <td v-if="scope.obj.duration">
-            {{ time.parse(scope.obj.duration) }}
-          </td>
-          <td v-else>
-            <translate>N/A</translate>
+            {{ scope.obj.tracks.length }}
           </td>
-          <td v-if="scope.obj.size">
-            {{ scope.obj.size | humanSize }}
-          </td>
-          <td v-else>
-            <translate>N/A</translate>
+          <td>
+            <human-date :date="scope.obj.creation_date"></human-date>
           </td>
         </template>
       </action-table>
@@ -95,7 +82,7 @@
         ></pagination>
 
       <span v-if="result && result.results.length > 0">
-        <translate
+        <translate translate-context="Content/*/Paragraph"
           :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
           Showing results %{ start }-%{ end } on %{ total }
         </translate>
@@ -108,15 +95,18 @@
 import axios from 'axios'
 import _ from '@/lodash'
 import time from '@/utils/time'
+import {normalizeQuery, parseTokens} from '@/search'
 import Pagination from '@/components/Pagination'
 import ActionTable from '@/components/common/ActionTable'
 import OrderingMixin from '@/components/mixins/Ordering'
 import TranslationsMixin from '@/components/mixins/Translations'
+import SmartSearchMixin from '@/components/mixins/SmartSearch'
+
 
 export default {
-  mixins: [OrderingMixin, TranslationsMixin],
+  mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
   props: {
-    filters: {type: Object, required: false}
+    filters: {type: Object, required: false},
   },
   components: {
     Pagination,
@@ -129,19 +119,17 @@ export default {
       isLoading: false,
       result: null,
       page: 1,
-      paginateBy: 25,
-      search: '',
+      paginateBy: 50,
+      search: {
+        query: this.defaultQuery,
+        tokens: parseTokens(normalizeQuery(this.defaultQuery))
+      },
       orderingDirection: defaultOrdering.direction || '+',
       ordering: defaultOrdering.field,
       orderingOptions: [
         ['creation_date', 'creation_date'],
-        ['accessed_date', 'accessed_date'],
-        ['modification_date', 'modification_date'],
-        ['size', 'size'],
-        ['bitrate', 'bitrate'],
-        ['duration', 'duration']
+        ["name", "name"],
       ]
-
     }
   },
   created () {
@@ -152,13 +140,13 @@ export default {
       let params = _.merge({
         'page': this.page,
         'page_size': this.paginateBy,
-        'q': this.search,
+        'q': this.search.query,
         'ordering': this.getOrderingAsString()
       }, this.filters)
       let self = this
       self.isLoading = true
       self.checked = []
-      axios.get('/manage/library/uploads/', {params: params}).then((response) => {
+      axios.get('/manage/library/artists/', {params: params}).then((response) => {
         self.result = response.data
         self.isLoading = false
       }, error => {
@@ -168,17 +156,17 @@ export default {
     },
     selectPage: function (page) {
       this.page = page
-    }
+    },
   },
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Search by title, artist, domain…')
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by domain, name, MusicBrainz ID…')
       }
     },
     actionFilters () {
       var currentFilters = {
-        q: this.search
+        q: this.search.query
       }
       if (this.filters) {
         return _.merge(currentFilters, this.filters)
@@ -187,13 +175,17 @@ export default {
       }
     },
     actions () {
-      let msg = this.$gettext('Delete')
+      let deleteLabel = this.$pgettext('*/*/*/Verb', 'Delete')
+      let confirmationMessage = this.$pgettext('Popup/*/Paragraph', 'The selected artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible.')
       return [
         {
           name: 'delete',
-          label: msg,
-          isDangerous: true
-        }
+          label: deleteLabel,
+          confirmationMessage: confirmationMessage,
+          isDangerous: true,
+          allowAll: false,
+          confirmColor: 'red',
+        },
       ]
     }
   },
diff --git a/front/src/components/manage/library/EditsCardList.vue b/front/src/components/manage/library/EditsCardList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..28b07f37480b334e5b563e603977bc2a7d5fa245
--- /dev/null
+++ b/front/src/components/manage/library/EditsCardList.vue
@@ -0,0 +1,231 @@
+<template>
+  <div class="ui text container">
+    <slot></slot>
+    <div class="ui inline form">
+      <div class="fields">
+        <div class="ui field">
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
+          <form @submit.prevent="search.query = $refs.search.value">
+            <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
+          </form>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label (Value is All/Pending review/Approved/Rejected)">Status</translate></label>
+          <select class="ui dropdown" @change="addSearchToken('is_approved', $event.target.value)" :value="getTokenValue('is_approved', '')">
+            <option value="">
+              <translate translate-context="Content/*/Dropdown">All</translate>
+            </option>
+            <option value="null">
+              <translate translate-context="Content/Admin/*/Noun">Pending review</translate>
+            </option>
+            <option value="yes">
+              <translate translate-context="Content/*/*/Short">Approved</translate>
+            </option>
+            <option value="no">
+              <translate translate-context="Content/Library/*/Short">Rejected</translate>
+            </option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
+          <select class="ui dropdown" v-model="ordering">
+            <option v-for="option in orderingOptions" :value="option[0]">
+              {{ sharedLabels.filters[option[1]] }}
+            </option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Order</translate></label>
+          <select class="ui dropdown" v-model="orderingDirection">
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
+          </select>
+        </div>
+      </div>
+    </div>
+    <div class="dimmable">
+      <div v-if="isLoading" class="ui active inverted dimmer">
+        <div class="ui loader"></div>
+      </div>
+      <div v-else-if="result && result.count > 0">
+        <edit-card
+          :obj="obj"
+          :current-state="getCurrentState(obj.target)"
+          v-for="obj in result.results"
+          @deleted="handle('delete', obj.uuid, null)"
+          @approved="handle('approved', obj.uuid, $event)"
+          :key="obj.uuid" />
+      </div>
+      <empty-state v-else :refresh="true" @refresh="fetchData()"></empty-state>
+    </div>
+    <div class="ui hidden divider"></div>
+    <div>
+      <pagination
+        v-if="result && result.count > paginateBy"
+        @page-changed="selectPage"
+        :compact="true"
+        :current="page"
+        :paginate-by="paginateBy"
+        :total="result.count"
+        ></pagination>
+
+      <span v-if="result && result.results.length > 0">
+        <translate translate-context="Content/*/Paragraph"
+          :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
+          Showing results %{ start }-%{ end } on %{ total }
+        </translate>
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import _ from '@/lodash'
+import time from '@/utils/time'
+import Pagination from '@/components/Pagination'
+import OrderingMixin from '@/components/mixins/Ordering'
+import TranslationsMixin from '@/components/mixins/Translations'
+import EditCard from '@/components/library/EditCard'
+import {normalizeQuery, parseTokens} from '@/search'
+import SmartSearchMixin from '@/components/mixins/SmartSearch'
+
+import edits from '@/edits'
+
+
+export default {
+  mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
+  props: {
+    filters: {type: Object, required: false}
+  },
+  components: {
+    Pagination,
+    EditCard
+  },
+  data () {
+    let defaultOrdering = this.getOrderingFromString(this.defaultOrdering || '-creation_date')
+    return {
+      time,
+      isLoading: false,
+      result: null,
+      page: 1,
+      paginateBy: 25,
+      search: {
+        query: this.defaultQuery,
+        tokens: parseTokens(normalizeQuery(this.defaultQuery))
+      },
+      orderingDirection: defaultOrdering.direction || '+',
+      ordering: defaultOrdering.field,
+      orderingOptions: [
+        ['creation_date', 'creation_date'],
+        ['applied_date', 'applied_date'],
+      ],
+      targets: {
+        track: {}
+      }
+    }
+  },
+  created () {
+    this.fetchData()
+  },
+  methods: {
+    fetchData () {
+      let params = _.merge({
+        'page': this.page,
+        'page_size': this.paginateBy,
+        'q': this.search.query,
+        'ordering': this.getOrderingAsString()
+      }, this.filters)
+      let self = this
+      self.isLoading = true
+      this.result = null
+      axios.get('mutations/', {params: params}).then((response) => {
+        self.result = response.data
+        self.isLoading = false
+        self.fetchTargets()
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+    fetchTargets () {
+      // we request target data via the API so we can display previous state
+      // additionnal data next to the edit card
+      let self = this
+      let typesAndIds = {
+        track: {
+          url: 'tracks/',
+          ids: [],
+        }
+      }
+      this.result.results.forEach((m) => {
+        if (!m.target || !typesAndIds[m.target.type]) {
+          return
+        }
+        typesAndIds[m.target.type]['ids'].push(m.target.id)
+      })
+      Object.keys(typesAndIds).forEach((k) => {
+        let config = typesAndIds[k]
+        if (config.ids.length === 0) {
+          return
+        }
+        axios.get(config.url, {params: {id: _.uniq(config.ids), hidden: 'null'}}).then((response) => {
+          response.data.results.forEach((e) => {
+            self.$set(self.targets[k], e.id, {
+              payload: e,
+              currentState: edits.getCurrentStateForObj(e, edits.getConfigs.bind(self)()[k])
+            })
+          })
+        }, error => {
+          self.errors = error.backendErrors
+        })
+      })
+    },
+    selectPage: function (page) {
+      this.page = page
+    },
+    handle (type, id, value) {
+      if (type === 'delete') {
+        this.exclude.push(id)
+      }
+
+      this.result.results.forEach((e) => {
+        if (e.uuid === id) {
+          e.is_approved = value
+        }
+      })
+    },
+    getCurrentState (target) {
+      if (!target) {
+        return {}
+      }
+      if (this.targets[target.type] && this.targets[target.type][String(target.id)]) {
+        return this.targets[target.type][String(target.id)].currentState
+      }
+      return {}
+    }
+  },
+  computed: {
+    labels () {
+      return {
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by account, summary, domain…')
+      }
+    },
+  },
+  watch: {
+    search (newValue) {
+      this.page = 1
+      this.fetchData()
+    },
+    page () {
+      this.fetchData()
+    },
+    ordering () {
+      this.fetchData()
+    },
+    orderingDirection () {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/manage/library/LibrariesTable.vue b/front/src/components/manage/library/LibrariesTable.vue
new file mode 100644
index 0000000000000000000000000000000000000000..88c58f3110ff068b9905a81d9bd09deffc1e7bda
--- /dev/null
+++ b/front/src/components/manage/library/LibrariesTable.vue
@@ -0,0 +1,235 @@
+<template>
+  <div>
+    <div class="ui inline form">
+      <div class="fields">
+        <div class="ui six wide field">
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
+          <form @submit.prevent="search.query = $refs.search.value">
+            <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
+          </form>
+        </div>
+        <div class="field">
+          <label><translate translate-context="*/*/*">Visibility</translate></label>
+          <select class="ui dropdown" @change="addSearchToken('privacy_level', $event.target.value)" :value="getTokenValue('privacy_level', '')">
+            <option value=""><translate translate-context="Content/*/Dropdown">All</translate></option>
+            <option value="me">{{ sharedLabels.fields.privacy_level.shortChoices.me }}</option>
+            <option value="instance">{{ sharedLabels.fields.privacy_level.shortChoices.instance }}</option>
+            <option value="everyone">{{ sharedLabels.fields.privacy_level.shortChoices.everyone }}</option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
+          <select class="ui dropdown" v-model="ordering">
+            <option v-for="option in orderingOptions" :value="option[0]">
+              {{ sharedLabels.filters[option[1]] }}
+            </option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
+          <select class="ui dropdown" v-model="orderingDirection">
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
+          </select>
+        </div>
+      </div>
+      </div>
+    <div class="dimmable">
+      <div v-if="isLoading" class="ui active inverted dimmer">
+          <div class="ui loader"></div>
+      </div>
+      <action-table
+        v-if="result"
+        @action-launched="fetchData"
+        :objects-data="result"
+        :actions="actions"
+        action-url="manage/library/libraries/action/"
+        :filters="actionFilters">
+        <template slot="header-cells">
+          <th><translate translate-context="*/*/*">Name</translate></th>
+          <th><translate translate-context="*/*/*">Account</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
+          <th><translate translate-context="*/*/*">Visibility</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Uploads</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Followers</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+        </template>
+        <template slot="row-cells" slot-scope="scope">
+          <td>
+            <router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.uuid }}">{{ scope.obj.name }}</router-link>
+          </td>
+          <td>
+            <router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.actor.full_username }}">
+              <i class="wrench icon"></i>
+            </router-link>
+            <span role="button" class="discrete link" @click="addSearchToken('account', scope.obj.actor.full_username)" :title="scope.obj.actor.full_username">{{ scope.obj.actor.preferred_username }}</span>
+          </td>
+          <td>
+            <template v-if="!scope.obj.is_local">
+              <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
+                <i class="wrench icon"></i>
+              </router-link>
+              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+            </template>
+            <span role="button" v-else class="ui tiny teal icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+              <i class="home icon"></i>
+              <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+            </span>
+          </td>
+          <td>
+            <span
+              role="button"
+              class="discrete link"
+              @click="addSearchToken('privacy_level', scope.obj.privacy_level)"
+              :title="sharedLabels.fields.privacy_level.shortChoices[scope.obj.privacy_level]">
+              {{ sharedLabels.fields.privacy_level.shortChoices[scope.obj.privacy_level] }}
+            </span>
+          </td>
+          <td>
+            {{ scope.obj.uploads_count }}
+          </td>
+          <td>
+            {{ scope.obj.followers_count }}
+          </td>
+          <td>
+            <human-date :date="scope.obj.creation_date"></human-date>
+          </td>
+        </template>
+      </action-table>
+    </div>
+    <div>
+      <pagination
+        v-if="result && result.count > paginateBy"
+        @page-changed="selectPage"
+        :compact="true"
+        :current="page"
+        :paginate-by="paginateBy"
+        :total="result.count"
+        ></pagination>
+
+      <span v-if="result && result.results.length > 0">
+        <translate translate-context="Content/*/Paragraph"
+          :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
+          Showing results %{ start }-%{ end } on %{ total }
+        </translate>
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import _ from '@/lodash'
+import time from '@/utils/time'
+import {normalizeQuery, parseTokens} from '@/search'
+import Pagination from '@/components/Pagination'
+import ActionTable from '@/components/common/ActionTable'
+import OrderingMixin from '@/components/mixins/Ordering'
+import TranslationsMixin from '@/components/mixins/Translations'
+import SmartSearchMixin from '@/components/mixins/SmartSearch'
+
+
+export default {
+  mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
+  props: {
+    filters: {type: Object, required: false},
+  },
+  components: {
+    Pagination,
+    ActionTable
+  },
+  data () {
+    let defaultOrdering = this.getOrderingFromString(this.defaultOrdering || '-creation_date')
+    return {
+      time,
+      isLoading: false,
+      result: null,
+      page: 1,
+      paginateBy: 50,
+      search: {
+        query: this.defaultQuery,
+        tokens: parseTokens(normalizeQuery(this.defaultQuery))
+      },
+      orderingDirection: defaultOrdering.direction || '+',
+      ordering: defaultOrdering.field,
+      orderingOptions: [
+        ['creation_date', 'creation_date'],
+        ['followers_count', 'followers'],
+        ['uploads_count', 'uploads'],
+      ]
+    }
+  },
+  created () {
+    this.fetchData()
+  },
+  methods: {
+    fetchData () {
+      let params = _.merge({
+        'page': this.page,
+        'page_size': this.paginateBy,
+        'q': this.search.query,
+        'ordering': this.getOrderingAsString()
+      }, this.filters)
+      let self = this
+      self.isLoading = true
+      self.checked = []
+      axios.get('/manage/library/libraries/', {params: params}).then((response) => {
+        self.result = response.data
+        self.isLoading = false
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+    selectPage: function (page) {
+      this.page = page
+    },
+  },
+  computed: {
+    labels () {
+      return {
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by domain, actor, name, description…')
+      }
+    },
+    actionFilters () {
+      var currentFilters = {
+        q: this.search.query
+      }
+      if (this.filters) {
+        return _.merge(currentFilters, this.filters)
+      } else {
+        return currentFilters
+      }
+    },
+    actions () {
+      let deleteLabel = this.$pgettext('*/*/*/Verb', 'Delete')
+      let confirmationMessage = this.$pgettext('Popup/*/Paragraph', 'The selected library will be removed, as well as associated uploads and follows. This action is irreversible.')
+      return [
+        {
+          name: 'delete',
+          label: deleteLabel,
+          confirmationMessage: confirmationMessage,
+          isDangerous: true,
+          allowAll: false,
+          confirmColor: 'red',
+        },
+      ]
+    }
+  },
+  watch: {
+    search (newValue) {
+      this.page = 1
+      this.fetchData()
+    },
+    page () {
+      this.fetchData()
+    },
+    ordering () {
+      this.fetchData()
+    },
+    orderingDirection () {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/manage/library/TracksTable.vue b/front/src/components/manage/library/TracksTable.vue
new file mode 100644
index 0000000000000000000000000000000000000000..a702d8e25cb180827e1134aad530f99936bd7675
--- /dev/null
+++ b/front/src/components/manage/library/TracksTable.vue
@@ -0,0 +1,218 @@
+<template>
+  <div>
+    <div class="ui inline form">
+      <div class="fields">
+        <div class="ui six wide field">
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
+          <form @submit.prevent="search.query = $refs.search.value">
+            <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
+          </form>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
+          <select class="ui dropdown" v-model="ordering">
+            <option v-for="option in orderingOptions" :value="option[0]">
+              {{ sharedLabels.filters[option[1]] }}
+            </option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
+          <select class="ui dropdown" v-model="orderingDirection">
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
+          </select>
+        </div>
+      </div>
+      </div>
+    <div class="dimmable">
+      <div v-if="isLoading" class="ui active inverted dimmer">
+          <div class="ui loader"></div>
+      </div>
+      <action-table
+        v-if="result"
+        @action-launched="fetchData"
+        :objects-data="result"
+        :actions="actions"
+        action-url="manage/library/tracks/action/"
+        :filters="actionFilters">
+        <template slot="header-cells">
+          <th><translate translate-context="*/*/*">Title</translate></th>
+          <th><translate translate-context="*/*/*">Album</translate></th>
+          <th><translate translate-context="*/*/*">Artist</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">License</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+        </template>
+        <template slot="row-cells" slot-scope="scope">
+          <td>
+            <router-link :to="{name: 'manage.library.tracks.detail', params: {id: scope.obj.id }}">{{ scope.obj.title }}</router-link>
+          </td>
+          <td>
+            <router-link :to="{name: 'manage.library.albums.detail', params: {id: scope.obj.album.id }}">
+              <i class="wrench icon"></i>
+            </router-link>
+            <span role="button" class="discrete link" @click="addSearchToken('album_id', scope.obj.album.id)" :title="scope.obj.album.title">{{ scope.obj.album.title }}</span>
+          </td>
+          <td>
+            <router-link :to="{name: 'manage.library.artists.detail', params: {id: scope.obj.artist.id }}">
+              <i class="wrench icon"></i>
+            </router-link>
+            <span role="button" class="discrete link" @click="addSearchToken('artist_id', scope.obj.artist.id)" :title="scope.obj.artist.name">{{ scope.obj.artist.name }}</span>
+          </td>
+          <td>
+            <template v-if="!scope.obj.is_local">
+              <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
+                <i class="wrench icon"></i>
+              </router-link>
+              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+            </template>
+            <span role="button" v-else class="ui tiny teal icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+              <i class="home icon"></i>
+              <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+            </span>
+          </td>
+          <td>
+            <span role="button" v-if="scope.obj.license" class="discrete link" @click="addSearchToken('license', scope.obj.license)" :title="scope.obj.license">{{ scope.obj.license }}</span>
+            <translate v-else translate-context="*/*/*">N/A</translate>
+          </td>
+          <td>
+            <human-date :date="scope.obj.creation_date"></human-date>
+          </td>
+        </template>
+      </action-table>
+    </div>
+    <div>
+      <pagination
+        v-if="result && result.count > paginateBy"
+        @page-changed="selectPage"
+        :compact="true"
+        :current="page"
+        :paginate-by="paginateBy"
+        :total="result.count"
+        ></pagination>
+
+      <span v-if="result && result.results.length > 0">
+        <translate translate-context="Content/*/Paragraph"
+          :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
+          Showing results %{ start }-%{ end } on %{ total }
+        </translate>
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import _ from '@/lodash'
+import time from '@/utils/time'
+import {normalizeQuery, parseTokens} from '@/search'
+import Pagination from '@/components/Pagination'
+import ActionTable from '@/components/common/ActionTable'
+import OrderingMixin from '@/components/mixins/Ordering'
+import TranslationsMixin from '@/components/mixins/Translations'
+import SmartSearchMixin from '@/components/mixins/SmartSearch'
+
+
+export default {
+  mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
+  props: {
+    filters: {type: Object, required: false},
+  },
+  components: {
+    Pagination,
+    ActionTable
+  },
+  data () {
+    let defaultOrdering = this.getOrderingFromString(this.defaultOrdering || '-creation_date')
+    return {
+      time,
+      isLoading: false,
+      result: null,
+      page: 1,
+      paginateBy: 50,
+      search: {
+        query: this.defaultQuery,
+        tokens: parseTokens(normalizeQuery(this.defaultQuery))
+      },
+      orderingDirection: defaultOrdering.direction || '+',
+      ordering: defaultOrdering.field,
+      orderingOptions: [
+        ['creation_date', 'creation_date'],
+      ]
+    }
+  },
+  created () {
+    this.fetchData()
+  },
+  methods: {
+    fetchData () {
+      let params = _.merge({
+        'page': this.page,
+        'page_size': this.paginateBy,
+        'q': this.search.query,
+        'ordering': this.getOrderingAsString()
+      }, this.filters)
+      let self = this
+      self.isLoading = true
+      self.checked = []
+      axios.get('/manage/library/tracks/', {params: params}).then((response) => {
+        self.result = response.data
+        self.isLoading = false
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+    selectPage: function (page) {
+      this.page = page
+    },
+  },
+  computed: {
+    labels () {
+      return {
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by domain, title, artist, album, MusicBrainz ID…')
+      }
+    },
+    actionFilters () {
+      var currentFilters = {
+        q: this.search.query
+      }
+      if (this.filters) {
+        return _.merge(currentFilters, this.filters)
+      } else {
+        return currentFilters
+      }
+    },
+    actions () {
+      let deleteLabel = this.$pgettext('*/*/*/Verb', 'Delete')
+      let confirmationMessage = this.$pgettext('Popup/*/Paragraph', 'The selected tracks will be removed, as well as associated uploads, favorites and listening history. This action is irreversible.')
+      return [
+        {
+          name: 'delete',
+          label: deleteLabel,
+          confirmationMessage: confirmationMessage,
+          isDangerous: true,
+          allowAll: false,
+          confirmColor: 'red',
+        },
+      ]
+    }
+  },
+  watch: {
+    search (newValue) {
+      this.page = 1
+      this.fetchData()
+    },
+    page () {
+      this.fetchData()
+    },
+    ordering () {
+      this.fetchData()
+    },
+    orderingDirection () {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/manage/library/UploadsTable.vue b/front/src/components/manage/library/UploadsTable.vue
new file mode 100644
index 0000000000000000000000000000000000000000..efc4e23944387bf84ae8330452a561d341e90dfe
--- /dev/null
+++ b/front/src/components/manage/library/UploadsTable.vue
@@ -0,0 +1,285 @@
+<template>
+  <div>
+    <div class="ui inline form">
+      <div class="fields">
+        <div class="ui six wide field">
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
+          <form @submit.prevent="search.query = $refs.search.value">
+            <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
+          </form>
+        </div>
+        <div class="field">
+          <label><translate translate-context="*/*/*">Visibility</translate></label>
+          <select class="ui dropdown" @change="addSearchToken('privacy_level', $event.target.value)" :value="getTokenValue('privacy_level', '')">
+            <option value=""><translate translate-context="Content/*/Dropdown">All</translate></option>
+            <option value="me">{{ sharedLabels.fields.privacy_level.shortChoices.me }}</option>
+            <option value="instance">{{ sharedLabels.fields.privacy_level.shortChoices.instance }}</option>
+            <option value="everyone">{{ sharedLabels.fields.privacy_level.shortChoices.everyone }}</option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Library/*/Noun">Import status</translate></label>
+          <select class="ui dropdown" @change="addSearchToken('status', $event.target.value)" :value="getTokenValue('status', '')">
+            <option value=""><translate translate-context="Content/*/Dropdown">All</translate></option>
+            <option value="pending"><translate translate-context="Content/Library/*/Short">Pending</translate></option>
+            <option value="skipped"><translate translate-context="Content/Library/*">Skipped</translate></option>
+            <option value="errored"><translate translate-context="Content/Library/Dropdown">Failed</translate></option>
+            <option value="finished"><translate translate-context="Content/Library/*">Finished</translate></option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
+          <select class="ui dropdown" v-model="ordering">
+            <option v-for="option in orderingOptions" :value="option[0]">
+              {{ sharedLabels.filters[option[1]] }}
+            </option>
+          </select>
+        </div>
+        <div class="field">
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
+          <select class="ui dropdown" v-model="orderingDirection">
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
+          </select>
+        </div>
+      </div>
+    </div>
+    <import-status-modal :upload="detailedUpload" :show.sync="showUploadDetailModal" />
+    <div class="dimmable">
+      <div v-if="isLoading" class="ui active inverted dimmer">
+          <div class="ui loader"></div>
+      </div>
+      <action-table
+        v-if="result"
+        @action-launched="fetchData"
+        :objects-data="result"
+        :actions="actions"
+        action-url="manage/library/uploads/action/"
+        :filters="actionFilters">
+        <template slot="header-cells">
+          <th><translate translate-context="*/*/*">Name</translate></th>
+          <th><translate translate-context="*/*/*">Library</translate></th>
+          <th><translate translate-context="*/*/*">Account</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
+          <th><translate translate-context="*/*/*">Visibility</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Import status</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Size</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Accessed date</translate></th>
+        </template>
+        <template slot="row-cells" slot-scope="scope">
+          <td>
+            <router-link :to="{name: 'manage.library.uploads.detail', params: {id: scope.obj.uuid }}" :title="displayName(scope.obj)">
+              {{ displayName(scope.obj)|truncate(30, "…", true) }}
+            </router-link>
+          </td>
+          <td>
+            <router-link :to="{name: 'manage.library.libraries.detail', params: {id: scope.obj.library.uuid }}">
+              <i class="wrench icon"></i>
+            </router-link>
+            <span role="button" class="discrete link"
+              @click="addSearchToken('library_id', scope.obj.library.id)"
+              :title="scope.obj.library.name">
+              {{ scope.obj.library.name | truncate(20) }}
+            </span>
+          </td>
+          <td>
+            <router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: scope.obj.library.actor.full_username }}">
+            </router-link>
+            <span role="button" class="discrete link" @click="addSearchToken('account', scope.obj.library.actor.full_username)" :title="scope.obj.library.actor.full_username">{{ scope.obj.library.actor.preferred_username }}</span>
+          </td>
+          <td>
+            <template v-if="!scope.obj.is_local">
+              <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: scope.obj.domain }}">
+                <i class="wrench icon"></i>
+              </router-link>
+              <span role="button" class="discrete link" @click="addSearchToken('domain', scope.obj.domain)" :title="scope.obj.domain">{{ scope.obj.domain }}</span>
+            </template>
+            <span role="button" v-else class="ui tiny teal icon link label" @click="addSearchToken('domain', scope.obj.domain)">
+              <i class="home icon"></i>
+              <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+            </span>
+          </td>
+          <td>
+            <span
+              role="button"
+              class="discrete link"
+              @click="addSearchToken('privacy_level', scope.obj.library.privacy_level)"
+              :title="sharedLabels.fields.privacy_level.shortChoices[scope.obj.library.privacy_level]">
+              {{ sharedLabels.fields.privacy_level.shortChoices[scope.obj.library.privacy_level] }}
+            </span>
+          </td>
+          <td>
+            <span class="discrete link" @click="addSearchToken('status', scope.obj.import_status)" :title="sharedLabels.fields.import_status.choices[scope.obj.import_status].help">
+              {{ sharedLabels.fields.import_status.choices[scope.obj.import_status].label }}
+            </span>
+            <button class="ui tiny basic icon button" :title="sharedLabels.fields.import_status.detailTitle" @click="detailedUpload = scope.obj; showUploadDetailModal = true">
+              <i class="question circle outline icon"></i>
+            </button>
+          </td>
+          <td>
+            <span v-if="scope.obj.size">{{ scope.obj.size | humanSize }}</span>
+            <translate v-else translate-context="*/*/*">N/A</translate>
+          </td>
+          <td>
+            <human-date :date="scope.obj.creation_date"></human-date>
+          </td>
+          <td>
+            <human-date v-if="scope.obj.accessed_date" :date="scope.obj.accessed_date"></human-date>
+            <translate v-else translate-context="*/*/*">N/A</translate>
+          </td>
+        </template>
+      </action-table>
+    </div>
+    <div>
+      <pagination
+        v-if="result && result.count > paginateBy"
+        @page-changed="selectPage"
+        :compact="true"
+        :current="page"
+        :paginate-by="paginateBy"
+        :total="result.count"
+        ></pagination>
+
+      <span v-if="result && result.results.length > 0">
+        <translate translate-context="Content/*/Paragraph"
+          :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
+          Showing results %{ start }-%{ end } on %{ total }
+        </translate>
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from 'axios'
+import _ from '@/lodash'
+import time from '@/utils/time'
+import {normalizeQuery, parseTokens} from '@/search'
+import Pagination from '@/components/Pagination'
+import ActionTable from '@/components/common/ActionTable'
+import OrderingMixin from '@/components/mixins/Ordering'
+import TranslationsMixin from '@/components/mixins/Translations'
+import SmartSearchMixin from '@/components/mixins/SmartSearch'
+import ImportStatusModal from '@/components/library/ImportStatusModal'
+
+
+export default {
+  mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
+  props: {
+    filters: {type: Object, required: false},
+  },
+  components: {
+    Pagination,
+    ActionTable,
+    ImportStatusModal
+  },
+  data () {
+    let defaultOrdering = this.getOrderingFromString(this.defaultOrdering || '-creation_date')
+    return {
+      detailedUpload: null,
+      showUploadDetailModal: false,
+      time,
+      isLoading: false,
+      result: null,
+      page: 1,
+      paginateBy: 50,
+      search: {
+        query: this.defaultQuery,
+        tokens: parseTokens(normalizeQuery(this.defaultQuery))
+      },
+      orderingDirection: defaultOrdering.direction || '+',
+      ordering: defaultOrdering.field,
+      orderingOptions: [
+        ['creation_date', 'creation_date'],
+        ['modification_date', 'modification_date'],
+        ['accessed_date', 'accessed_date'],
+        ['size', 'size'],
+        ['bitrate', 'bitrate'],
+        ['duration', 'duration'],
+      ]
+    }
+  },
+  created () {
+    this.fetchData()
+  },
+  methods: {
+    fetchData () {
+      let params = _.merge({
+        'page': this.page,
+        'page_size': this.paginateBy,
+        'q': this.search.query,
+        'ordering': this.getOrderingAsString()
+      }, this.filters)
+      let self = this
+      self.isLoading = true
+      self.checked = []
+      axios.get('/manage/library/uploads/', {params: params}).then((response) => {
+        self.result = response.data
+        self.isLoading = false
+      }, error => {
+        self.isLoading = false
+        self.errors = error.backendErrors
+      })
+    },
+    selectPage: function (page) {
+      this.page = page
+    },
+    displayName (upload) {
+      if (upload.filename) {
+        return upload.filename
+      }
+      if (upload.source) {
+        return upload.source
+      }
+      return upload.uuid
+    }
+  },
+  computed: {
+    labels () {
+      return {
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by domain, actor, name, reference, source…')
+      }
+    },
+    actionFilters () {
+      var currentFilters = {
+        q: this.search.query
+      }
+      if (this.filters) {
+        return _.merge(currentFilters, this.filters)
+      } else {
+        return currentFilters
+      }
+    },
+    actions () {
+      let deleteLabel = this.$pgettext('*/*/*/Verb', 'Delete')
+      let confirmationMessage = this.$pgettext('Popup/*/Paragraph', 'The selected upload will be removed. This action is irreversible.')
+      return [
+        {
+          name: 'delete',
+          label: deleteLabel,
+          confirmationMessage: confirmationMessage,
+          isDangerous: true,
+          allowAll: false,
+          confirmColor: 'red',
+        },
+      ]
+    }
+  },
+  watch: {
+    search (newValue) {
+      this.page = 1
+      this.fetchData()
+    },
+    page () {
+      this.fetchData()
+    },
+    ordering () {
+      this.fetchData()
+    },
+    orderingDirection () {
+      this.fetchData()
+    }
+  }
+}
+</script>
diff --git a/front/src/components/manage/moderation/AccountsTable.vue b/front/src/components/manage/moderation/AccountsTable.vue
index 8259e8ec8b0b0fc170424236daaa6674b07519d1..ce91fe43e32df84913066f594442b8adbfdac07e 100644
--- a/front/src/components/manage/moderation/AccountsTable.vue
+++ b/front/src/components/manage/moderation/AccountsTable.vue
@@ -3,13 +3,13 @@
     <div class="ui inline form">
       <div class="fields">
         <div class="ui six wide field">
-          <label><translate>Search</translate></label>
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
           <form @submit.prevent="search.query = $refs.search.value">
             <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
           </form>
         </div>
         <div class="field">
-          <label><translate>Ordering</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
           <select class="ui dropdown" v-model="ordering">
             <option v-for="option in orderingOptions" :value="option[0]">
               {{ sharedLabels.filters[option[1]] }}
@@ -17,10 +17,10 @@
           </select>
         </div>
         <div class="field">
-          <label><translate>Ordering direction</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
           <select class="ui dropdown" v-model="orderingDirection">
-            <option value="+"><translate>Ascending</translate></option>
-            <option value="-"><translate>Descending</translate></option>
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
           </select>
         </div>
       </div>
@@ -37,12 +37,12 @@
         action-url="manage/accounts/action/"
         :filters="actionFilters">
         <template slot="header-cells">
-          <th><translate>Name</translate></th>
-          <th><translate>Domain</translate></th>
-          <th><translate>Uploads</translate></th>
-          <th><translate>First seen</translate></th>
-          <th><translate>Last seen</translate></th>
-          <th><translate>Under moderation rule</translate></th>
+          <th><translate translate-context="*/*/*/Noun">Name</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Domain</translate></th>
+          <th><translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate></th>
+          <th><translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate></th>
+          <th><translate translate-context="Content/Moderation/Table.Label/Noun">Last seen</translate></th>
+          <th><translate translate-context="Content/Moderation/Table.Label/Short">Under moderation rule</translate></th>
         </template>
         <template slot="row-cells" slot-scope="scope">
           <td>
@@ -57,7 +57,7 @@
             </template>
             <span role="button" v-else class="ui tiny teal icon link label" @click="addSearchToken('domain', scope.obj.domain)">
               <i class="home icon"></i>
-              <translate>Local account</translate>
+              <translate translate-context="Content/Moderation/*/Short, Noun">Local account</translate>
             </span>
           </td>
           <td>
@@ -70,7 +70,7 @@
             <human-date v-if="scope.obj.last_fetch_date" :date="scope.obj.last_fetch_date"></human-date>
           </td>
           <td>
-            <span v-if="scope.obj.instance_policy"><i class="shield icon"></i> <translate>Yes</translate></span>
+            <span v-if="scope.obj.instance_policy"><i class="shield icon"></i> <translate translate-context="*/*/*">Yes</translate></span>
           </td>
         </template>
       </action-table>
@@ -86,7 +86,7 @@
         ></pagination>
 
       <span v-if="result && result.results.length > 0">
-        <translate
+        <translate translate-context="Content/*/Paragraph"
           :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
           Showing results %{ start }-%{ end } on %{ total }
         </translate>
@@ -168,7 +168,7 @@ export default {
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Search by domain, username, bio…')
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by domain, username, bio…')
       }
     },
     actionFilters () {
@@ -185,7 +185,7 @@ export default {
       return [
         {
           name: 'purge',
-          label: this.$gettext('Purge'),
+          label: this.$pgettext('*/*/*/Verb', 'Purge'),
           isDangerous: true
         }
       ]
diff --git a/front/src/components/manage/moderation/DomainsTable.vue b/front/src/components/manage/moderation/DomainsTable.vue
index ed9eb5be8066755fc316ba12ce69c3d3dbca8fda..544d91156f3101236b8395bec133b9248d2d112a 100644
--- a/front/src/components/manage/moderation/DomainsTable.vue
+++ b/front/src/components/manage/moderation/DomainsTable.vue
@@ -3,11 +3,11 @@
     <div class="ui inline form">
       <div class="fields">
         <div class="ui field">
-          <label><translate>Search</translate></label>
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
           <input name="search" type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
         </div>
         <div class="field">
-          <label><translate>Ordering</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
           <select class="ui dropdown" v-model="ordering">
             <option v-for="option in orderingOptions" :value="option[0]">
               {{ sharedLabels.filters[option[1]] }}
@@ -15,10 +15,10 @@
           </select>
         </div>
         <div class="field">
-          <label><translate>Ordering direction</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
           <select class="ui dropdown" v-model="orderingDirection">
-            <option value="+"><translate>Ascending</translate></option>
-            <option value="-"><translate>Descending</translate></option>
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
           </select>
         </div>
       </div>
@@ -36,11 +36,11 @@
         idField="name"
         :filters="actionFilters">
         <template slot="header-cells">
-          <th><translate>Name</translate></th>
-          <th><translate>Users</translate></th>
-          <th><translate>Received messages</translate></th>
-          <th><translate>First seen</translate></th>
-          <th><translate>Under moderation rule</translate></th>
+          <th><translate translate-context="*/*/*/Noun">Name</translate></th>
+          <th><translate translate-context="*/*/*/Noun">Users</translate></th>
+          <th><translate translate-context="Content/Moderation/*/Noun">Received messages</translate></th>
+          <th><translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate></th>
+          <th><translate translate-context="Content/Moderation/Table.Label/Short">Under moderation rule</translate></th>
         </template>
         <template slot="row-cells" slot-scope="scope">
           <td>
@@ -56,7 +56,7 @@
             <human-date :date="scope.obj.creation_date"></human-date>
           </td>
           <td>
-            <span v-if="scope.obj.instance_policy"><i class="shield icon"></i> <translate>Yes</translate></span>
+            <span v-if="scope.obj.instance_policy"><i class="shield icon"></i> <translate translate-context="*/*/*">Yes</translate></span>
           </td>
         </template>
       </action-table>
@@ -72,7 +72,7 @@
         ></pagination>
 
       <span v-if="result && result.results.length > 0">
-        <translate
+        <translate translate-context="Content/*/Paragraph"
           :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
           Showing results %{ start }-%{ end } on %{ total }
         </translate>
@@ -148,7 +148,7 @@ export default {
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Search by name…')
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by name…')
       }
     },
     actionFilters () {
@@ -165,7 +165,7 @@ export default {
       return [
         {
           name: 'purge',
-          label: this.$gettext('Purge'),
+          label: this.$pgettext('*/*/*/Verb', 'Purge'),
           isDangerous: true
         }
       ]
diff --git a/front/src/components/manage/moderation/InstancePolicyCard.vue b/front/src/components/manage/moderation/InstancePolicyCard.vue
index b72c6bac8dfea889b60cc7a19d3c44650c467011..040195d0975f259a4a613d329284d1c95e84e9b4 100644
--- a/front/src/components/manage/moderation/InstancePolicyCard.vue
+++ b/front/src/components/manage/moderation/InstancePolicyCard.vue
@@ -6,44 +6,44 @@
       <i class="user icon"></i>{{ object.actor }}  &nbsp;
       <template v-if="object.is_active">
         <i class="play icon"></i>
-        <translate>Enabled</translate>
+        <translate translate-context="*/*/*">Enabled</translate>
       </template>
       <template v-if="!object.is_active">
         <i class="pause icon"></i>
-        <translate>Paused</translate>
+        <translate translate-context="Content/Moderation/Card.List item">Paused</translate>
       </template>
     </p>
     <div>
-      <p><strong><translate>Rule</translate></strong></p>
+      <p><strong><translate translate-context="Content/Moderation/Card.Title/Noun">Rule</translate></strong></p>
       <p v-if="object.block_all">
         <i class="ban icon"></i>
-        <translate>Block everything</translate>
+        <translate translate-context="Content/Moderation/*/Verb">Block everything</translate>
       </p>
       <div v-else class="ui list">
         <div class="ui item" v-if="object.silence_activity">
           <i class="feed icon"></i>
-          <div class="content"><translate>Mute activity</translate></div>
+          <div class="content"><translate translate-context="Content/Moderation/*/Verb">Mute activity</translate></div>
         </div>
         <div class="ui item" v-if="object.silence_notifications">
           <i class="bell icon"></i>
-          <div class="content"><translate>Mute notifications</translate></div>
+          <div class="content"><translate translate-context="Content/Moderation/*/Verb">Mute notifications</translate></div>
         </div>
         <div class="ui item" v-if="object.reject_media">
           <i class="file icon"></i>
-          <div class="content"><translate>Reject media</translate></div>
+          <div class="content"><translate translate-context="Content/Moderation/*/Verb">Reject media</translate></div>
         </div>
 
       </div>
     </div>
     <div v-if="markdown && object.summary">
       <div class="ui hidden divider"></div>
-      <p><strong><translate>Reason</translate></strong></p>
+      <p><strong><translate translate-context="Content/Moderation/*/Noun">Reason</translate></strong></p>
       <div v-html="markdown.makeHtml(object.summary)"></div>
     </div>
     <div class="ui hidden divider"></div>
     <button @click="$emit('update')" class="ui right floated labeled icon button">
       <i class="edit icon"></i>
-      <translate>Update</translate>
+      <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
     </button>
   </div>
 </template>
diff --git a/front/src/components/manage/moderation/InstancePolicyForm.vue b/front/src/components/manage/moderation/InstancePolicyForm.vue
index a31f162b9d4d0291fd2da2a0a9b9aa0cc29a45a2..b38a2a9a586f22038ea5de6b42ced404067e1526 100644
--- a/front/src/components/manage/moderation/InstancePolicyForm.vue
+++ b/front/src/components/manage/moderation/InstancePolicyForm.vue
@@ -1,11 +1,11 @@
 <template>
   <form class="ui form" @submit.prevent="createOrUpdate">
     <h3 class="ui header">
-      <translate v-if="object" key="1">Update moderation rule</translate>
-      <translate v-else key="2">Add a new moderation rule</translate>
+      <translate translate-context="Content/Moderation/Card.Title/Verb" v-if="object" key="1">Edit moderation rule</translate>
+      <translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-else key="2">Add a new moderation rule</translate>
     </h3>
     <div v-if="errors && errors.length > 0" class="ui negative message">
-      <div class="header"><translate>Error while creating rule</translate></div>
+      <div class="header"><translate translate-context="Content/Moderation/Error message.Title">Error while creating rule</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
@@ -15,15 +15,15 @@
       <div class="ui toggle checkbox">
         <input id="policy-is-active" v-model="current.isActive" type="checkbox">
         <label for="policy-is-active">
-          <translate v-if="current.isActive" key="1">Enabled</translate>
-          <translate v-else key="2">Disabled</translate>
+          <translate translate-context="*/*/*" v-if="current.isActive" key="1">Enabled</translate>
+          <translate translate-context="*/*/*" v-else key="2">Disabled</translate>
           <tooltip :content="labels.isActiveHelp" />
         </label>
       </div>
     </div>
     <div class="field">
       <label for="policy-summary">
-        <translate>Reason</translate>
+        <translate translate-context="Content/Moderation/*/Noun">Reason</translate>
         <tooltip :content="labels.summaryHelp" />
       </label>
       <textarea name="policy-summary" id="policy-summary" rows="5" v-model="current.summary"></textarea>
@@ -32,13 +32,13 @@
       <div class="ui toggle checkbox">
         <input id="policy-is-active" v-model="current.blockAll" type="checkbox">
         <label for="policy-is-active">
-          <translate>Block everything</translate>
+          <translate translate-context="Content/Moderation/*/Verb">Block everything</translate>
           <tooltip :content="labels.blockAllHelp" />
         </label>
       </div>
     </div>
     <div class="ui horizontal divider">
-      <translate>Or customize your rule</translate>
+      <translate translate-context="Content/Moderation/Card.Title">Or customize your rule</translate>
     </div>
     <div v-for="config in fieldConfig" :class="['field']">
       <div class="ui toggle checkbox">
@@ -52,30 +52,30 @@
     </div>
     <div class="ui hidden divider"></div>
     <button @click.prevent="$emit('cancel')" class="ui basic left floated button">
-      <translate>Cancel</translate>
+      <translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
     </button>
     <button :class="['ui', 'right', 'floated', 'green', {'disabled loading': isLoading}, 'button']" :disabled="isLoading">
-      <translate v-if="object" key="1">Update</translate>
-      <translate v-else key="2">Create</translate>
+      <translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-if="object" key="1">Update</translate>
+      <translate translate-context="Content/Moderation/Card.Button.Label/Verb" v-else key="2">Create</translate>
     </button>
     <dangerous-button v-if="object" class="right floated basic button" color='red' @confirm="remove">
-      <translate>Delete</translate>
+      <translate translate-context="*/*/*/Verb">Delete</translate>
       <p slot="modal-header">
-        <translate>Delete this moderation rule?</translate>
+        <translate translate-context="Popup/Moderation/Title">Delete this moderation rule?</translate>
       </p>
       <p slot="modal-content">
-        <translate>This action is irreversible.</translate>
-      </p>
-      <p slot="modal-confirm">
-        <translate>Delete moderation rule</translate>
+        <translate translate-context="Popup/Moderation/Paragraph">This action is irreversible.</translate>
       </p>
+      <div slot="modal-confirm">
+        <translate translate-context="Popup/Moderation/Button.Label/Verb">Delete moderation rule</translate>
+      </div>
     </dangerous-button>
   </form>
 </template>
 
 <script>
 import axios from 'axios'
-import _ from 'lodash'
+import _ from '@/lodash'
 
 export default {
   props: {
@@ -107,20 +107,20 @@ export default {
   computed: {
     labels () {
       return {
-        summaryHelp: this.$gettext("Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."),
-        isActiveHelp: this.$gettext("Use this setting to temporarily enable/disable the policy without completely removing it."),
-        blockAllHelp: this.$gettext("Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"),
+        summaryHelp: this.$pgettext('Content/Moderation/Help text', "Explain why you're applying this policy. Depending on your instance configuration, this will help you remember why you acted on this account or domain, and may be displayed publicly to help users understand what moderation rules are in place."),
+        isActiveHelp: this.$pgettext('Content/Moderation/Help text', "Use this setting to temporarily enable/disable the policy without completely removing it."),
+        blockAllHelp: this.$pgettext('Content/Moderation/Help text', "Block everything from this account or domain. This will prevent any interaction with the entity, and purge related content (uploads, libraries, follows, etc.)"),
         silenceActivity: {
-          help: this.$gettext("Hide account or domain content, except from followers."),
-          label: this.$gettext("Mute activity"),
+          help: this.$pgettext('Content/Moderation/Help text', "Hide account or domain content, except from followers."),
+          label: this.$pgettext('Content/Moderation/*/Verb', "Mute activity"),
         },
         silenceNotifications: {
-          help: this.$gettext("Prevent account or domain from triggering notifications, except from followers."),
-          label: this.$gettext("Silence notifications"),
+          help: this.$pgettext('Content/Moderation/Help text', "Prevent account or domain from triggering notifications, except from followers."),
+          label: this.$pgettext('Content/Moderation/*/Verb', "Mute notifications"),
         },
         rejectMedia: {
-          help: this.$gettext("Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."),
-          label: this.$gettext("Reject media"),
+          help: this.$pgettext('Content/Moderation/Help text', "Do not download any media file (audio, album cover, account avatar…) from this account or domain. This will purge existing content as well."),
+          label: this.$pgettext('Content/Moderation/*/Verb', "Reject media"),
         }
       }
     }
diff --git a/front/src/components/manage/users/InvitationForm.vue b/front/src/components/manage/users/InvitationForm.vue
index 02cfba5a949734d7dd0c5f88dd54a58a10fe5f55..950e11e08e72c6f5dedbabd72a071b1cdc8f4b0f 100644
--- a/front/src/components/manage/users/InvitationForm.vue
+++ b/front/src/components/manage/users/InvitationForm.vue
@@ -2,19 +2,19 @@
   <div>
     <form class="ui form" @submit.prevent="submit">
       <div v-if="errors.length > 0" class="ui negative message">
-        <div class="header"><translate>Error while creating invitation</translate></div>
+        <div class="header"><translate translate-context="Content/Admin/Error message.Title">Error while creating invitation</translate></div>
         <ul class="list">
           <li v-for="error in errors">{{ error }}</li>
         </ul>
       </div>
       <div class="inline fields">
         <div class="ui field">
-          <label><translate>Invitation code</translate></label>
+          <label><translate translate-context="Content/*/Input.Label">Invitation code</translate></label>
           <input name="code" type="text" v-model="code" :placeholder="labels.placeholder" />
         </div>
         <div class="ui field">
           <button :class="['ui', {loading: isLoading}, 'button']" :disabled="isLoading" type="submit">
-            <translate>Get a new invitation</translate>
+            <translate translate-context="Content/Admin/Button.Label/Verb">Get a new invitation</translate>
           </button>
         </div>
       </div>
@@ -24,8 +24,8 @@
       <table class="ui ui basic table">
         <thead>
           <tr>
-            <th><translate>Code</translate></th>
-            <th><translate>Share link</translate></th>
+            <th><translate translate-context="Content/Admin/Table.Label/Noun">Code</translate></th>
+            <th><translate translate-context="Content/Admin/Table.Label/Noun">Share link</translate></th>
           </tr>
         </thead>
         <tbody>
@@ -35,7 +35,7 @@
           </tr>
         </tbody>
       </table>
-      <button class="ui basic button" @click="invitations = []"><translate>Clear</translate></button>
+      <button class="ui basic button" @click="invitations = []"><translate translate-context="Content/Admin/Button.Label/Verb">Clear</translate></button>
     </div>
   </div>
 </template>
@@ -55,7 +55,7 @@ export default {
   computed: {
     labels () {
       return {
-        placeholder: this.$gettext('Leave empty for a random code')
+        placeholder: this.$pgettext('Content/Admin/Input.Placeholder', 'Leave empty for a random code')
       }
     }
   },
diff --git a/front/src/components/manage/users/InvitationsTable.vue b/front/src/components/manage/users/InvitationsTable.vue
index ee9eb503501cee9541c6c9bf2d32cdaf1625ec10..6f557c8af2c879a64613f5dff68dbd0fbffd5159 100644
--- a/front/src/components/manage/users/InvitationsTable.vue
+++ b/front/src/components/manage/users/InvitationsTable.vue
@@ -3,11 +3,11 @@
     <div class="ui inline form">
       <div class="fields">
         <div class="ui field">
-          <label><translate>Search</translate></label>
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
           <input name="search" type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
         </div>
         <div class="field">
-          <label><translate>Ordering</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
           <select class="ui dropdown" v-model="ordering">
             <option v-for="option in orderingOptions" :value="option[0]">
               {{ sharedLabels.filters[option[1]] }}
@@ -15,11 +15,11 @@
           </select>
         </div>
         <div class="field">
-          <label><translate>Status</translate></label>
+          <label><translate translate-context="Content/Admin/*/Noun (Value is Used/Not used)">Status</translate></label>
           <select class="ui dropdown" v-model="isOpen">
-            <option :value="null"><translate>All</translate></option>
-            <option :value="true"><translate>Open</translate></option>
-            <option :value="false"><translate>Expired/used</translate></option>
+            <option :value="null"><translate translate-context="Content/*/Dropdown">All</translate></option>
+            <option :value="true"><translate translate-context="Content/Admin/Dropdown/Adjective">Open</translate></option>
+            <option :value="false"><translate translate-context="Content/Admin/Dropdown/Adjective">Expired/used</translate></option>
           </select>
         </div>
       </div>
@@ -36,20 +36,20 @@
         :action-url="'manage/users/invitations/action/'"
         :filters="actionFilters">
         <template slot="header-cells">
-          <th><translate>Owner</translate></th>
-          <th><translate>Status</translate></th>
-          <th><translate>Creation date</translate></th>
-          <th><translate>Expiration date</translate></th>
-          <th><translate>Code</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label">Owner</translate></th>
+          <th><translate translate-context="Content/Admin/*/Noun (Value is Used/Not used)">Status</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Creation date</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label/Noun">Expiration date</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label/Noun">Code</translate></th>
         </template>
         <template slot="row-cells" slot-scope="scope">
           <td>
             <router-link :to="{name: 'manage.users.users.detail', params: {id: scope.obj.id }}">{{ scope.obj.owner.username }}</router-link>
           </td>
           <td>
-            <span v-if="scope.obj.users.length > 0" class="ui green basic label"><translate>Used</translate></span>
-            <span v-else-if="moment().isAfter(scope.obj.expiration_date)" class="ui red basic label"><translate>Expired</translate></span>
-            <span v-else class="ui basic label"><translate>Not used</translate></span>
+            <span v-if="scope.obj.users.length > 0" class="ui green basic label"><translate translate-context="Content/Admin/Table">Used</translate></span>
+            <span v-else-if="moment().isAfter(scope.obj.expiration_date)" class="ui red basic label"><translate translate-context="Content/Admin/Table">Expired</translate></span>
+            <span v-else class="ui basic label"><translate translate-context="Content/Admin/Table">Not used</translate></span>
           </td>
           <td>
             <human-date :date="scope.obj.creation_date"></human-date>
@@ -74,7 +74,7 @@
         ></pagination>
 
       <span v-if="result && result.results.length > 0">
-        <translate
+        <translate translate-context="Content/*/Paragraph"
           :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
           Showing results %{ start }-%{ end } on %{ total }
         </translate>
@@ -150,7 +150,7 @@ export default {
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Search by username, e-mail address, code…')
+        searchPlaceholder: this.$pgettext('Content/Admin/Input.Placeholder/Verb', 'Search by username, e-mail address, code…')
       }
     },
     actionFilters () {
@@ -164,7 +164,7 @@ export default {
       }
     },
     actions () {
-      let deleteLabel = this.$gettext('Delete')
+      let deleteLabel = this.$pgettext('*/*/*/Verb', 'Delete')
       return [
         {
           name: 'delete',
diff --git a/front/src/components/manage/users/UsersTable.vue b/front/src/components/manage/users/UsersTable.vue
index d76634a331d186677db00c943e23483890739196..ee1d3110b2c800e7f1445718ff26f484af82b23e 100644
--- a/front/src/components/manage/users/UsersTable.vue
+++ b/front/src/components/manage/users/UsersTable.vue
@@ -3,11 +3,11 @@
     <div class="ui inline form">
       <div class="fields">
         <div class="ui field">
-          <label><translate>Search</translate></label>
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
           <input name="search" type="text" v-model="search" :placeholder="labels.searchPlaceholder" />
         </div>
         <div class="field">
-          <label><translate>Ordering</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
           <select class="ui dropdown" v-model="ordering">
             <option v-for="option in orderingOptions" :value="option[0]">
               {{ sharedLabels.filters[option[1]] }}
@@ -15,10 +15,10 @@
           </select>
         </div>
         <div class="field">
-          <label><translate>Order</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Order</translate></label>
           <select class="ui dropdown" v-model="orderingDirection">
-            <option value="+"><translate>Ascending</translate></option>
-            <option value="-"><translate>Descending</translate></option>
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
           </select>
         </div>
       </div>
@@ -35,13 +35,13 @@
         :action-url="'manage/library/uploads/action/'"
         :filters="actionFilters">
         <template slot="header-cells">
-          <th><translate>Username</translate></th>
-          <th><translate>Email</translate></th>
-          <th><translate>Account status</translate></th>
-          <th><translate>Sign-up</translate></th>
-          <th><translate>Last activity</translate></th>
-          <th><translate>Permissions</translate></th>
-          <th><translate>Status</translate></th>
+          <th><translate translate-context="Content/*/*">Username</translate></th>
+          <th><translate translate-context="Content/*/*/Noun">Email</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label/Short, Noun">Account status</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label/Short, Noun (Value is a date)">Sign-up</translate></th>
+          <th><translate translate-context="Content/Profile/Table.Label/Short, Noun (Value is a date)">Last activity</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label/Noun">Permissions</translate></th>
+          <th><translate translate-context="Content/Admin/Table.Label/Noun (Value is Regular user/Admin)">Status</translate></th>
         </template>
         <template slot="row-cells" slot-scope="scope">
           <td>
@@ -51,15 +51,15 @@
             <span>{{ scope.obj.email }}</span>
           </td>
           <td>
-            <span v-if="scope.obj.is_active" class="ui basic green label"><translate>Active</translate></span>
-            <span v-else class="ui basic grey label"><translate>Inactive</translate></span>
+            <span v-if="scope.obj.is_active" class="ui basic green label"><translate translate-context="Content/Admin/Table">Active</translate></span>
+            <span v-else class="ui basic grey label"><translate translate-context="Content/Admin/Table">Inactive</translate></span>
           </td>
           <td>
             <human-date :date="scope.obj.date_joined"></human-date>
           </td>
           <td>
             <human-date v-if="scope.obj.last_activity" :date="scope.obj.last_activity"></human-date>
-            <template v-else><translate>N/A</translate></template>
+            <template v-else><translate translate-context="*/*/*">N/A</translate></template>
           </td>
           <td>
             <template v-for="p in permissions">
@@ -67,9 +67,9 @@
             </template>
           </td>
           <td>
-            <span v-if="scope.obj.is_superuser" class="ui pink label"><translate>Admin</translate></span>
-            <span v-else-if="scope.obj.is_staff" class="ui purple label"><translate>Staff member</translate></span>
-            <span v-else class="ui basic label"><translate>regular user</translate></span>
+            <span v-if="scope.obj.is_superuser" class="ui pink label"><translate translate-context="Content/Admin/Table.User role">Admin</translate></span>
+            <span v-else-if="scope.obj.is_staff" class="ui purple label"><translate translate-context="Content/Profile/User role">Staff member</translate></span>
+            <span v-else class="ui basic label"><translate translate-context="Content/Admin/Table, User role">Regular user</translate></span>
           </td>
         </template>
       </action-table>
@@ -85,7 +85,7 @@
         ></pagination>
 
       <span v-if="result && result.results.length > 0">
-        <translate
+        <translate translate-context="Content/*/Paragraph"
           :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
           Showing results %{ start }-%{ end } on %{ total }
         </translate>
@@ -160,7 +160,7 @@ export default {
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Search by username, e-mail address, name…')
+        searchPlaceholder: this.$pgettext('Content/Search/Input.Placeholder', 'Search by username, e-mail address, name…')
       }
     },
     privacyLevels () {
@@ -170,15 +170,15 @@ export default {
       return [
         {
           'code': 'library',
-          'label': this.$gettext('Library')
+          'label': this.$pgettext('*/*/*', 'Library')
         },
         {
           'code': 'moderation',
-          'label': this.$gettext('Moderation')
+          'label': this.$pgettext('*/Moderation/*', 'Moderation')
         },
         {
           'code': 'settings',
-          'label': this.$gettext('Settings')
+          'label': this.$pgettext('*/*/*/Noun', 'Settings')
         }
       ]
     },
@@ -196,7 +196,7 @@ export default {
       return [
         // {
         //   name: 'delete',
-        //   label: this.$gettext('Delete'),
+        //   label: this.$pgettext('Content/Admin/Button.Label/Verb', 'Delete'),
         //   isDangerous: true
         // }
       ]
diff --git a/front/src/components/metadata/ArtistCard.vue b/front/src/components/metadata/ArtistCard.vue
index 98c35337ece4e0c093fc4d77fe0519b835f3b04a..531c2645c147c2504ea2856feb57923572da4bfe 100644
--- a/front/src/components/metadata/ArtistCard.vue
+++ b/front/src/components/metadata/ArtistCard.vue
@@ -46,7 +46,7 @@ export default Vue.extend({
   computed: {
     labels() {
       return {
-        musicbrainz: this.$gettext("View on MusicBrainz")
+        musicbrainz: this.$pgettext('Content/*/*/Clickable, Verb', "View on MusicBrainz")
       }
     },
     type() {
diff --git a/front/src/components/metadata/ReleaseCard.vue b/front/src/components/metadata/ReleaseCard.vue
index 0da2c7e2c64e4f9ec98dd38d829ef08271e778b7..08a0fe4a596f57e962b3be6525d0c2c19ecd4e4e 100644
--- a/front/src/components/metadata/ReleaseCard.vue
+++ b/front/src/components/metadata/ReleaseCard.vue
@@ -50,7 +50,7 @@ export default Vue.extend({
   computed: {
     labels () {
       return {
-        musicbrainz: this.$gettext('View on MusicBrainz')
+        musicbrainz: this.$pgettext('Content/*/*/Clickable, Verb', 'View on MusicBrainz')
       }
     },
     type () {
diff --git a/front/src/components/metadata/Search.vue b/front/src/components/metadata/Search.vue
index c06e2706297fb4da0960434ced776c8f79db3298..f7feb511f095741b77d02e2e45f4fe012173be53 100644
--- a/front/src/components/metadata/Search.vue
+++ b/front/src/components/metadata/Search.vue
@@ -111,7 +111,7 @@ export default {
   computed: {
     labels () {
       return {
-        placeholder: this.$gettext('Enter your search query…')
+        placeholder: this.$pgettext('Content/Library/Input.Placeholder/Verb', 'Enter your search query…')
       }
     },
     currentTypeObject: function () {
@@ -127,15 +127,15 @@ export default {
       return [
         {
           value: 'artist',
-          label: this.$gettext('Artist')
+          label: this.$pgettext('*/*/*/Noun', 'Artist')
         },
         {
           value: 'release',
-          label: this.$gettext('Album')
+          label: this.$pgettext('*/*/*', 'Album')
         },
         {
           value: 'recording',
-          label: this.$gettext('Track')
+          label: this.$pgettext('*/*/*/Noun', 'Track')
         }
       ]
     }
diff --git a/front/src/components/mixins/SmartSearch.vue b/front/src/components/mixins/SmartSearch.vue
index 8b03becbbd8e7fb7b3bd38eaa673d9b01615a728..ef450603961a8cbdf61385d861698993a7ee5734 100644
--- a/front/src/components/mixins/SmartSearch.vue
+++ b/front/src/components/mixins/SmartSearch.vue
@@ -18,6 +18,7 @@ export default {
       return fallback
     },
     addSearchToken (key, value) {
+      value = String(value)
       if (!value) {
         // we remove existing matching tokens, if any
         this.search.tokens = this.search.tokens.filter(t => {
@@ -45,17 +46,19 @@ export default {
     },
     'search.tokens': {
       handler (newValue) {
-        this.search.query = compileTokens(newValue)
-        this.page = 1
-        this.fetchData()
+        let newQuery = compileTokens(newValue)
         if (this.updateUrl) {
           let params = {}
-          if (this.search.query) {
-            params.q = this.search.query
+          if (newQuery) {
+            params.q = newQuery
           }
           this.$router.replace({
             query: params
           })
+        } else {
+          this.search.query = newQuery
+          this.page = 1
+          this.fetchData()
         }
       },
       deep: true
diff --git a/front/src/components/mixins/Translations.vue b/front/src/components/mixins/Translations.vue
index 9d237c9161bb14fb26339f18de51399ac924ac11..56ea3ed152642d6b5fa99e415d42625262571224 100644
--- a/front/src/components/mixins/Translations.vue
+++ b/front/src/components/mixins/Translations.vue
@@ -5,38 +5,106 @@ export default {
       return {
         fields: {
           privacy_level: {
-            label: this.$gettext('Activity visibility'),
-            help: this.$gettext('Determine the visibility level of your activity'),
+            label: this.$pgettext('Content/Settings/Dropdown.Label/Noun', 'Activity visibility'),
+            help: this.$pgettext('Content/Settings/Dropdown.Help text', 'Determine the visibility level of your activity'),
             choices: {
-              me: this.$gettext('Nobody except me'),
-              instance: this.$gettext('Everyone on this instance'),
+              me: this.$pgettext('Content/Settings/Dropdown', 'Nobody except me'),
+              instance: this.$pgettext('Content/Settings/Dropdown', 'Everyone on this instance'),
+              everyone: this.$pgettext('Content/Settings/Dropdown', 'Everyone, across all instances'),
+            },
+            shortChoices: {
+              me: this.$pgettext('Content/Settings/Dropdown/Short', 'Private'),
+              instance: this.$pgettext('Content/Settings/Dropdown/Short', 'Instance'),
+              everyone: this.$pgettext('Content/Settings/Dropdown/Short', 'Everyone'),
             }
-          }
+          },
+          import_status: {
+            detailTitle: this.$pgettext('Content/Library/Link.Title', 'Click to display more information about the import process for this upload'),
+            choices: {
+              skipped: {
+                label: this.$pgettext('Content/Library/*', 'Skipped'),
+                help: this.$pgettext('Content/Library/Help text', 'This track is already present in one of your libraries'),
+              },
+              pending: {
+                label: this.$pgettext('Content/Library/*/Short', 'Pending'),
+                help: this.$pgettext('Content/Library/Help text', 'This track has been uploaded, but hasn\'t been processed by the server yet'),
+              },
+              errored: {
+                label: this.$pgettext('Content/Library/Table/Short', 'Errored'),
+                help: this.$pgettext('Content/Library/Help text', 'This track could not be processed, please it is tagged correctly'),
+              },
+              finished: {
+                label: this.$pgettext('Content/Library/*', 'Finished'),
+                help: this.$pgettext('Content/Library/Help text', 'Imported'),
+              },
+            }
+          },
         },
         filters: {
-          creation_date: this.$gettext('Creation date'),
-          first_seen: this.$gettext('First seen date'),
-          last_seen: this.$gettext('Last seen date'),
-          accessed_date: this.$gettext('Accessed date'),
-          modification_date: this.$gettext('Modification date'),
-          imported_date: this.$gettext('Imported date'),
-          expiration_date: this.$gettext('Expiration date'),
-          track_title: this.$gettext('Track name'),
-          album_title: this.$gettext('Album name'),
-          artist_name: this.$gettext('Artist name'),
-          name: this.$gettext('Name'),
-          title: this.$gettext('Title'),
-          size: this.$gettext('Size'),
-          bitrate: this.$gettext('Bitrate'),
-          duration: this.$gettext('Duration'),
-          date_joined: this.$gettext('Sign-up date'),
-          last_activity: this.$gettext('Last activity'),
-          username: this.$gettext('Username'),
-          domain: this.$gettext('Domain'),
-          users: this.$gettext('Users'),
-          received_messages: this.$gettext('Received messages'),
-          uploads: this.$gettext('Uploads'),
-          followers: this.$gettext('Followers'),
+          creation_date: this.$pgettext('Content/*/*/Noun', 'Creation date'),
+          release_date: this.$pgettext('Content/*/*/Noun', 'Release date'),
+          accessed_date: this.$pgettext('Content/*/*/Noun', 'Accessed date'),
+          first_seen: this.$pgettext('Content/Moderation/Dropdown/Noun', 'First seen date'),
+          last_seen: this.$pgettext('Content/Moderation/Dropdown/Noun', 'Last seen date'),
+          modification_date: this.$pgettext('Content/Playlist/Dropdown/Noun', 'Modification date'),
+          expiration_date: this.$pgettext('Content/Admin/Table.Label/Noun', 'Expiration date'),
+          track_title: this.$pgettext('Content/*/Dropdown/Noun', 'Track name'),
+          album_title: this.$pgettext('Content/*/Dropdown/Noun', 'Album name'),
+          artist_name: this.$pgettext('Content/*/Dropdown/Noun', 'Artist name'),
+          name: this.$pgettext('*/*/*/Noun', 'Name'),
+          size: this.$pgettext('Content/Library/*/in MB', 'Size'),
+          bitrate: this.$pgettext('Content/Track/*/Noun', 'Bitrate'),
+          duration: this.$pgettext('Content/*/*', 'Duration'),
+          date_joined: this.$pgettext('Content/Admin/Table.Label/Noun', 'Sign-up date'),
+          last_activity: this.$pgettext('Content/Profile/Table.Label/Short, Noun (Value is a date)', 'Last activity'),
+          username: this.$pgettext('Content/*/*', 'Username'),
+          domain: this.$pgettext('Content/Moderation/*/Noun', 'Domain'),
+          users: this.$pgettext('*/*/*/Noun', 'Users'),
+          received_messages: this.$pgettext('Content/Moderation/*/Noun', 'Received messages'),
+          uploads: this.$pgettext('Content/Moderation/Table.Label/Noun', 'Uploads'),
+          followers: this.$pgettext('Content/Federation/*/Noun', 'Followers'),
+        },
+        scopes: {
+          profile: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Profile'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to email, username, and profile information'),
+          },
+          libraries: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Libraries and uploads'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to audio files, libraries, artists, albums and tracks'),
+          },
+          favorites: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Favorites'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to favorites'),
+          },
+          listenings: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Listenings'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to listening history'),
+          },
+          follows: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Follows'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to follows'),
+          },
+          playlists: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Playlists'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to playlists'),
+          },
+          radios: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Radios'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to radios'),
+          },
+          filters: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Content filters'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to content filters'),
+          },
+          notifications: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Notifications'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to notifications'),
+          },
+          edits: {
+            label: this.$pgettext('Content/OAuth Scopes/Label', 'Edits'),
+            description: this.$pgettext('Content/OAuth Scopes/Paragraph', 'Access to edits'),
+          }
         }
       }
     }
diff --git a/front/src/components/moderation/FilterModal.vue b/front/src/components/moderation/FilterModal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..8885e61fc08f6f9a5dde2787c1ec77ad56afa2fe
--- /dev/null
+++ b/front/src/components/moderation/FilterModal.vue
@@ -0,0 +1,108 @@
+<template>
+  <modal @update:show="update" :show="$store.state.moderation.showFilterModal">
+    <div class="header">
+      <translate
+        v-if="type === 'artist'"
+        key="1"
+        translate-context="Popup/Moderation/Title/Verb"
+        :translate-params="{name: target.name}">Do you want to hide content from artist "%{ name }"?</translate>
+    </div>
+    <div class="scrolling content">
+      <div class="description">
+
+        <div v-if="errors.length > 0" class="ui negative message">
+          <div class="header"><translate translate-context="Popup/Moderation/Error message">Error while creating filter</translate></div>
+          <ul class="list">
+            <li v-for="error in errors">{{ error }}</li>
+          </ul>
+        </div>
+        <template v-if="type === 'artist'">
+          <p>
+            <translate translate-context="Popup/Moderation/Paragraph">
+              You will not see tracks, albums and user activity linked to this artist anymore:
+            </translate>
+          </p>
+          <ul>
+            <li><translate translate-context="Popup/Moderation/List item">In other users favorites and listening history</translate></li>
+            <li><translate translate-context="Popup/Moderation/List item">In "Recently added" widget</translate></li>
+            <li><translate translate-context="Popup/Moderation/List item">In artists and album listings</translate></li>
+            <li><translate translate-context="Popup/Moderation/List item">In radio suggestions</translate></li>
+          </ul>
+          <p>
+            <translate translate-context="Popup/Moderation/Paragraph">
+              You can manage and update your filters anytime from your account settings.
+            </translate>
+          </p>
+        </template>
+      </div>
+    </div>
+    <div class="actions">
+      <div class="ui cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
+      <div :class="['ui', 'green', {loading: isLoading}, 'button']" @click="hide"><translate translate-context="Popup/*/Button.Label">Hide content</translate></div>
+    </div>
+  </modal>
+</template>
+
+<script>
+import _ from '@/lodash'
+import axios from 'axios'
+import {mapState} from 'vuex'
+
+import logger from '@/logging'
+import Modal from '@/components/semantic/Modal'
+
+export default {
+  components: {
+    Modal,
+  },
+  data () {
+    return {
+      formKey: String(new Date()),
+      errors: [],
+      isLoading: false
+    }
+  },
+  computed: {
+    ...mapState({
+      type: state => state.moderation.filterModalTarget.type,
+      target: state => state.moderation.filterModalTarget.target,
+    })
+  },
+  methods: {
+    update (v) {
+      this.$store.commit('moderation/showFilterModal', v)
+      this.errors = []
+    },
+    hide () {
+      let self = this
+      self.isLoading = true
+      let payload = {
+        target: {
+          type: this.type,
+          id: this.target.id,
+        }
+      }
+      return axios.post('moderation/content-filters/', payload).then(response => {
+        logger.default.info('Successfully added track to playlist')
+        self.update(false)
+        self.$store.commit('moderation/lastUpdate', new Date())
+        self.isLoading = false
+        let msg = this.$pgettext('*/Moderation/Message', 'Content filter successfully added')
+        self.$store.commit('moderation/contentFilter', response.data)
+        self.$store.commit('ui/addMessage', {
+          content: msg,
+          date: new Date()
+        })
+      }, error => {
+        logger.default.error(`Error while hiding ${self.type} ${self.target.id}`)
+        self.errors = error.backendErrors
+        self.isLoading = false
+      })
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/front/src/components/notifications/NotificationRow.vue b/front/src/components/notifications/NotificationRow.vue
index 530e1527063023f9e305a13d08e7d070e904f442..b8e145647d03340fb62b8edc981f25179f341a9a 100644
--- a/front/src/components/notifications/NotificationRow.vue
+++ b/front/src/components/notifications/NotificationRow.vue
@@ -36,15 +36,15 @@ export default {
       return 'plop'
     },
     labels () {
-      let libraryFollowMessage = this.$gettext('%{ username } followed your library "%{ library }"')
-      let libraryAcceptFollowMessage = this.$gettext('%{ username } accepted your follow on library "%{ library }"')
-      let libraryPendingFollowMessage = this.$gettext('%{ username } wants to follow your library "%{ library }"')
+      let libraryFollowMessage = this.$pgettext('Content/Notifications/Paragraph', '%{ username } followed your library "%{ library }"')
+      let libraryAcceptFollowMessage = this.$pgettext('Content/Notifications/Paragraph', '%{ username } accepted your follow on library "%{ library }"')
+      let libraryPendingFollowMessage = this.$pgettext('Content/Notifications/Paragraph', '%{ username } wants to follow your library "%{ library }"')
       return {
         libraryFollowMessage,
         libraryAcceptFollowMessage,
-				libraryPendingFollowMessage,
-        markRead: this.$gettext('Mark as read'),
-        markUnread: this.$gettext('Mark as unread'),
+        libraryPendingFollowMessage,
+        markRead: this.$pgettext('Content/Notifications/Button.Tooltip/Verb', 'Mark as read'),
+        markUnread: this.$pgettext('Content/Notifications/Button.Tooltip/Verb', 'Mark as unread'),
 
       }
     },
@@ -57,18 +57,18 @@ export default {
       if (a.type === 'Follow') {
         if (a.object && a.object.type === 'music.Library') {
           let action = null
-					let message = null
+          let message = null
           if (!a.related_object.approved) {
-						message = this.labels.libraryPendingFollowMessage
+            message = this.labels.libraryPendingFollowMessage
             action = {
               buttonClass: 'green',
               icon: 'check',
-              label: this.$gettext('Approve'),
+              label: this.$pgettext('Content/*/Button.Label/Verb', 'Approve'),
               handler: () => { self.approveLibraryFollow(a.related_object) }
             }
-					} else {
-						message = this.labels.libraryFollowMessage
-					}
+          } else {
+            message = this.labels.libraryFollowMessage
+          }
           return {
             action,
             detailUrl: {name: 'content.libraries.detail', params: {id: a.object.uuid}},
diff --git a/front/src/components/playlists/Card.vue b/front/src/components/playlists/Card.vue
index 344eb5fbf9ecbc17e7d744d85cdb4efdf2b3d17e..60a322ab4c86486842d79f176b6b536b6714041e 100644
--- a/front/src/components/playlists/Card.vue
+++ b/front/src/components/playlists/Card.vue
@@ -16,7 +16,7 @@
         <duration :seconds="playlist.duration" />
          |
         <i class="sound icon"></i>
-        <translate
+        <translate translate-context="Content/*/Card/List item"
           translate-plural="%{ count } tracks"
           :translate-n="playlist.tracks_count"
           :translate-params="{count: playlist.tracks_count}">
diff --git a/front/src/components/playlists/Editor.vue b/front/src/components/playlists/Editor.vue
index e42c60dae17086f6683c7b2552975e429dd9dc7e..3ce554301901df62fb142b348edb51ea2d17e0f5 100644
--- a/front/src/components/playlists/Editor.vue
+++ b/front/src/components/playlists/Editor.vue
@@ -2,34 +2,44 @@
   <div class="ui text container">
     <playlist-form @updated="$emit('playlist-updated', $event)" :title="false" :playlist="playlist"></playlist-form>
     <h3 class="ui top attached header">
-      <translate>Playlist editor</translate>
+      <translate translate-context="Content/Playlist/Title">Playlist editor</translate>
     </h3>
     <div class="ui attached segment">
       <template v-if="status === 'loading'">
         <div class="ui active tiny inline loader"></div>
-        <translate>Syncing changes to server…</translate>
+        <translate translate-context="Content/Playlist/Paragraph">Syncing changes to server…</translate>
       </template>
       <template v-else-if="status === 'errored'">
         <i class="red close icon"></i>
-        <translate>An error occured while saving your changes</translate>
+        <translate translate-context="Content/Playlist/Error message.Title">An error occured while saving your changes</translate>
         <div v-if="errors.length > 0" class="ui negative message">
           <ul class="list">
             <li v-for="error in errors">{{ error }}</li>
           </ul>
         </div>
       </template>
+      <div v-else-if="status === 'confirmDuplicateAdd'" class="ui warning message">
+        <p translate-context="Content/Playlist/Paragraph"
+            v-translate="{playlist: playlist.name}">Some tracks in your queue are already in this playlist:</p>
+        <ul id="duplicateTrackList" class="ui relaxed divided list">
+          <li v-for="track in duplicateTrackAddInfo.tracks" class="ui item">{{ track }}</li>
+        </ul>
+        <button
+          class="ui small green button"
+          @click="insertMany(queueTracks, true)"><translate translate-context="*/Playlist/Button.Label/Verb">Add anyways</translate></button>
+      </div>
       <template v-else-if="status === 'saved'">
-        <i class="green check icon"></i> <translate>Changes synced with server</translate>
+        <i class="green check icon"></i> <translate translate-context="Content/Playlist/Paragraph">Changes synced with server</translate>
       </template>
     </div>
     <div class="ui bottom attached segment">
       <div
-        @click="insertMany(queueTracks)"
+        @click="insertMany(queueTracks, false)"
         :disabled="queueTracks.length === 0"
         :class="['ui', {disabled: queueTracks.length === 0}, 'labeled', 'icon', 'button']"
         :title="labels.copyTitle">
           <i class="plus icon"></i>
-          <translate
+          <translate translate-context="Content/Playlist/Button.Label/Verb"
             translate-plural="Insert from queue (%{ count } tracks)"
             :translate-n="queueTracks.length"
             :translate-params="{count: queueTracks.length}">
@@ -38,34 +48,37 @@
         </div>
 
       <dangerous-button :disabled="plts.length === 0" class="labeled right floated icon" color='yellow' :action="clearPlaylist">
-        <i class="eraser icon"></i> <translate>Clear playlist</translate>
-        <p slot="modal-header" v-translate="{playlist: playlist.name}" :translate-params="{playlist: playlist.name}">
+        <i class="eraser icon"></i> <translate translate-context="*/Playlist/Button.Label/Verb">Clear playlist</translate>
+        <p slot="modal-header" v-translate="{playlist: playlist.name}" translate-context="Popup/Playlist/Title"  :translate-params="{playlist: playlist.name}">
           Do you want to clear the playlist "%{ playlist }"?
         </p>
-        <p slot="modal-content"><translate>This will remove all tracks from this playlist and cannot be undone.</translate></p>
-        <p slot="modal-confirm"><translate>Clear playlist</translate></p>
+        <p slot="modal-content"><translate translate-context="Popup/Playlist/Paragraph">This will remove all tracks from this playlist and cannot be undone.</translate></p>
+        <div slot="modal-confirm"><translate translate-context="*/Playlist/Button.Label/Verb">Clear playlist</translate></div>
       </dangerous-button>
       <div class="ui hidden divider"></div>
       <template v-if="plts.length > 0">
-        <p><translate>Drag and drop rows to reorder tracks in the playlist</translate></p>
-        <table class="ui compact very basic fixed single line unstackable table">
-          <draggable v-model="plts" element="tbody" @update="reorder">
-            <tr v-for="(plt, index) in plts" :key="plt.id">
-              <td class="left aligned">{{ plt.index + 1}}</td>
-              <td class="center aligned">
-                <img class="ui mini image" v-if="plt.track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.small_square_crop)">
-                <img class="ui mini image" v-else src="../../assets/audio/default-cover.png">
-              </td>
-              <td colspan="4">
-                <strong>{{ plt.track.title }}</strong><br />
-                  {{ plt.track.artist.name }}
-              </td>
-              <td class="right aligned">
-                <i @click.stop="removePlt(index)" class="circular red trash icon"></i>
-              </td>
-            </tr>
-          </draggable>
-        </table>
+        <p><translate translate-context="Content/Playlist/Paragraph/Call to action">Drag and drop rows to reorder tracks in the playlist</translate></p>
+        <div class="table-wrapper">
+          <table class="ui compact very basic unstackable table">
+            <draggable v-model="plts" element="tbody" @update="reorder">
+              <tr v-for="(plt, index) in plts" :key="plt.id">
+                <td class="left aligned">{{ plt.index + 1}}</td>
+                <td class="center aligned">
+                  <img class="ui mini image" v-if="plt.track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.small_square_crop)">
+                  <img class="ui mini image" v-else src="../../assets/audio/default-cover.png">
+                </td>
+                <td colspan="4">
+                  <strong>{{ plt.track.title }}</strong><br />
+                    {{ plt.track.artist.name }}
+                </td>
+                <td class="right aligned">
+                  <i @click.stop="removePlt(index)" class="circular red trash icon"></i>
+                </td>
+              </tr>
+            </draggable>
+          </table>
+
+        </div>
       </template>
     </div>
   </div>
@@ -88,17 +101,25 @@ export default {
     return {
       plts: this.playlistTracks,
       isLoading: false,
-      errors: []
+      errors: [],
+      duplicateTrackAddInfo: {},
+      showDuplicateTrackAddConfirmation: false
     }
   },
   methods: {
     success () {
       this.isLoading = false
       this.errors = []
+      this.showDuplicateTrackAddConfirmation = false
     },
     errored (errors) {
       this.isLoading = false
-      this.errors = errors
+      if (errors.length == 1 && errors[0].code == 'tracks_already_exist_in_playlist') {
+        this.duplicateTrackAddInfo = errors[0]
+        this.showDuplicateTrackAddConfirmation = true
+      } else {
+        this.errors = errors
+      }
     },
     reorder ({oldIndex, newIndex}) {
       let self = this
@@ -136,21 +157,31 @@ export default {
         self.errored(error.backendErrors)
       })
     },
-    insertMany (tracks) {
+    insertMany (tracks, allowDuplicates) {
       let self = this
       let ids = tracks.map(t => {
         return t.id
       })
+      let payload = {
+        tracks: ids,
+        allow_duplicates: allowDuplicates
+      }
       self.isLoading = true
       let url = 'playlists/' + this.playlist.id + '/add/'
-      axios.post(url, {tracks: ids}).then((response) => {
+      axios.post(url, payload).then((response) => {
         response.data.results.forEach(r => {
           self.plts.push(r)
         })
         self.success()
         self.$store.dispatch('playlists/fetchOwn')
       }, error => {
-        self.errored(error.backendErrors)
+        // if backendErrors isn't populated (e.g. duplicate track exceptions raised by
+        // the playlist model), read directly from the response
+        if (error.rawPayload.playlist) {
+          self.errored(error.rawPayload.playlist.non_field_errors)
+        } else {
+          self.errored(error.backendErrors)
+        }
       })
     }
   },
@@ -160,7 +191,7 @@ export default {
     }),
     labels () {
       return {
-        copyTitle: this.$gettext('Copy queued tracks to playlist')
+        copyTitle: this.$pgettext('Content/Playlist/Button.Tooltip/Verb', 'Copy queued tracks to playlist')
       }
     },
     status () {
@@ -170,6 +201,9 @@ export default {
       if (this.errors.length > 0) {
         return 'errored'
       }
+      if (this.showDuplicateTrackAddConfirmation) {
+        return 'confirmDuplicateAdd'
+      }
       return 'saved'
     }
   },
@@ -189,4 +223,8 @@ export default {
 
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped>
+#duplicateTrackList {
+  max-height: 10em;
+  overflow-y: auto;
+}
 </style>
diff --git a/front/src/components/playlists/Form.vue b/front/src/components/playlists/Form.vue
index 1fe9740654192adcdbbc22872dbae38217d976d7..4fc905fc6aeb66427771c75164ff5fba519b387f 100644
--- a/front/src/components/playlists/Form.vue
+++ b/front/src/components/playlists/Form.vue
@@ -1,29 +1,29 @@
 <template>
   <form class="ui form" @submit.prevent="submit()">
-    <h4 v-if="title" class="ui header"><translate>Create a new playlist</translate></h4>
+    <h4 v-if="title" class="ui header"><translate translate-context="Popup/Playlist/Title/Verb">Create a new playlist</translate></h4>
     <div v-if="success" class="ui positive message">
       <div class="header">
         <template v-if="playlist">
-          <translate>Playlist updated</translate>
+          <translate translate-context="Content/Playlist/Message">Playlist updated</translate>
         </template>
         <template v-else>
-          <translate>Playlist created</translate>
+          <translate translate-context="Content/Playlist/Message">Playlist created</translate>
         </template>
       </div>
     </div>
     <div v-if="errors.length > 0" class="ui negative message">
-      <div class="header"><translate>We cannot create the playlist</translate></div>
+      <div class="header"><translate translate-context="Content/Playlist/Error message.Title">The playlist could not be created</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
     </div>
     <div class="three fields">
       <div class="field">
-        <label><translate>Playlist name</translate></label>
+        <label><translate translate-context="Content/Playlist/Input.Label">Playlist name</translate></label>
         <input name="name" v-model="name" required type="text" :placeholder="labels.placeholder" />
       </div>
       <div class="field">
-        <label><translate>Playlist visibility</translate></label>
+        <label><translate translate-context="Content/Playlist/Dropdown.Label">Playlist visibility</translate></label>
         <select class="ui dropdown" v-model="privacyLevel">
           <option :value="c.value" v-for="c in privacyLevelChoices">{{ c.label }}</option>
         </select>
@@ -31,8 +31,8 @@
       <div class="field">
         <label>&nbsp;</label>
         <button :class="['ui', 'fluid', {'loading': isLoading}, 'button']" type="submit">
-          <template v-if="playlist"><translate>Update playlist</translate></template>
-          <template v-else><translate>Create playlist</translate></template>
+          <template v-if="playlist"><translate translate-context="Content/Playlist/Button.Label/Verb">Update playlist</translate></template>
+          <template v-else><translate translate-context="Content/Playlist/Button.Label/Verb">Create playlist</translate></template>
         </button>
       </div>
     </div>
@@ -42,10 +42,12 @@
 <script>
 import $ from 'jquery'
 import axios from 'axios'
+import TranslationsMixin from "@/components/mixins/Translations"
 
 import logger from '@/logging'
 
 export default {
+  mixins: [TranslationsMixin],
   props: {
     title: {type: Boolean, default: true},
     playlist: {type: Object, default: null}
@@ -71,22 +73,22 @@ export default {
   computed: {
     labels () {
       return {
-        placeholder: this.$gettext('My awesome playlist')
+        placeholder: this.$pgettext('Content/Playlist/Input.Placeholder', 'My awesome playlist')
       }
     },
     privacyLevelChoices: function () {
       return [
         {
           value: 'me',
-          label: this.$gettext('Nobody except me')
+          label: this.sharedLabels.fields.privacy_level.choices['me']
         },
         {
           value: 'instance',
-          label: this.$gettext('Everyone on this instance')
+          label: this.sharedLabels.fields.privacy_level.choices['instance']
         },
         {
           value: 'everyone',
-          label: this.$gettext('Everyone')
+          label: this.sharedLabels.fields.privacy_level.choices['everyone']
         }
       ]
     }
diff --git a/front/src/components/playlists/PlaylistModal.vue b/front/src/components/playlists/PlaylistModal.vue
index 7d44f0e191d5a55afaf645e5fa5181dfd329f5f5..44969afbfd8860c565173292c8eb338178869173 100644
--- a/front/src/components/playlists/PlaylistModal.vue
+++ b/front/src/components/playlists/PlaylistModal.vue
@@ -1,13 +1,14 @@
 <template>
   <modal @update:show="update" :show="$store.state.playlists.showModal">
     <div class="header">
-      <translate>Manage playlists</translate>
+      <translate translate-context="Popup/Playlist/Title/Verb">Manage playlists</translate>
     </div>
     <div class="scrolling content">
       <div class="description">
         <template v-if="track">
-          <h4 class="ui header"><translate>Current track</translate></h4>
+          <h4 class="ui header"><translate translate-context="Popup/Playlist/Title">Current track</translate></h4>
           <span
+            translate-context="Popup/Playlist/Paragraph"
             v-translate="{artist: track.artist.name, title: track.title}"
             :translate-params="{artist: track.artist.name, title: track.title}">
             "%{ title }", by %{ artist }
@@ -17,21 +18,34 @@
 
         <playlist-form :key="formKey"></playlist-form>
         <div class="ui divider"></div>
+        <div v-if="showDuplicateTrackAddConfirmation" class="ui warning message">
+          <p translate-context="Popup/Playlist/Paragraph"
+            v-translate="{track: track.title, playlist: duplicateTrackAddInfo.playlist_name}"
+            :translate-params="{track: track.title, playlist: duplicateTrackAddInfo.playlist_name}"><strong>%{ track }</strong> is already in <strong>%{ playlist }</strong>.</p>
+          <button
+            @click="update(false)"
+            class="ui small cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate>
+          </button>
+          <button
+            class="ui small green button"
+            @click="addToPlaylist(lastSelectedPlaylist, true)">
+              <translate translate-context="*/Playlist/Button.Label/Verb">Add anyways</translate></button>
+        </div>
         <div v-if="errors.length > 0" class="ui negative message">
-          <div class="header"><translate>We cannot add the track to a playlist</translate></div>
+          <div class="header"><translate translate-context="Popup/Playlist/Error message.Title">The track can't be added to a playlist</translate></div>
           <ul class="list">
             <li v-for="error in errors">{{ error }}</li>
           </ul>
         </div>
         </div>
-        <h4 class="ui header"><translate>Available playlists</translate></h4>
+        <h4 class="ui header"><translate translate-context="Popup/Playlist/Title">Available playlists</translate></h4>
         <table class="ui unstackable very basic table">
           <thead>
             <tr>
               <th></th>
-              <th><translate>Name</translate></th>
-              <th class="sorted descending"><translate>Last modification</translate></th>
-              <th><translate>Tracks</translate></th>
+              <th><translate translate-context="*/*/*/Noun">Name</translate></th>
+              <th class="sorted descending"><translate translate-context="Popup/Playlist/Table.Label/Short">Last modification</translate></th>
+              <th><translate translate-context="*/*/*/Noun">Tracks</translate></th>
               <th></th>
             </tr>
           </thead>
@@ -51,8 +65,8 @@
                   v-if="track"
                   class="ui green icon basic small right floated button"
                   :title="labels.addToPlaylist"
-                  @click="addToPlaylist(playlist.id)">
-                  <i class="plus icon"></i> <translate>Add track</translate>
+                  @click="addToPlaylist(playlist.id, false)">
+                  <i class="plus icon"></i> <translate translate-context="Popup/Playlist/Table.Button.Label/Verb">Add track</translate>
                 </div>
               </td>
             </tr>
@@ -61,7 +75,7 @@
       </div>
     </div>
     <div class="actions">
-      <div class="ui cancel button"><translate>Cancel</translate></div>
+      <div class="ui cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div>
     </div>
   </modal>
 </template>
@@ -83,26 +97,38 @@ export default {
   data () {
     return {
       formKey: String(new Date()),
-      errors: []
+      errors: [],
+      duplicateTrackAddInfo: {},
+      showDuplicateTrackAddConfirmation: false,
+      lastSelectedPlaylist: -1,
     }
   },
   methods: {
     update (v) {
       this.$store.commit('playlists/showModal', v)
     },
-    addToPlaylist (playlistId) {
+    addToPlaylist (playlistId, allowDuplicate) {
       let self = this
       let payload = {
         track: this.track.id,
-        playlist: playlistId
+        playlist: playlistId,
+        allow_duplicates: allowDuplicate
       }
+
+      self.lastSelectedPlaylist = playlistId
+
       return axios.post('playlist-tracks/', payload).then(response => {
         logger.default.info('Successfully added track to playlist')
         self.update(false)
         self.$store.dispatch('playlists/fetchOwn')
       }, error => {
-        logger.default.error('Error while adding track to playlist')
-        self.errors = error.backendErrors
+        if (error.backendErrors.length == 1 && error.backendErrors[0].code == 'tracks_already_exist_in_playlist') {
+          self.duplicateTrackAddInfo = error.backendErrors[0]
+          self.showDuplicateTrackAddConfirmation = true
+        } else {
+          self.errors = error.backendErrors
+          self.showDuplicateTrackAddConfirmation = false
+        }
       })
     }
   },
@@ -113,7 +139,7 @@ export default {
     }),
     labels () {
       return {
-        addToPlaylist: this.$gettext('Add to this playlist')
+        addToPlaylist: this.$pgettext('Popup/Playlist/Table.Button.Tooltip/Verb', 'Add to this playlist')
       }
     },
     sortedPlaylists () {
@@ -125,9 +151,11 @@ export default {
   watch: {
     '$store.state.route.path' () {
       this.$store.commit('playlists/showModal', false)
+      this.showDuplicateTrackAddConfirmation = false
     },
     '$store.state.playlists.showModal' () {
       this.formKey = String(new Date())
+      this.showDuplicateTrackAddConfirmation = false
     }
   }
 }
diff --git a/front/src/components/playlists/TrackPlaylistIcon.vue b/front/src/components/playlists/TrackPlaylistIcon.vue
index 8487e6777b23c181749e8b8764fdc79bfeb7dc61..2f57eb163ab3c698bc4695ed69a1d2644a930e8b 100644
--- a/front/src/components/playlists/TrackPlaylistIcon.vue
+++ b/front/src/components/playlists/TrackPlaylistIcon.vue
@@ -2,9 +2,9 @@
   <button
     @click="$store.commit('playlists/chooseTrack', track)"
     v-if="button"
-    :class="['ui', 'button']">
+    :class="['ui', 'icon', 'labeled', 'button']">
     <i class="list icon"></i>
-    <translate>Add to playlist…</translate>
+    <translate translate-context="Sidebar/Player/Icon.Tooltip/Verb">Add to playlist…</translate>
   </button>
   <button
     v-else
@@ -31,7 +31,7 @@ export default {
   computed: {
     labels () {
       return {
-        addToPlaylist: this.$gettext('Add to playlist…')
+        addToPlaylist: this.$pgettext('Sidebar/Player/Icon.Tooltip/Verb', 'Add to playlist…')
       }
     }
   }
diff --git a/front/src/components/playlists/Widget.vue b/front/src/components/playlists/Widget.vue
index 7329c502ec27f0f1f55cf41abea6636c9cf53ea7..b018f9731e97b307df3ded23a5d1660c6eba9ea9 100644
--- a/front/src/components/playlists/Widget.vue
+++ b/front/src/components/playlists/Widget.vue
@@ -6,7 +6,6 @@
     <button :disabled="!previousPage" @click="fetchData(previousPage)" :class="['ui', {disabled: !previousPage}, 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'angle up', 'icon']"></i></button>
     <button :disabled="!nextPage" @click="fetchData(nextPage)" :class="['ui', {disabled: !nextPage}, 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'angle down', 'icon']"></i></button>
     <button @click="fetchData(url)" :class="['ui', 'circular', 'icon', 'basic', 'button']"><i :class="['ui', 'refresh', 'icon']"></i></button>
-
     <div v-if="isLoading" class="ui inverted active dimmer">
       <div class="ui loader"></div>
     </div>
@@ -71,6 +70,9 @@ export default {
   watch: {
     offset () {
       this.fetchData()
+    },
+    "$store.state.moderation.lastUpdate": function () {
+      this.fetchData(this.url)
     }
   }
 }
diff --git a/front/src/components/radios/Button.vue b/front/src/components/radios/Button.vue
index a33478c9d1e9e8932ffbb6781e3c5d7a8f4bdaa9..e66f97ad5fafe1622e6a586c8e2d88155e87a766 100644
--- a/front/src/components/radios/Button.vue
+++ b/front/src/components/radios/Button.vue
@@ -1,9 +1,8 @@
 <template>
-  <button @click="toggleRadio" :class="['ui', 'blue', {'inverted': running}, 'button']">
+  <button @click="toggleRadio" :class="['ui', 'blue', {'inverted': running}, 'icon', 'labeled', 'button']">
     <i class="ui feed icon"></i>
-    <template v-if="running"><translate>Stop</translate></template>
-    <template v-else><translate>Start</translate></template>
-    radio
+    <template v-if="running"><translate translate-context="*/Player/Button.Label/Short, Verb">Stop radio</translate></template>
+    <template v-else><translate translate-context="*/Queue/Button.Label/Short, Verb">Start radio</translate></template>
   </button>
 </template>
 
diff --git a/front/src/components/radios/Card.vue b/front/src/components/radios/Card.vue
index ae0ae20960e36e4f076b1da6c50fc4b3b7a9fa58..e72b9f1c1ca65cf6fd10020fe1b0b720de5a49f9 100644
--- a/front/src/components/radios/Card.vue
+++ b/front/src/components/radios/Card.vue
@@ -15,12 +15,13 @@
       </div>
       <div class="extra content">
         <user-link v-if="radio.user" :user="radio.user" class="left floated" />
+        <div class="ui hidden divider"></div>
         <radio-button class="right floated button" :type="type" :custom-radio-id="customRadioId"></radio-button>
         <router-link
           class="ui basic yellow button right floated"
           v-if="$store.state.auth.authenticated && type === 'custom' && radio.user.id === $store.state.auth.profile.id"
           :to="{name: 'library.radios.edit', params: {id: customRadioId }}">
-          <translate>Edit…</translate>
+          <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
         </router-link>
       </div>
     </div>
diff --git a/front/src/components/semantic/Modal.vue b/front/src/components/semantic/Modal.vue
index fec8fdd0595ffd8866d93e54bd2cffaedd2f52d5..076b3e466dac8b487924d06f0ae24d4d04a0b854 100644
--- a/front/src/components/semantic/Modal.vue
+++ b/front/src/components/semantic/Modal.vue
@@ -21,8 +21,9 @@ export default {
   },
   beforeDestroy () {
     if (this.control) {
-      this.control.remove()
+      $(this.$el).modal('hide')
     }
+    $(this.$el).remove()
   },
   methods: {
     initModal () {
@@ -61,5 +62,4 @@ export default {
 
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
-
 </style>
diff --git a/front/src/edits.js b/front/src/edits.js
new file mode 100644
index 0000000000000000000000000000000000000000..a53ab2fcc286d31815b81b99cb4a161a53416c4a
--- /dev/null
+++ b/front/src/edits.js
@@ -0,0 +1,117 @@
+export default {
+  getConfigs () {
+    return {
+      artist: {
+        fields: [
+          {
+            id: 'name',
+            type: 'text',
+            required: true,
+            label: this.$pgettext('*/*/*/Noun', 'Name'),
+            getValue: (obj) => { return obj.name }
+          },
+        ]
+      },
+      album: {
+        fields: [
+          {
+            id: 'title',
+            type: 'text',
+            required: true,
+            label: this.$pgettext('*/*/*/Noun', 'Title'),
+            getValue: (obj) => { return obj.title }
+          },
+          {
+            id: 'release_date',
+            type: 'text',
+            required: false,
+            label: this.$pgettext('Content/*/*/Noun', 'Release date'),
+            getValue: (obj) => { return obj.release_date }
+          },
+        ]
+      },
+      track: {
+        fields: [
+          {
+            id: 'title',
+            type: 'text',
+            required: true,
+            label: this.$pgettext('*/*/*/Noun', 'Title'),
+            getValue: (obj) => { return obj.title }
+          },
+          {
+            id: 'position',
+            type: 'text',
+            inputType: 'number',
+            required: false,
+            label: this.$pgettext('*/*/*/Short, Noun', 'Position'),
+            getValue: (obj) => { return obj.position }
+          },
+          {
+            id: 'copyright',
+            type: 'text',
+            required: false,
+            label: this.$pgettext('Content/Track/*/Noun', 'Copyright'),
+            getValue: (obj) => { return obj.copyright }
+          },
+          {
+            id: 'license',
+            type: 'license',
+            required: false,
+            label: this.$pgettext('Content/*/*/Noun', 'License'),
+            getValue: (obj) => { return obj.license },
+          },
+        ]
+      }
+    }
+  },
+
+  getConfig () {
+    return this.configs[this.objectType]
+  },
+
+  getCurrentState () {
+    let self = this
+    let s = {}
+    this.config.fields.forEach(f => {
+      s[f.id] = {value: f.getValue(self.object)}
+    })
+    return s
+  },
+  getCurrentStateForObj (obj, config) {
+    let s = {}
+    config.fields.forEach(f => {
+      s[f.id] = {value: f.getValue(obj)}
+    })
+    return s
+  },
+
+  getCanDelete () {
+    if (this.obj.is_applied || this.obj.is_approved) {
+      return false
+    }
+    if (!this.$store.state.auth.authenticated) {
+      return false
+    }
+    return (
+      this.obj.created_by.full_username === this.$store.state.auth.fullUsername
+      || this.$store.state.auth.availablePermissions['library']
+    )
+  },
+  getCanApprove () {
+    if (this.obj.is_applied) {
+      return false
+    }
+    if (!this.$store.state.auth.authenticated) {
+      return false
+    }
+    return this.$store.state.auth.availablePermissions['library']
+  },
+  getCanEdit () {
+    if (!this.$store.state.auth.authenticated) {
+      return false
+    }
+    return this.$store.state.auth.availablePermissions['library']
+  },
+
+}
diff --git a/front/src/filters.js b/front/src/filters.js
index 1edea76f6afb6b8f929b7ab0566b15d4f1813e75..9667426191e6fae0aa76ba9eba47dcad023730fe 100644
--- a/front/src/filters.js
+++ b/front/src/filters.js
@@ -2,13 +2,24 @@ import Vue from 'vue'
 
 import moment from 'moment'
 
-export function truncate (str, max, ellipsis) {
+export function truncate (str, max, ellipsis, middle) {
   max = max || 100
   ellipsis = ellipsis || '…'
   if (str.length <= max) {
     return str
   }
-  return str.slice(0, max) + ellipsis
+  if (middle) {
+    var sepLen = 1,
+        charsToShow = max - sepLen,
+        frontChars = Math.ceil(charsToShow/2),
+        backChars = Math.floor(charsToShow/2);
+
+    return str.substr(0, frontChars) +
+           ellipsis +
+           str.substr(str.length - backChars);
+  } else {
+    return str.slice(0, max) + ellipsis
+  }
 }
 
 Vue.filter('truncate', truncate)
diff --git a/front/src/lodash.js b/front/src/lodash.js
index 91e1a0eac30bdf5104a18913578bafcb35298fa6..8cd3ed92f41e86b0eff9b88bd5af923742b1864e 100644
--- a/front/src/lodash.js
+++ b/front/src/lodash.js
@@ -10,4 +10,6 @@ export default {
   sortBy: require('lodash/sortBy'),
   throttle: require('lodash/throttle'),
   uniq: require('lodash/uniq'),
+  remove: require('lodash/remove'),
+  reverse: require('lodash/reverse'),
 }
diff --git a/front/src/main.js b/front/src/main.js
index 9f058d8ecbef6491660647a67e815d0b5beb8f62..dd755dee356f427a58d3ceb89b6e0c5e5419d35f 100644
--- a/front/src/main.js
+++ b/front/src/main.js
@@ -4,6 +4,7 @@ import logger from '@/logging'
 
 logger.default.info('Loading environment:', process.env.NODE_ENV)
 logger.default.debug('Environment variables:', process.env)
+import jQuery from "jquery"
 
 import Vue from 'vue'
 import App from './App'
@@ -58,16 +59,13 @@ Vue.use(VueMasonryPlugin)
 Vue.use(VueLazyload)
 Vue.config.productionTip = false
 Vue.directive('title', function (el, binding) {
-  let parts = []
-  let instanceName = store.state.instance.settings.instance.name.value
-  if (instanceName.length === 0) {
-    instanceName = 'Funkwhale'
-  }
-  parts.unshift(instanceName)
-  parts.unshift(binding.value)
-  document.title = parts.join(' - ')
-  }
-)
+  store.commit('ui/pageTitle', binding.value)
+})
+Vue.directive('dropdown', function (el, binding) {
+  jQuery(el).dropdown({
+    selectOnKeydown: false,
+  })
+})
 axios.interceptors.request.use(function (config) {
   // Do something before request is sent
   if (store.state.auth.token) {
@@ -99,8 +97,11 @@ axios.interceptors.response.use(function (response) {
     if (error.response.data.detail) {
       error.backendErrors.push(error.response.data.detail)
     } else {
+      error.rawPayload = error.response.data
       for (var field in error.response.data) {
-        if (error.response.data.hasOwnProperty(field)) {
+        // some views (e.g. v1/playlists/{id}/add) have deeper nested data (e.g. data[field]
+        // is another object), so don't try to unpack non-array fields
+        if (error.response.data.hasOwnProperty(field) && error.response.data[field].forEach) {
           error.response.data[field].forEach(e => {
             error.backendErrors.push(e)
           })
diff --git a/front/src/router/index.js b/front/src/router/index.js
index 1b60a681331fe0e0c9e58691eec1b305658fb35a..182cf61b0714f6f2feecc529526b314d475ccab3 100644
--- a/front/src/router/index.js
+++ b/front/src/router/index.js
@@ -1,47 +1,5 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-import PageNotFound from '@/components/PageNotFound'
-import About from '@/components/About'
-import Home from '@/components/Home'
-import Login from '@/components/auth/Login'
-import Signup from '@/components/auth/Signup'
-import Profile from '@/components/auth/Profile'
-import Settings from '@/components/auth/Settings'
-import Logout from '@/components/auth/Logout'
-import PasswordReset from '@/views/auth/PasswordReset'
-import PasswordResetConfirm from '@/views/auth/PasswordResetConfirm'
-import EmailConfirm from '@/views/auth/EmailConfirm'
-import Library from '@/components/library/Library'
-import LibraryHome from '@/components/library/Home'
-import LibraryArtist from '@/components/library/Artist'
-import LibraryArtists from '@/components/library/Artists'
-import LibraryAlbum from '@/components/library/Album'
-import LibraryTrack from '@/components/library/Track'
-import LibraryRadios from '@/components/library/Radios'
-import RadioBuilder from '@/components/library/radios/Builder'
-import RadioDetail from '@/views/radios/Detail'
-import PlaylistDetail from '@/views/playlists/Detail'
-import PlaylistList from '@/views/playlists/List'
-import Favorites from '@/components/favorites/List'
-import AdminSettings from '@/views/admin/Settings'
-import AdminLibraryBase from '@/views/admin/library/Base'
-import AdminLibraryFilesList from '@/views/admin/library/FilesList'
-import AdminUsersBase from '@/views/admin/users/Base'
-import AdminUsersList from '@/views/admin/users/UsersList'
-import AdminInvitationsList from '@/views/admin/users/InvitationsList'
-import AdminModerationBase from '@/views/admin/moderation/Base'
-import AdminDomainsList from '@/views/admin/moderation/DomainsList'
-import AdminDomainsDetail from '@/views/admin/moderation/DomainsDetail'
-import AdminAccountsList from '@/views/admin/moderation/AccountsList'
-import AdminAccountsDetail from '@/views/admin/moderation/AccountsDetail'
-import ContentBase from '@/views/content/Base'
-import ContentHome from '@/views/content/Home'
-import LibrariesHome from '@/views/content/libraries/Home'
-import LibrariesUpload from '@/views/content/libraries/Upload'
-import LibrariesDetail from '@/views/content/libraries/Detail'
-import LibrariesFiles from '@/views/content/libraries/Files'
-import RemoteLibrariesHome from '@/views/content/remote/Home'
-import Notifications from '@/views/Notifications'
 
 Vue.use(Router)
 
@@ -52,7 +10,8 @@ export default new Router({
     {
       path: '/',
       name: 'index',
-      component: Home
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/Home"),
     },
     {
       path: '/front',
@@ -62,23 +21,27 @@ export default new Router({
     {
       path: '/about',
       name: 'about',
-      component: About
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/About"),
     },
     {
       path: '/login',
       name: 'login',
-      component: Login,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/Login"),
       props: (route) => ({ next: route.query.next || '/library' })
     },
     {
       path: '/notifications',
       name: 'notifications',
-      component: Notifications
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/Notifications"),
     },
     {
       path: '/auth/password/reset',
       name: 'auth.password-reset',
-      component: PasswordReset,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/auth/PasswordReset"),
       props: (route) => ({
         defaultEmail: route.query.email
       })
@@ -86,7 +49,8 @@ export default new Router({
     {
       path: '/auth/email/confirm',
       name: 'auth.email-confirm',
-      component: EmailConfirm,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/auth/EmailConfirm"),
       props: (route) => ({
         defaultKey: route.query.key
       })
@@ -94,16 +58,32 @@ export default new Router({
     {
       path: '/auth/password/reset/confirm',
       name: 'auth.password-reset-confirm',
-      component: PasswordResetConfirm,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/auth/PasswordResetConfirm"),
       props: (route) => ({
         defaultUid: route.query.uid,
         defaultToken: route.query.token
       })
     },
+    {
+      path: '/authorize',
+      name: 'authorize',
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/Authorize"),
+      props: (route) => ({
+        clientId: route.query.client_id,
+        redirectUri: route.query.redirect_uri,
+        scope: route.query.scope,
+        responseType: route.query.response_type,
+        nonce: route.query.nonce,
+        state: route.query.state,
+      })
+    },
     {
       path: '/signup',
       name: 'signup',
-      component: Signup,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/Signup"),
       props: (route) => ({
         defaultInvitation: route.query.invitation
       })
@@ -111,22 +91,45 @@ export default new Router({
     {
       path: '/logout',
       name: 'logout',
-      component: Logout
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/Logout"),
+
     },
     {
       path: '/settings',
       name: 'settings',
-      component: Settings
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/Settings"),
+    },
+    {
+      path: '/settings/applications/new',
+      name: 'settings.applications.new',
+      props: (route) => ({
+        scopes: route.query.scopes,
+        name: route.query.name,
+        redirect_uris: route.query.redirect_uris,
+      }),
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/ApplicationNew"),
+    },
+    {
+      path: '/settings/applications/:id/edit',
+      name: 'settings.applications.edit',
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/ApplicationEdit"),
+      props: true
     },
     {
       path: '/@:username',
       name: 'profile',
-      component: Profile,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/auth/Profile"),
       props: true
     },
     {
       path: '/favorites',
-      component: Favorites,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/favorites/List"),
       props: (route) => ({
         defaultOrdering: route.query.ordering,
         defaultPage: route.query.page,
@@ -135,23 +138,27 @@ export default new Router({
     },
     {
       path: '/content',
-      component: ContentBase,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/content/Base"),
       children: [
         {
           path: '',
           name: 'content.index',
-          component: ContentHome
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/content/Home"),
         }
       ]
     },
     {
       path: '/content/libraries/tracks',
-      component: ContentBase,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/content/Base"),
       children: [
         {
           path: '',
           name: 'content.libraries.files',
-          component: LibrariesFiles,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/content/libraries/Files"),
           props: (route) => ({
             query: route.query.q
           })
@@ -160,17 +167,20 @@ export default new Router({
     },
     {
       path: '/content/libraries',
-      component: ContentBase,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/content/Base"),
       children: [
         {
           path: '',
           name: 'content.libraries.index',
-          component: LibrariesHome
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/content/libraries/Home"),
         },
         {
           path: ':id/upload',
           name: 'content.libraries.detail.upload',
-          component: LibrariesUpload,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/content/libraries/Upload"),
           props: (route) => ({
             id: route.params.id,
             defaultImportReference: route.query.import
@@ -179,73 +189,181 @@ export default new Router({
         {
           path: ':id',
           name: 'content.libraries.detail',
-          component: LibrariesDetail,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/content/libraries/Detail"),
           props: true
         }
       ]
     },
     {
       path: '/content/remote',
-      component: ContentBase,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/views/content/Base"),
       children: [
         {
           path: '',
           name: 'content.remote.index',
-          component: RemoteLibrariesHome
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/content/remote/Home"),
         }
       ]
     },
     {
       path: '/manage/settings',
       name: 'manage.settings',
-      component: AdminSettings
+      component: () =>
+        import(/* webpackChunkName: "admin" */ "@/views/admin/Settings"),
     },
     {
       path: '/manage/library',
-      component: AdminLibraryBase,
+      component: () =>
+        import(/* webpackChunkName: "admin" */ "@/views/admin/library/Base"),
       children: [
         {
-          path: 'files',
-          name: 'manage.library.files',
-          component: AdminLibraryFilesList
-        }
+          path: 'edits',
+          name: 'manage.library.edits',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/EditsList"),
+          props: (route) => {
+            return {
+              defaultQuery: route.query.q,
+            }
+          }
+        },
+        {
+          path: 'artists',
+          name: 'manage.library.artists',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/ArtistsList"),
+          props: (route) => {
+            return {
+              defaultQuery: route.query.q,
+            }
+          }
+        },
+        {
+          path: 'artists/:id',
+          name: 'manage.library.artists.detail',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/ArtistDetail"),
+          props: true
+        },
+        {
+          path: 'albums',
+          name: 'manage.library.albums',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/AlbumsList"),
+          props: (route) => {
+            return {
+              defaultQuery: route.query.q,
+            }
+          }
+        },
+        {
+          path: 'albums/:id',
+          name: 'manage.library.albums.detail',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/AlbumDetail"),
+          props: true
+        },
+        {
+          path: 'tracks',
+          name: 'manage.library.tracks',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/TracksList"),
+          props: (route) => {
+            return {
+              defaultQuery: route.query.q,
+            }
+          }
+        },
+        {
+          path: 'tracks/:id',
+          name: 'manage.library.tracks.detail',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/TrackDetail"),
+          props: true
+        },
+        {
+          path: 'libraries',
+          name: 'manage.library.libraries',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/LibrariesList"),
+          props: (route) => {
+            return {
+              defaultQuery: route.query.q,
+            }
+          }
+        },
+        {
+          path: 'libraries/:id',
+          name: 'manage.library.libraries.detail',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/LibraryDetail"),
+          props: true
+        },
+        {
+          path: 'uploads',
+          name: 'manage.library.uploads',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/UploadsList"),
+          props: (route) => {
+            return {
+              defaultQuery: route.query.q,
+            }
+          }
+        },
+        {
+          path: 'uploads/:id',
+          name: 'manage.library.uploads.detail',
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/library/UploadDetail"),
+          props: true
+        },
       ]
     },
     {
       path: '/manage/users',
-      component: AdminUsersBase,
+      component: () =>
+        import(/* webpackChunkName: "admin" */ "@/views/admin/users/Base"),
       children: [
         {
           path: 'users',
           name: 'manage.users.users.list',
-          component: AdminUsersList
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/users/UsersList"),
         },
         {
           path: 'invitations',
           name: 'manage.users.invitations.list',
-          component: AdminInvitationsList
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/users/InvitationsList"),
         }
       ]
     },
     {
       path: '/manage/moderation',
-      component: AdminModerationBase,
+      component: () =>
+        import(/* webpackChunkName: "admin" */ "@/views/admin/moderation/Base"),
       children: [
         {
           path: 'domains',
           name: 'manage.moderation.domains.list',
-          component: AdminDomainsList
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/moderation/DomainsList"),
         },
         {
           path: 'domains/:id',
           name: 'manage.moderation.domains.detail',
-          component: AdminDomainsDetail,
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/moderation/DomainsDetail"),
           props: true
         },
         {
           path: 'accounts',
           name: 'manage.moderation.accounts.list',
-          component: AdminAccountsList,
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/moderation/AccountsList"),
           props: (route) => {
             return {
               defaultQuery: route.query.q,
@@ -256,20 +374,40 @@ export default new Router({
         {
           path: 'accounts/:id',
           name: 'manage.moderation.accounts.detail',
-          component: AdminAccountsDetail,
+          component: () =>
+            import(/* webpackChunkName: "admin" */ "@/views/admin/moderation/AccountsDetail"),
           props: true
         }
       ]
     },
     {
       path: '/library',
-      component: Library,
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/library/Library"),
       children: [
-        { path: '', component: LibraryHome, name: 'library.index' },
+        {
+          path: '',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/Home"),
+          name: 'library.index'
+        },
         {
           path: 'artists/',
           name: 'library.artists.browse',
-          component: LibraryArtists,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/Artists"),
+          props: (route) => ({
+            defaultOrdering: route.query.ordering,
+            defaultQuery: route.query.query,
+            defaultPaginateBy: route.query.paginateBy,
+            defaultPage: route.query.page
+          })
+        },
+        {
+          path: 'albums/',
+          name: 'library.albums.browse',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/Albums"),
           props: (route) => ({
             defaultOrdering: route.query.ordering,
             defaultQuery: route.query.query,
@@ -280,7 +418,8 @@ export default new Router({
         {
           path: 'radios/',
           name: 'library.radios.browse',
-          component: LibraryRadios,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/Radios"),
           props: (route) => ({
             defaultOrdering: route.query.ordering,
             defaultQuery: route.query.query,
@@ -288,13 +427,32 @@ export default new Router({
             defaultPage: route.query.page
           })
         },
-        { path: 'radios/build', name: 'library.radios.build', component: RadioBuilder, props: true },
-        { path: 'radios/build/:id', name: 'library.radios.edit', component: RadioBuilder, props: true },
-        { path: 'radios/:id', name: 'library.radios.detail', component: RadioDetail, props: true },
+        {
+          path: 'radios/build',
+          name: 'library.radios.build',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/radios/Builder"),
+          props: true
+        },
+        {
+          path: 'radios/build/:id',
+          name: 'library.radios.edit',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/radios/Builder"),
+          props: true
+        },
+        {
+          path: 'radios/:id',
+          name: 'library.radios.detail',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/radios/Detail"),
+          props: true
+        },
         {
           path: 'playlists/',
           name: 'library.playlists.browse',
-          component: PlaylistList,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/playlists/List"),
           props: (route) => ({
             defaultOrdering: route.query.ordering,
             defaultQuery: route.query.query,
@@ -305,16 +463,99 @@ export default new Router({
         {
           path: 'playlists/:id',
           name: 'library.playlists.detail',
-          component: PlaylistDetail,
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/views/playlists/Detail"),
           props: (route) => ({
             id: route.params.id,
             defaultEdit: route.query.mode === 'edit' })
         },
-        { path: 'artists/:id', name: 'library.artists.detail', component: LibraryArtist, props: true },
-        { path: 'albums/:id', name: 'library.albums.detail', component: LibraryAlbum, props: true },
-        { path: 'tracks/:id', name: 'library.tracks.detail', component: LibraryTrack, props: true },
+        {
+          path: 'artists/:id',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/ArtistBase"),
+          props: true,
+          children: [
+            {
+              path: '',
+              name: 'library.artists.detail',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/ArtistDetail"),
+            },
+            {
+              path: 'edit',
+              name: 'library.artists.edit',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/ArtistEdit"),
+            },
+            {
+              path: 'edit/:editId',
+              name: 'library.artists.edit.detail',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/EditDetail"),
+              props: true,
+            }
+          ]
+        },
+        {
+          path: 'albums/:id',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/AlbumBase"),
+          props: true,
+          children: [
+            {
+              path: '',
+              name: 'library.albums.detail',
+              component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/AlbumDetail"),
+            },
+            {
+              path: 'edit',
+              name: 'library.albums.edit',
+              component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/AlbumEdit"),
+            },
+            {
+              path: 'edit/:editId',
+              name: 'library.albums.edit.detail',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/EditDetail"),
+              props: true,
+            }
+          ]
+        },
+        {
+          path: 'tracks/:id',
+          component: () =>
+            import(/* webpackChunkName: "core" */ "@/components/library/TrackBase"),
+          props: true,
+          children: [
+            {
+              path: '',
+              name: 'library.tracks.detail',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/TrackDetail"),
+            },
+            {
+              path: 'edit',
+              name: 'library.tracks.edit',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/TrackEdit"),
+            },
+            {
+              path: 'edit/:editId',
+              name: 'library.tracks.edit.detail',
+              component: () =>
+                import(/* webpackChunkName: "core" */ "@/components/library/EditDetail"),
+              props: true,
+            }
+          ]
+        },
       ]
     },
-    { path: '*', component: PageNotFound }
+    {
+      path: '*',
+      component: () =>
+        import(/* webpackChunkName: "core" */ "@/components/PageNotFound"),
+    }
   ]
 })
diff --git a/front/src/store/auth.js b/front/src/store/auth.js
index 90cd27e9e094b62534ec1ed94c325e4a4ae8ae7e..52cc98a6de7abde1ebfb1c03bd5ea434e1fa2af8 100644
--- a/front/src/store/auth.js
+++ b/front/src/store/auth.js
@@ -8,6 +8,7 @@ export default {
   state: {
     authenticated: false,
     username: '',
+    fullUsername: '',
     availablePermissions: {
       settings: false,
       library: false,
@@ -27,6 +28,7 @@ export default {
       state.authenticated = false
       state.profile = null
       state.username = ''
+      state.fullUsername = ''
       state.token = ''
       state.tokenData = {}
       state.availablePermissions = {
@@ -43,6 +45,7 @@ export default {
       state.authenticated = value
       if (value === false) {
         state.username = null
+        state.fullUsername = null
         state.token = null
         state.tokenData = null
         state.profile = null
@@ -52,6 +55,9 @@ export default {
     username: (state, value) => {
       state.username = value
     },
+    fullUsername: (state, value) => {
+      state.fullUsername = value
+    },
     avatar: (state, value) => {
       if (state.profile) {
         state.profile.avatar = value
@@ -112,10 +118,6 @@ export default {
       }
     },
     fetchProfile ({commit, dispatch, state}) {
-      if (document) {
-        // this is to ensure we do not have any leaking cookie set by django
-        document.cookie = 'sessionid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'
-      }
 
       return new Promise((resolve, reject) => {
         axios.get('users/users/me/').then((response) => {
@@ -124,7 +126,9 @@ export default {
             resolve(response.data)
           })
           dispatch('ui/fetchUnreadNotifications', null, { root: true })
+          dispatch('ui/fetchPendingReviewEdits', null, { root: true })
           dispatch('favorites/fetch', null, { root: true })
+          dispatch('moderation/fetchContentFilters', null, { root: true })
           dispatch('playlists/fetchOwn', null, { root: true })
         }, (response) => {
           logger.default.info('Error while fetching user profile')
@@ -137,6 +141,7 @@ export default {
         commit("authenticated", true)
         commit("profile", data)
         commit("username", data.username)
+        commit("fullUsername", data.full_username)
         Object.keys(data.permissions).forEach(function(key) {
           // this makes it easier to check for permissions in templates
           commit("permission", {
diff --git a/front/src/store/index.js b/front/src/store/index.js
index 2454dd20a1497333d5a7b3416859952fdd323d32..791dbb1e92fd1d3add3509ea67575dc734c64dd8 100644
--- a/front/src/store/index.js
+++ b/front/src/store/index.js
@@ -5,6 +5,7 @@ import createPersistedState from 'vuex-persistedstate'
 import favorites from './favorites'
 import auth from './auth'
 import instance from './instance'
+import moderation from './moderation'
 import queue from './queue'
 import radios from './radios'
 import player from './player'
@@ -19,6 +20,7 @@ export default new Vuex.Store({
     auth,
     favorites,
     instance,
+    moderation,
     queue,
     radios,
     playlists,
@@ -52,8 +54,7 @@ export default new Vuex.Store({
       paths: [
         'player.looping',
         'player.volume',
-        'player.duration',
-        'player.errored'],
+        'player.duration'],
       filter: (mutation) => {
         return mutation.type.startsWith('player/') && mutation.type !== 'player/currentTime'
       }
diff --git a/front/src/store/instance.js b/front/src/store/instance.js
index d0bff7dcb217007ff662838f5f96c2fb26b009aa..6af36e8090e3ba276c7fabaf870ebd251f086a15 100644
--- a/front/src/store/instance.js
+++ b/front/src/store/instance.js
@@ -104,6 +104,7 @@ export default {
       let modules = [
         'auth',
         'favorites',
+        'moderation',
         'player',
         'playlists',
         'queue',
diff --git a/front/src/store/moderation.js b/front/src/store/moderation.js
new file mode 100644
index 0000000000000000000000000000000000000000..153f3cd5959d307d0edbf7760a4ff34d6a8eced3
--- /dev/null
+++ b/front/src/store/moderation.js
@@ -0,0 +1,93 @@
+import axios from 'axios'
+import logger from '@/logging'
+import _ from '@/lodash'
+
+export default {
+  namespaced: true,
+  state: {
+    filters: [],
+    showFilterModal: false,
+    lastUpdate: new Date(),
+    filterModalTarget: {
+      type: null,
+      target: null,
+    }
+  },
+  mutations: {
+    filterModalTarget (state, value) {
+      state.filterModalTarget = value
+    },
+    empty (state) {
+      state.filters = []
+    },
+    lastUpdate (state, value) {
+      state.lastUpdate = value
+    },
+    contentFilter (state, value) {
+      state.filters.push(value)
+    },
+    showFilterModal (state, value) {
+      state.showFilterModal = value
+      if (!value) {
+        state.filterModalTarget = {
+          type: null,
+          target: null,
+        }
+      }
+    },
+    reset (state) {
+      state.filters = []
+      state.filterModalTarget = null
+      state.showFilterModal = false
+    },
+    deleteContentFilter (state, uuid) {
+      state.filters = state.filters.filter((e) => {
+        return e.uuid != uuid
+      })
+    }
+  },
+  getters: {
+    artistFilters: (state) => () => {
+      let f = state.filters.filter((f) => {
+        return f.target.type === 'artist'
+      })
+      let p = _.sortBy(f, [(e) => { return e.creation_date }])
+      p.reverse()
+      return p
+    },
+  },
+  actions: {
+    hide ({commit}, payload) {
+      commit('filterModalTarget', payload)
+      commit('showFilterModal', true)
+    },
+    fetchContentFilters ({dispatch, state, commit, rootState}, url) {
+      let params = {}
+      let promise
+      if (url) {
+        promise = axios.get(url)
+      } else {
+          commit('empty')
+          params = {
+            page_size: 100,
+            ordering: '-creation_date'
+          }
+          promise = axios.get('moderation/content-filters/', {params: params})
+      }
+      return promise.then((response) => {
+        logger.default.info('Fetched a batch of ' + response.data.results.length + ' filters')
+        if (response.data.next) {
+          dispatch('fetchContentFilters', response.data.next)
+        }
+        response.data.results.forEach(result => {
+          commit('contentFilter', result)
+        })
+      })
+    },
+    deleteContentFilter ({commit}, uuid) {
+      return axios.delete(`moderation/content-filters/${ uuid }/`).then((response) => {
+        commit('deleteContentFilter', uuid)
+      })
+    }
+  }
+}
diff --git a/front/src/store/ui.js b/front/src/store/ui.js
index fa4624c700c73b0581d9f2d881e70f81096a2b57..8a8bc1da01854a6b630c5a3877bca91217feb524 100644
--- a/front/src/store/ui.js
+++ b/front/src/store/ui.js
@@ -12,11 +12,15 @@ export default {
     messages: [],
     notifications: {
       inbox: 0,
+      pendingReviewEdits: 0,
     },
     websocketEventsHandlers: {
       'inbox.item_added': {},
       'import.status_updated': {},
-    }
+      'mutation.created': {},
+      'mutation.updated': {},
+    },
+    pageTitle: null
   },
   mutations: {
     addWebsocketEventHandler: (state, {eventName, id, handler}) => {
@@ -44,8 +48,15 @@ export default {
     notifications (state, {type, count}) {
       state.notifications[type] = count
     },
-    incrementNotifications (state, {type, count}) {
-      state.notifications[type] = Math.max(0, state.notifications[type] + count)
+    incrementNotifications (state, {type, count, value}) {
+      if (value != undefined) {
+          state.notifications[type] = Math.max(0, value)
+      } else {
+        state.notifications[type] = Math.max(0, state.notifications[type] + count)
+      }
+    },
+    pageTitle: (state, value) => {
+      state.pageTitle = value
     }
   },
   actions: {
@@ -54,6 +65,11 @@ export default {
         commit('notifications', {type: 'inbox', count: response.data.count})
       })
     },
+    fetchPendingReviewEdits ({commit, rootState}, payload) {
+      axios.get('mutations/', {params: {is_approved: 'null', page_size: 1}}).then((response) => {
+        commit('notifications', {type: 'pendingReviewEdits', count: response.data.count})
+      })
+    },
     websocketEvent ({state}, event) {
       let handlers = state.websocketEventsHandlers[event.type]
       console.log('Dispatching websocket event', event, handlers)
diff --git a/front/src/style/_main.scss b/front/src/style/_main.scss
index 76d0372f336578f4658adf6328990accaa038932..8f8ee8b16f514dac63480f0375774166e17db18f 100644
--- a/front/src/style/_main.scss
+++ b/front/src/style/_main.scss
@@ -88,8 +88,14 @@ body {
   font-family: "Avenir", Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
+  display: flex;
+  min-height: 100vh;
+  flex-direction: column;
 }
 
+#app > main, #app > .main {
+  flex: 1;
+}
 .instance-chooser {
   margin-top: 2em;
 }
@@ -225,8 +231,15 @@ body {
   justify-content: center;
 }
 
-.segment-content .button {
-  margin: 0.5em;
+.header-buttons > .buttons {
+  display: inline-block;
+  padding: 0.2em;
+  margin: 0;
+  font-size: 1em;
+  .buttons {
+    margin: 0;
+  }
+
 }
 
 a {
@@ -296,3 +309,49 @@ canvas.color-thief {
 .ui.list .list.icon {
   padding-left: 0;
 }
+
+
+.ui.dropdown .item[disabled] {
+  display: none;
+}
+
+span.diff.added {
+  background-color:rgba(0, 255, 0, 0.25);
+}
+
+
+span.diff.removed {
+  background-color: rgba(255, 0, 0, 0.25);
+}
+
+.table-wrapper {
+  display: block;
+  overflow-x: auto;
+}
+
+td.align.right {
+  text-align: right;
+}
+
+.ui.pagination.menu {
+  margin-top: 1em;
+  + span {
+    margin-left: 1em;
+  }
+}
+
+.card .description {
+  word-wrap: break-word;
+}
+
+.ui.checkbox label {
+  cursor: pointer;
+}
+
+input + .help {
+  margin-top: 0.5em;
+}
+
+.table td .ui.dropdown {
+  min-width: 150px;
+}
diff --git a/front/src/views/Notifications.vue b/front/src/views/Notifications.vue
index 2ba075b34c32af977c2ef972b6058214088f2d64..648654c8fc1c02ede3fc86a94263bacb528f902e 100644
--- a/front/src/views/Notifications.vue
+++ b/front/src/views/Notifications.vue
@@ -2,22 +2,22 @@
   <main class="main pusher" v-title="labels.title">
     <section class="ui vertical aligned stripe segment">
       <div class="ui container">
-        <h1 class="ui header"><translate>Your notifications</translate></h1>
+        <h1 class="ui header"><translate translate-context="Content/Notifications/Title">Your notifications</translate></h1>
         <div class="ui toggle checkbox">
           <input v-model="filters.is_read" type="checkbox">
-          <label><translate>Show read notifications</translate></label>
+          <label><translate translate-context="Content/Notifications/Form.Label/Verb">Show read notifications</translate></label>
         </div>
         <div
           v-if="filters.is_read === false && notifications.count > 0"
           @click="markAllAsRead"
           class="ui basic labeled icon right floated button">
           <i class="ui check icon" />
-          <translate>Mark all as read</translate>
+          <translate translate-context="Content/Notifications/Button.Label/Verb">Mark all as read</translate>
         </div>
         <div class="ui hidden divider" />
 
         <div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
-          <div class="ui text loader"><translate>Loading notifications…</translate></div>
+          <div class="ui text loader"><translate translate-context="Content/Notifications/Paragraph">Loading notifications…</translate></div>
         </div>
 
         <table v-else-if="notifications.count > 0" class="ui table">
@@ -26,7 +26,7 @@
           </tbody>
         </table>
         <p v-else>
-          <translate>No notification to show.</translate>
+          <translate translate-context="Content/Notifications/Paragraph">No notification to show.</translate>
         </p>
       </div>
     </section>
@@ -73,7 +73,7 @@ export default {
     }),
     labels() {
       return {
-        title: this.$gettext("Notifications")
+        title: this.$pgettext('*/Notifications/*', "Notifications")
       }
     }
   },
diff --git a/front/src/views/admin/Settings.vue b/front/src/views/admin/Settings.vue
index 779bb7459bd0d9e6966370f22cdd74cc789f77f7..7102fb311b1b64fa9c63f160d026659ebe06a087 100644
--- a/front/src/views/admin/Settings.vue
+++ b/front/src/views/admin/Settings.vue
@@ -13,7 +13,7 @@
           </div>
           <div class="four wide column">
             <div class="ui sticky vertical secondary menu">
-              <div class="header item"><translate>Sections</translate></div>
+              <div class="header item"><translate translate-context="Content/Admin/Menu.Title">Sections</translate></div>
               <a :class="['menu', {active: group.id === current}, 'item']"
                 @click.prevent="scrollTo(group.id)"
                 :href="'#' + group.id"
@@ -72,19 +72,19 @@ export default {
   computed: {
     labels() {
       return {
-        settings: this.$gettext("Instance settings")
+        settings: this.$pgettext('Head/Admin/Title', 'Instance settings')
       }
     },
     groups() {
       // somehow, extraction fails if in the return block directly
-      let instanceLabel = this.$gettext("Instance information")
-      let usersLabel = this.$gettext("Users")
-      let musicLabel = this.$gettext("Music")
-      let playlistsLabel = this.$gettext("Playlists")
-      let federationLabel = this.$gettext("Federation")
-      let subsonicLabel = this.$gettext("Subsonic")
-      let statisticsLabel = this.$gettext("Statistics")
-      let errorLabel = this.$gettext("Error reporting")
+      let instanceLabel = this.$pgettext('Content/Admin/Menu','Instance information')
+      let usersLabel = this.$pgettext('*/*/*/Noun', 'Users')
+      let musicLabel = this.$pgettext('*/*/*/Noun', 'Music')
+      let playlistsLabel = this.$pgettext('*/*/*', 'Playlists')
+      let federationLabel = this.$pgettext('Content/Admin/Menu', 'Federation')
+      let subsonicLabel = this.$pgettext('Content/Admin/Menu', 'Subsonic')
+      let statisticsLabel = this.$pgettext('Content/Admin/Menu', 'Statistics')
+      let errorLabel = this.$pgettext('Content/Admin/Menu', 'Error reporting')
       return [
         {
           label: instanceLabel,
diff --git a/front/src/views/admin/library/AlbumDetail.vue b/front/src/views/admin/library/AlbumDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b89afb945d7003cef05c7a92a68c8404b4e2e1c0
--- /dev/null
+++ b/front/src/views/admin/library/AlbumDetail.vue
@@ -0,0 +1,334 @@
+<template>
+  <main>
+    <div v-if="isLoading" class="ui vertical segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object">
+      <section :class="['ui', 'head', 'vertical', 'stripe', 'segment']" v-title="object.title">
+        <div class="ui stackable one column grid">
+          <div class="ui column">
+            <div class="segment-content">
+              <h2 class="ui header">
+                <img v-if="object.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](object.cover.square_crop)">
+                <img v-else src="../../../assets/audio/default-cover.png">
+                <div class="content">
+                  {{ object.title | truncate(100) }}
+                  <div class="sub header">
+                    <template v-if="object.is_local">
+                      <span class="ui tiny teal label">
+                        <i class="home icon"></i>
+                        <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+                      </span>
+                      &nbsp;
+                    </template>
+                  </div>
+                </div>
+              </h2>
+              <div class="header-buttons">
+
+                <div class="ui icon buttons">
+                  <router-link class="ui labeled icon button" :to="{name: 'library.albums.detail', params: {id: object.id }}">
+                    <i class="info icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate>&nbsp;
+                  </router-link>
+                  <div class="ui floating dropdown icon button" v-dropdown>
+                    <i class="dropdown icon"></i>
+                    <div class="menu">
+                      <a
+                        v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                        class="basic item"
+                        :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/album/${object.id}`)"
+                        target="_blank" rel="noopener noreferrer">
+                        <i class="wrench icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                      </a>
+                      <a class="basic item" v-if="object.mbid" :href="`https://musicbrainz.org/release/${object.mbid}`" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open on MusicBrainz</translate>&nbsp;
+                      </a>
+                      <fetch-button @refresh="fetchData" v-if="!object.is_local" class="basic item" :url="`albums/${object.id}/fetches/`">
+                        <i class="refresh icon"></i>&nbsp;
+                        <translate translate-context="Content/Moderation/Button/Verb">Refresh from remote server</translate>&nbsp;
+                      </fetch-button>
+                      <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate>&nbsp;
+                      </a>
+                    </div>
+                  </div>
+                </div>
+                <div class="ui buttons">
+                  <router-link
+                    v-if="object.is_local"
+                    :to="{name: 'library.albums.edit', params: {id: object.id }}"
+                    class="ui labeled icon button">
+                    <i class="edit icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
+                  </router-link>
+                </div>
+                <div class="ui buttons">
+                  <dangerous-button
+                    :class="['ui', {loading: isLoading}, 'basic button']"
+                    :action="remove">
+                    <translate translate-context="*/*/*/Verb">Delete</translate>
+                    <p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this album?</translate></p>
+                    <div slot="modal-content">
+                      <p><translate translate-context="Content/Moderation/Paragraph">The album will be removed, as well as associated uploads, tracks, favorites and listening history. This action is irreversible.</translate></p>
+                    </div>
+                    <p slot="modal-confirm"><translate translate-context="*/*/*/Verb">Delete</translate></p>
+                  </dangerous-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <div class="ui vertical stripe segment">
+        <div class="ui stackable three column grid">
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="info icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Album data</translate>
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Title</translate>
+                    </td>
+                    <td>
+                      {{ object.title }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.artists.detail', params: {id: object.artist.id }}">
+                        <translate translate-context="*/*/*/Noun">Artist</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.artist.name }}
+                    </td>
+                  </tr>
+                  <tr v-if="!object.is_local">
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
+                        <translate translate-context="Content/Moderation/*/Noun">Domain</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.domain }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="feed icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Listenings</translate>
+                    </td>
+                    <td>
+                      {{ stats.listenings }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*">Favorited tracks</translate>
+                    </td>
+                    <td>
+                      {{ stats.track_favorites }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*">Playlists</translate>
+                    </td>
+                    <td>
+                      {{ stats.playlists }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'album ' + object.id)}}">
+                        <translate translate-context="*/Admin/*/Noun">Edits</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.mutations }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="music icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_downloaded_size | humanSize }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label">Total size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_total_size | humanSize }}
+                    </td>
+                  </tr>
+
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('album_id', object.id) }}">
+                        <translate translate-context="*/*/*/Noun">Libraries</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.libraries }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('album_id', object.id) }}">
+                        <translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.uploads }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('album_id', object.id) }}">
+                        <translate translate-context="*/*/*">Tracks</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.tracks.length }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+
+            </section>
+          </div>
+        </div>
+      </div>
+
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+import FetchButton from "@/components/federation/FetchButton"
+
+
+export default {
+  props: ["id"],
+  components: {
+    FetchButton
+  },
+  data() {
+    return {
+      isLoading: true,
+      isLoadingStats: false,
+      object: null,
+      stats: null,
+    }
+  },
+  created() {
+    this.fetchData()
+    this.fetchStats()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/albums/${this.id}/`
+      axios.get(url).then(response => {
+        self.object = response.data
+        self.isLoading = false
+      })
+    },
+    fetchStats() {
+      var self = this
+      this.isLoadingStats = true
+      let url = `manage/library/albums/${this.id}/stats/`
+      axios.get(url).then(response => {
+        self.stats = response.data
+        self.isLoadingStats = false
+      })
+    },
+    remove () {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/albums/${this.id}/`
+      axios.delete(url).then(response => {
+        self.$router.push({name: 'manage.library.albums'})
+      })
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        statsWarning: this.$pgettext('Content/Moderation/Help text', 'Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object'),
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/AlbumsList.vue b/front/src/views/admin/library/AlbumsList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..650b4d69389aadd05ae8fd2e7a385ed02c2a5945
--- /dev/null
+++ b/front/src/views/admin/library/AlbumsList.vue
@@ -0,0 +1,29 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <h2 class="ui header">{{ labels.title }}</h2>
+      <div class="ui hidden divider"></div>
+      <albums-table :update-url="true" :default-query="defaultQuery"></albums-table>
+    </section>
+  </main>
+</template>
+
+<script>
+import AlbumsTable from "@/components/manage/library/AlbumsTable"
+
+export default {
+  components: {
+    AlbumsTable
+  },
+  props: {
+    defaultQuery: {type: String, required: false},
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Albums')
+      }
+    }
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/ArtistDetail.vue b/front/src/views/admin/library/ArtistDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..0c4175bae4a84a68bb1f526deafd1af2fce42cea
--- /dev/null
+++ b/front/src/views/admin/library/ArtistDetail.vue
@@ -0,0 +1,333 @@
+<template>
+  <main>
+    <div v-if="isLoading" class="ui vertical segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object">
+      <section :class="['ui', 'head', 'vertical', 'stripe', 'segment']" v-title="object.name">
+        <div class="ui stackable one column grid">
+          <div class="ui column">
+            <div class="segment-content">
+              <h2 class="ui header">
+                <i class="circular inverted user icon"></i>
+                <div class="content">
+                  {{ object.name | truncate(100) }}
+                  <div class="sub header">
+                    <template v-if="object.is_local">
+                      <span class="ui tiny teal label">
+                        <i class="home icon"></i>
+                        <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+                      </span>
+                      &nbsp;
+                    </template>
+                  </div>
+                </div>
+              </h2>
+              <div class="header-buttons">
+
+                <div class="ui icon buttons">
+                  <router-link class="ui labeled icon button" :to="{name: 'library.artists.detail', params: {id: object.id }}">
+                    <i class="info icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate>&nbsp;
+                  </router-link>
+                  <div class="ui floating dropdown icon button" v-dropdown>
+                    <i class="dropdown icon"></i>
+                    <div class="menu">
+                      <a
+                        v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                        class="basic item"
+                        :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/artist/${object.id}`)"
+                        target="_blank" rel="noopener noreferrer">
+                        <i class="wrench icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                      </a>
+                      <a class="basic item" v-if="object.mbid" :href="`https://musicbrainz.org/artist/${object.mbid}`" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open on MusicBrainz</translate>&nbsp;
+                      </a>
+                      <fetch-button @refresh="fetchData" v-if="!object.is_local" class="basic item" :url="`artists/${object.id}/fetches/`">
+                        <i class="refresh icon"></i>&nbsp;
+                        <translate translate-context="Content/Moderation/Button/Verb">Refresh from remote server</translate>&nbsp;
+                      </fetch-button>
+                      <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate>&nbsp;
+                      </a>
+                    </div>
+                  </div>
+                </div>
+                <div class="ui buttons">
+                  <router-link
+                    v-if="object.is_local"
+                    :to="{name: 'library.artists.edit', params: {id: object.id }}"
+                    class="ui labeled icon button">
+                    <i class="edit icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
+                  </router-link>
+                </div>
+                <div class="ui buttons">
+                  <dangerous-button
+                    :class="['ui', {loading: isLoading}, 'basic button']"
+                    :action="remove">
+                    <translate translate-context="*/*/*/Verb">Delete</translate>
+                    <p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this artist?</translate></p>
+                    <div slot="modal-content">
+                      <p><translate translate-context="Content/Moderation/Paragraph">The artist will be removed, as well as associated uploads, tracks, albums, favorites and listening history. This action is irreversible.</translate></p>
+                    </div>
+                    <p slot="modal-confirm"><translate translate-context="*/*/*/Verb">Delete</translate></p>
+                  </dangerous-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <div class="ui vertical stripe segment">
+        <div class="ui stackable three column grid">
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="info icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Artist data</translate>
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Name</translate>
+                    </td>
+                    <td>
+                      {{ object.name }}
+                    </td>
+                  </tr>
+                  <tr v-if="!object.is_local">
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
+                        <translate translate-context="Content/Moderation/*/Noun">Domain</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.domain }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="feed icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Listenings</translate>
+                    </td>
+                    <td>
+                      {{ stats.listenings }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*">Favorited tracks</translate>
+                    </td>
+                    <td>
+                      {{ stats.track_favorites }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*">Playlists</translate>
+                    </td>
+                    <td>
+                      {{ stats.playlists }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'artist ' + object.id)}}">
+                        <translate translate-context="*/Admin/*/Noun">Edits</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.mutations }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="music icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_downloaded_size | humanSize }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label">Total size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_total_size | humanSize }}
+                    </td>
+                  </tr>
+
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('artist_id', object.id) }}">
+                        <translate translate-context="*/*/*/Noun">Libraries</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.libraries }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('artist_id', object.id) }}">
+                        <translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.uploads }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.albums', query: {q: getQuery('artist_id', object.id) }}">
+                        <translate translate-context="*/*/*">Albums</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.albums.length }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('artist_id', object.id) }}">
+                        <translate translate-context="*/*/*">Tracks</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.tracks.length }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+
+            </section>
+          </div>
+        </div>
+      </div>
+
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+
+import FetchButton from "@/components/federation/FetchButton"
+
+export default {
+  props: ["id"],
+  components: {
+    FetchButton
+  },
+  data() {
+    return {
+      isLoading: true,
+      isLoadingStats: false,
+      object: null,
+      stats: null,
+    }
+  },
+  created() {
+    this.fetchData()
+    this.fetchStats()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/artists/${this.id}/`
+      axios.get(url).then(response => {
+        self.object = response.data
+        self.isLoading = false
+      })
+    },
+    fetchStats() {
+      var self = this
+      this.isLoadingStats = true
+      let url = `manage/library/artists/${this.id}/stats/`
+      axios.get(url).then(response => {
+        self.stats = response.data
+        self.isLoadingStats = false
+      })
+    },
+    remove () {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/artists/${this.id}/`
+      axios.delete(url).then(response => {
+        self.$router.push({name: 'manage.library.artists'})
+      })
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        statsWarning: this.$pgettext('Content/Moderation/Help text', 'Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object'),
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/ArtistsList.vue b/front/src/views/admin/library/ArtistsList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2a5932796ec6003703942ee1fe6e7e31f4d532c9
--- /dev/null
+++ b/front/src/views/admin/library/ArtistsList.vue
@@ -0,0 +1,29 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <h2 class="ui header">{{ labels.title }}</h2>
+      <div class="ui hidden divider"></div>
+      <artists-table :update-url="true" :default-query="defaultQuery"></artists-table>
+    </section>
+  </main>
+</template>
+
+<script>
+import ArtistsTable from "@/components/manage/library/ArtistsTable"
+
+export default {
+  components: {
+    ArtistsTable
+  },
+  props: {
+    defaultQuery: {type: String, required: false},
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Artists')
+      }
+    }
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/Base.vue b/front/src/views/admin/library/Base.vue
index 45d257606b403769d865560749cf31a0700e0d09..009e1ca95c9f8bc615c73c37f808887b14949711 100644
--- a/front/src/views/admin/library/Base.vue
+++ b/front/src/views/admin/library/Base.vue
@@ -3,7 +3,22 @@
     <nav class="ui secondary pointing menu" role="navigation" :aria-label="labels.secondaryMenu">
       <router-link
         class="ui item"
-        :to="{name: 'manage.library.files'}"><translate>Files</translate></router-link>
+        :to="{name: 'manage.library.edits'}"><translate translate-context="*/Admin/*/Noun">Edits</translate></router-link>
+      <router-link
+        class="ui item"
+        :to="{name: 'manage.library.artists'}"><translate translate-context="*/*/*">Artists</translate></router-link>
+      <router-link
+        class="ui item"
+        :to="{name: 'manage.library.albums'}"><translate translate-context="*/*/*">Albums</translate></router-link>
+      <router-link
+        class="ui item"
+        :to="{name: 'manage.library.tracks'}"><translate translate-context="*/*/*">Tracks</translate></router-link>
+      <router-link
+        class="ui item"
+        :to="{name: 'manage.library.libraries'}"><translate translate-context="*/*/*">Libraries</translate></router-link>
+      <router-link
+        class="ui item"
+        :to="{name: 'manage.library.uploads'}"><translate translate-context="*/*/*">Uploads</translate></router-link>
     </nav>
     <router-view :key="$route.fullPath"></router-view>
   </div>
@@ -13,8 +28,8 @@
 export default {
   computed: {
     labels() {
-      let title = this.$gettext("Manage library")
-      let secondaryMenu = this.$gettext("Secondary menu")
+      let title = this.$pgettext('Head/Admin/Title', 'Manage library')
+      let secondaryMenu = this.$pgettext('Menu/*/Hidden text', 'Secondary menu')
       return {
         title,
         secondaryMenu
diff --git a/front/src/views/admin/library/EditsList.vue b/front/src/views/admin/library/EditsList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..ec1ddb15e7e09374bb7c0d1622dad41814e3850e
--- /dev/null
+++ b/front/src/views/admin/library/EditsList.vue
@@ -0,0 +1,33 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <edits-card-list :update-url="true" :default-query="defaultQuery">
+        <h2 class="ui header"><translate translate-context="Content/Admin/Title/Noun">Library edits</translate></h2>
+      </edits-card-list>
+    </section>
+  </main>
+</template>
+
+<script>
+import EditsCardList from "@/components/manage/library/EditsCardList"
+
+export default {
+  props: {
+    defaultQuery: {type: String, required: false},
+  },
+  components: {
+    EditsCardList
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/Admin/*/Noun', 'Edits')
+      }
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/front/src/views/admin/library/FilesList.vue b/front/src/views/admin/library/FilesList.vue
deleted file mode 100644
index 3557879bb29acb14a704a6c5113cf243ca0a4edc..0000000000000000000000000000000000000000
--- a/front/src/views/admin/library/FilesList.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-<template>
-  <main v-title="labels.title">
-    <section class="ui vertical stripe segment">
-      <h2 class="ui header"><translate>Library files</translate></h2>
-      <div class="ui hidden divider"></div>
-      <library-files-table :show-library="true"></library-files-table>
-    </section>
-  </main>
-</template>
-
-<script>
-import LibraryFilesTable from "@/components/manage/library/FilesTable"
-
-export default {
-  components: {
-    LibraryFilesTable
-  },
-  computed: {
-    labels() {
-      return {
-        title: this.$gettext("Files")
-      }
-    }
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-</style>
diff --git a/front/src/views/admin/library/LibrariesList.vue b/front/src/views/admin/library/LibrariesList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..495a660c19609fde101fff87b2774f6ca7890c3c
--- /dev/null
+++ b/front/src/views/admin/library/LibrariesList.vue
@@ -0,0 +1,29 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <h2 class="ui header">{{ labels.title }}</h2>
+      <div class="ui hidden divider"></div>
+      <libraries-table :update-url="true" :default-query="defaultQuery"></libraries-table>
+    </section>
+  </main>
+</template>
+
+<script>
+import LibrariesTable from "@/components/manage/library/LibrariesTable"
+
+export default {
+  components: {
+    LibrariesTable
+  },
+  props: {
+    defaultQuery: {type: String, required: false},
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Libraries')
+      }
+    }
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/LibraryDetail.vue b/front/src/views/admin/library/LibraryDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..beec7e2b408cf6b032c5f0114c979d77f958a64c
--- /dev/null
+++ b/front/src/views/admin/library/LibraryDetail.vue
@@ -0,0 +1,321 @@
+<template>
+  <main>
+    <div v-if="isLoading" class="ui vertical segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object">
+      <section :class="['ui', 'head', 'vertical', 'stripe', 'segment']" v-title="object.name">
+        <div class="ui stackable one column grid">
+          <div class="ui column">
+            <div class="segment-content">
+              <h2 class="ui header">
+                <i class="circular inverted book icon"></i>
+                <div class="content">
+                  {{ object.name | truncate(100) }}
+                  <div class="sub header">
+                    <template v-if="object.is_local">
+                      <span class="ui tiny teal label">
+                        <i class="home icon"></i>
+                        <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+                      </span>
+                      &nbsp;
+                    </template>
+                  </div>
+                </div>
+              </h2>
+              <div class="header-buttons">
+
+                <div class="ui icon buttons">
+                  <a
+                    v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="ui labeled icon button"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/library/${object.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                  <div class="ui floating dropdown icon button" v-dropdown>
+                    <i class="dropdown icon"></i>
+                    <div class="menu">
+                      <a
+                        v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                        class="basic item"
+                        :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/library/${object.id}`)"
+                        target="_blank" rel="noopener noreferrer">
+                        <i class="wrench icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                      </a>
+                      <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate>&nbsp;
+                      </a>
+                    </div>
+                  </div>
+                </div>
+                <div class="ui buttons">
+                  <dangerous-button
+                    :class="['ui', {loading: isLoading}, 'basic button']"
+                    :action="remove">
+                    <translate translate-context="*/*/*/Verb">Delete</translate>
+                    <p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this library?</translate></p>
+                    <div slot="modal-content">
+                      <p><translate translate-context="Content/Moderation/Paragraph">The library will be removed, as well as associated uploads, and follows. This action is irreversible.</translate></p>
+                    </div>
+                    <p slot="modal-confirm"><translate translate-context="*/*/*/Verb">Delete</translate></p>
+                  </dangerous-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <div class="ui vertical stripe segment">
+        <div class="ui stackable three column grid">
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="info icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Library data</translate>
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Name</translate>
+                    </td>
+                    <td>
+                      {{ object.name }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('privacy_level', object.privacy_level) }}">
+                        <translate translate-context="*/*/*">Visibility</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ sharedLabels.fields.privacy_level.shortChoices[object.privacy_level] }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: object.actor.full_username }}">
+                        <translate translate-context="*/*/*/Noun">Account</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.actor.preferred_username }}
+                    </td>
+                  </tr>
+                  <tr v-if="!object.is_local">
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
+                        <translate translate-context="Content/Moderation/*/Noun">Domain</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.domain }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Description</translate>
+                    </td>
+                    <td>
+                      {{ object.description }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="feed icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Federation/*/Noun">Followers</translate>
+                    </td>
+                    <td>
+                      {{ stats.followers }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="music icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_downloaded_size | humanSize }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label">Total size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_total_size | humanSize }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.artists', query: {q: getQuery('library_id', object.id) }}">
+                        <translate translate-context="*/*/*">Artists</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.artists }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.albums', query: {q: getQuery('library_id', object.id) }}">
+                        <translate translate-context="*/*/*">Albums</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.albums }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('library_id', object.id) }}">
+                        <translate translate-context="*/*/*">Tracks</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.tracks }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('library_id', object.id) }}">
+                        <translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.uploads }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+
+            </section>
+          </div>
+        </div>
+      </div>
+
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+import TranslationsMixin from "@/components/mixins/Translations"
+
+
+export default {
+  props: ["id"],
+  mixins: [
+    TranslationsMixin
+  ],
+  data() {
+    return {
+      isLoading: true,
+      isLoadingStats: false,
+      object: null,
+      stats: null,
+    }
+  },
+  created() {
+    this.fetchData()
+    this.fetchStats()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/libraries/${this.id}/`
+      axios.get(url).then(response => {
+        self.object = response.data
+        self.isLoading = false
+      })
+    },
+    fetchStats() {
+      var self = this
+      this.isLoadingStats = true
+      let url = `manage/library/libraries/${this.id}/stats/`
+      axios.get(url).then(response => {
+        self.stats = response.data
+        self.isLoadingStats = false
+      })
+    },
+    remove () {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/libraries/${this.id}/`
+      axios.delete(url).then(response => {
+        self.$router.push({name: 'manage.library.libraries'})
+      })
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        statsWarning: this.$pgettext('Content/Moderation/Help text', 'Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object'),
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/TrackDetail.vue b/front/src/views/admin/library/TrackDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..29cd29810ee619bf96be7ac499b6a5f6d3d5cbcb
--- /dev/null
+++ b/front/src/views/admin/library/TrackDetail.vue
@@ -0,0 +1,376 @@
+<template>
+  <main>
+    <div v-if="isLoading" class="ui vertical segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object">
+      <section :class="['ui', 'head', 'vertical', 'stripe', 'segment']" v-title="object.title">
+        <div class="ui stackable one column grid">
+          <div class="ui column">
+            <div class="segment-content">
+              <h2 class="ui header">
+                <i class="circular inverted user icon"></i>
+                <div class="content">
+                  {{ object.title | truncate(100) }}
+                  <div class="sub header">
+                    <template v-if="object.is_local">
+                      <span class="ui tiny teal label">
+                        <i class="home icon"></i>
+                        <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+                      </span>
+                      &nbsp;
+                    </template>
+                  </div>
+                </div>
+              </h2>
+              <div class="header-buttons">
+
+                <div class="ui icon buttons">
+                  <router-link class="ui icon labeled button" :to="{name: 'library.tracks.detail', params: {id: object.id }}">
+                    <i class="info icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate>&nbsp;
+                  </router-link>
+                  <div class="ui floating dropdown icon button" v-dropdown>
+                    <i class="dropdown icon"></i>
+                    <div class="menu">
+                      <a
+                        v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                        class="basic item"
+                        :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/track/${object.id}`)"
+                        target="_blank" rel="noopener noreferrer">
+                        <i class="wrench icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                      </a>
+                      <a class="basic item" v-if="object.mbid" :href="`https://musicbrainz.org/recording/${object.mbid}`" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open on MusicBrainz</translate>&nbsp;
+                      </a>
+                      <fetch-button @refresh="fetchData" v-if="!object.is_local" class="basic item" :url="`tracks/${object.id}/fetches/`">
+                        <i class="refresh icon"></i>&nbsp;
+                        <translate translate-context="Content/Moderation/Button/Verb">Refresh from remote server</translate>&nbsp;
+                      </fetch-button>
+                      <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate>&nbsp;
+                      </a>
+                    </div>
+                  </div>
+                </div>
+                <div class="ui buttons">
+                  <router-link
+                    v-if="object.is_local"
+                    :to="{name: 'library.tracks.edit', params: {id: object.id }}"
+                    class="ui labeled icon button">
+                    <i class="edit icon"></i>
+                    <translate translate-context="Content/*/Button.Label/Verb">Edit</translate>
+                  </router-link>
+                </div>
+                <div class="ui buttons">
+                  <dangerous-button
+                    :class="['ui', {loading: isLoading}, 'basic button']"
+                    :action="remove">
+                    <translate translate-context="*/*/*/Verb">Delete</translate>
+                    <p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this album?</translate></p>
+                    <div slot="modal-content">
+                      <p><translate translate-context="Content/Moderation/Paragraph">The track will be removed, as well as associated uploads, favorites and listening history. This action is irreversible.</translate></p>
+                    </div>
+                    <p slot="modal-confirm"><translate translate-context="*/*/*/Verb">Delete</translate></p>
+                  </dangerous-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <div class="ui vertical stripe segment">
+        <div class="ui stackable three column grid">
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="info icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Track data</translate>
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Title</translate>
+                    </td>
+                    <td>
+                      {{ object.title }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.albums.detail', params: {id: object.album.id }}">
+                        <translate translate-context="*/*/*/Noun">Album</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.album.title }}
+                    </td>
+                  </tr>
+
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.artists.detail', params: {id: object.artist.id }}">
+                        <translate translate-context="*/*/*/Noun">Artist</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.artist.name }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.artists.detail', params: {id: object.album.artist.id }}">
+                        <translate translate-context="*/*/*/Noun">Album artist</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.album.artist.name }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Position</translate>
+                    </td>
+                    <td>
+                      {{ object.position }}
+                    </td>
+                  </tr>
+                  <tr v-if="object.disc_number">
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Disc number</translate>
+                    </td>
+                    <td>
+                      {{ object.disc_number }}
+                    </td>
+                  </tr>
+                  <tr v-if="object.copyright">
+                    <td>
+                      <translate translate-context="Content/Track/Table.Label/Noun">Copyright</translate>
+                    </td>
+                    <td>{{ object.copyright }}</td>
+                  </tr>
+                  <tr v-if="object.license">
+                    <td>
+                      <translate translate-context="Content/*/*/Noun">License</translate>
+                    </td>
+                    <td>
+                      <router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('license', object.license)}}">
+                        {{ object.license }}
+                      </router-link>
+                    </td>
+                  </tr>
+                  <tr v-if="!object.is_local">
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
+                        <translate translate-context="Content/Moderation/*/Noun">Domain</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.domain }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="feed icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Listenings</translate>
+                    </td>
+                    <td>
+                      {{ stats.listenings }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*">Favorited tracks</translate>
+                    </td>
+                    <td>
+                      {{ stats.track_favorites }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*">Playlists</translate>
+                    </td>
+                    <td>
+                      {{ stats.playlists }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.edits', query: {q: getQuery('target', 'track ' + object.id)}}">
+                        <translate translate-context="*/Admin/*/Noun">Edits</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.mutations }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="music icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
+                  <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
+
+                </div>
+              </h3>
+              <div v-if="isLoadingStats" class="ui placeholder">
+                <div class="full line"></div>
+                <div class="short line"></div>
+                <div class="medium line"></div>
+                <div class="long line"></div>
+              </div>
+              <table v-else class="ui very basic table">
+                <tbody>
+
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_downloaded_size | humanSize }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label">Total size</translate>
+                    </td>
+                    <td>
+                      {{ stats.media_total_size | humanSize }}
+                    </td>
+                  </tr>
+
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('track_id', object.id) }}">
+                        <translate translate-context="*/*/*/Noun">Libraries</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.libraries }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('track_id', object.id) }}">
+                        <translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ stats.uploads }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+
+            </section>
+          </div>
+        </div>
+      </div>
+
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+import FetchButton from "@/components/federation/FetchButton"
+
+
+export default {
+  props: ["id"],
+  components: {
+    FetchButton
+  },
+  data() {
+    return {
+      isLoading: true,
+      isLoadingStats: false,
+      object: null,
+      stats: null,
+    }
+  },
+  created() {
+    this.fetchData()
+    this.fetchStats()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/tracks/${this.id}/`
+      axios.get(url).then(response => {
+        self.object = response.data
+        self.isLoading = false
+      })
+    },
+    fetchStats() {
+      var self = this
+      this.isLoadingStats = true
+      let url = `manage/library/tracks/${this.id}/stats/`
+      axios.get(url).then(response => {
+        self.stats = response.data
+        self.isLoadingStats = false
+      })
+    },
+    remove () {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/tracks/${this.id}/`
+      axios.delete(url).then(response => {
+        self.$router.push({name: 'manage.library.tracks'})
+      })
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        statsWarning: this.$pgettext('Content/Moderation/Help text', 'Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object'),
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/TracksList.vue b/front/src/views/admin/library/TracksList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3aefc86060af1a12aa006136f49c224f27b2b7af
--- /dev/null
+++ b/front/src/views/admin/library/TracksList.vue
@@ -0,0 +1,29 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <h2 class="ui header">{{ labels.title }}</h2>
+      <div class="ui hidden divider"></div>
+      <tracks-table :update-url="true" :default-query="defaultQuery"></tracks-table>
+    </section>
+  </main>
+</template>
+
+<script>
+import TracksTable from "@/components/manage/library/TracksTable"
+
+export default {
+  components: {
+    TracksTable
+  },
+  props: {
+    defaultQuery: {type: String, required: false},
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Tracks')
+      }
+    }
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/UploadDetail.vue b/front/src/views/admin/library/UploadDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..4dbd83793c5b52374d174417265eae7b5cabcf4b
--- /dev/null
+++ b/front/src/views/admin/library/UploadDetail.vue
@@ -0,0 +1,340 @@
+<template>
+  <main>
+    <div v-if="isLoading" class="ui vertical segment">
+      <div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
+    </div>
+    <template v-if="object">
+      <import-status-modal :upload="object" :show.sync="showUploadDetailModal" />
+      <section :class="['ui', 'head', 'vertical', 'stripe', 'segment']" v-title="displayName(object)">
+        <div class="ui stackable one column grid">
+          <div class="ui column">
+            <div class="segment-content">
+              <h2 class="ui header">
+                <i class="circular inverted file icon"></i>
+                <div class="content">
+                  {{ displayName(object) | truncate(100) }}
+                  <div class="sub header">
+                    <template v-if="object.is_local">
+                      <span class="ui tiny teal label">
+                        <i class="home icon"></i>
+                        <translate translate-context="Content/Moderation/*/Short, Noun">Local</translate>
+                      </span>
+                      &nbsp;
+                    </template>
+                  </div>
+                </div>
+              </h2>
+              <div class="header-buttons">
+
+                <div class="ui icon buttons">
+                  <a
+                    v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="ui labeled icon button"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/upload/${object.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                  <div class="ui floating dropdown icon button" v-dropdown>
+                    <i class="dropdown icon"></i>
+                    <div class="menu">
+                      <a
+                        v-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                        class="basic item"
+                        :href="$store.getters['instance/absoluteUrl'](`/api/admin/music/upload/${object.id}`)"
+                        target="_blank" rel="noopener noreferrer">
+                        <i class="wrench icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                      </a>
+                      <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate>&nbsp;
+                      </a>
+                    </div>
+                  </div>
+                </div>
+                <div class="ui buttons">
+                  <a class="ui labeled icon button" v-if="object.audio_file" :href="$store.getters['instance/absoluteUrl'](object.audio_file)" target="_blank" rel="noopener noreferrer">
+                    <i class="download icon"></i>
+                    <translate translate-context="Content/Track/Link/Verb">Download</translate>
+                  </a>
+                </div>
+                <div class="ui buttons">
+                  <dangerous-button
+                    :class="['ui', {loading: isLoading}, 'basic button']"
+                    :action="remove">
+                    <translate translate-context="*/*/*/Verb">Delete</translate>
+                    <p slot="modal-header"><translate translate-context="Popup/Library/Title">Delete this upload?</translate></p>
+                    <div slot="modal-content">
+                      <p><translate translate-context="Content/Moderation/Paragraph">The upload will be removed. This action is irreversible.</translate></p>
+                    </div>
+                    <p slot="modal-confirm"><translate translate-context="*/*/*/Verb">Delete</translate></p>
+                  </dangerous-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <div class="ui vertical stripe segment">
+        <div class="ui stackable three column grid">
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="info icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Upload data</translate>
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="*/*/*/Noun">Name</translate>
+                    </td>
+                    <td>
+                      {{ displayName(object) }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('privacy_level', object.library.privacy_level) }}">
+                        <translate translate-context="*/*/*">Visibility</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ sharedLabels.fields.privacy_level.shortChoices[object.library.privacy_level] }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.accounts.detail', params: {id: object.library.actor.full_username }}">
+                        <translate translate-context="*/*/*/Noun">Account</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.library.actor.preferred_username }}
+                    </td>
+                  </tr>
+                  <tr v-if="!object.is_local">
+                    <td>
+                      <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
+                        <translate translate-context="Content/Moderation/*/Noun">Domain</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.domain }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('status', object.import_status) }}">
+                        <translate translate-context="Content/*/*/Noun">Import status</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ sharedLabels.fields.import_status.choices[object.import_status].label }}
+                      <button class="ui tiny basic icon button" :title="sharedLabels.fields.import_status.detailTitle" @click="detailedUpload = object; showUploadDetailModal = true">
+                        <i class="question circle outline icon"></i>
+                      </button>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.libraries.detail', params: {id: object.library.uuid }}">
+                        <translate translate-context="*/*/*">Library</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.library.name }}
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="feed icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/*/*/Noun">Accessed date</translate>
+                    </td>
+                    <td>
+                      <human-date v-if="object.accessed_date" :date="object.accessed_date"></human-date>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+          <div class="column">
+            <section>
+              <h3 class="ui header">
+                <i class="music icon"></i>
+                <div class="content">
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
+                </div>
+              </h3>
+              <table class="ui very basic table">
+                <tbody>
+                  <tr v-if="object.track">
+                    <td>
+                      <router-link :to="{name: 'manage.library.tracks.detail', params: {id: object.track.id }}">
+                        <translate translate-context="*/*/*">Track</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      {{ object.track.title }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
+                    </td>
+                    <td>
+                      <template v-if="object.audio_file">
+                        {{ object.size | humanSize }}
+                      </template>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/*/*/Noun">Size</translate>
+                    </td>
+                    <td>
+                      {{ object.size | humanSize }}
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Track/*/Noun">Bitrate</translate>
+                    </td>
+                    <td>
+                      <template v-if="object.bitrate">
+                        {{ object.bitrate | humanSize }}/s
+                      </template>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/*/*">Duration</translate>
+                    </td>
+                    <td>
+                      <template v-if="object.duration">
+                        {{ time.parse(object.duration) }}
+                      </template>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
+                    </td>
+                  </tr>
+                  <tr>
+                    <td>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('type', object.mimetype) }}">
+                        <translate translate-context="Content/Track/Table.Label/Noun">Type</translate>
+                      </router-link>
+                    </td>
+                    <td>
+                      <template v-if="object.mimetype">
+                        {{ object.mimetype }}
+                      </template>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </section>
+          </div>
+        </div>
+      </div>
+
+    </template>
+  </main>
+</template>
+
+<script>
+import axios from "axios"
+import logger from "@/logging"
+import TranslationsMixin from "@/components/mixins/Translations"
+import ImportStatusModal from '@/components/library/ImportStatusModal'
+import time from '@/utils/time'
+
+
+export default {
+  props: ["id"],
+  mixins: [
+    TranslationsMixin,
+  ],
+  components: {
+    ImportStatusModal
+  },
+  data() {
+    return {
+      time,
+      detailedUpload: null,
+      showUploadDetailModal: false,
+      isLoading: true,
+      object: null,
+      stats: null,
+    }
+  },
+  created() {
+    this.fetchData()
+  },
+  methods: {
+    fetchData() {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/uploads/${this.id}/`
+      axios.get(url).then(response => {
+        self.object = response.data
+        self.isLoading = false
+      })
+    },
+    remove () {
+      var self = this
+      this.isLoading = true
+      let url = `manage/library/uploads/${this.id}/`
+      axios.delete(url).then(response => {
+        self.$router.push({name: 'manage.library.uploads'})
+      })
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
+    },
+    displayName (upload) {
+      if (upload.filename) {
+        return upload.filename
+      }
+      if (upload.source) {
+        return upload.source
+      }
+      return upload.uuid
+    }
+  },
+  computed: {
+    labels() {
+      return {
+        statsWarning: this.$pgettext('Content/Moderation/Help text', 'Statistics are computed from known activity and content on your instance, and do not reflect general activity for this object'),
+      }
+    },
+  }
+}
+</script>
diff --git a/front/src/views/admin/library/UploadsList.vue b/front/src/views/admin/library/UploadsList.vue
new file mode 100644
index 0000000000000000000000000000000000000000..0d4d7b5e3c2975914ebbb05f3a5d3e26e044cd6a
--- /dev/null
+++ b/front/src/views/admin/library/UploadsList.vue
@@ -0,0 +1,29 @@
+<template>
+  <main v-title="labels.title">
+    <section class="ui vertical stripe segment">
+      <h2 class="ui header">{{ labels.title }}</h2>
+      <div class="ui hidden divider"></div>
+      <uploads-table :update-url="true" :default-query="defaultQuery"></uploads-table>
+    </section>
+  </main>
+</template>
+
+<script>
+import UploadsTable from "@/components/manage/library/UploadsTable"
+
+export default {
+  components: {
+    UploadsTable
+  },
+  props: {
+    defaultQuery: {type: String, required: false},
+  },
+  computed: {
+    labels() {
+      return {
+        title: this.$pgettext('*/*/*', 'Uploads')
+      }
+    }
+  }
+}
+</script>
diff --git a/front/src/views/admin/moderation/AccountsDetail.vue b/front/src/views/admin/moderation/AccountsDetail.vue
index 5a339db5656e7e453fcabbafd9c9af20ca6eb3b8..09b5bb8244faf339fd08a20e31068bf7e4a8cdb7 100644
--- a/front/src/views/admin/moderation/AccountsDetail.vue
+++ b/front/src/views/admin/moderation/AccountsDetail.vue
@@ -14,19 +14,48 @@
                   {{ object.full_username }}
                   <div class="sub header">
                     <template v-if="object.user">
-                      <span class="ui tiny teal icon label">
+                      <span class="ui tiny teal label">
                         <i class="home icon"></i>
-                        <translate>Local account</translate>
+                        <translate translate-context="Content/Moderation/*/Short, Noun">Local account</translate>
                       </span>
                       &nbsp;
                     </template>
                     <a :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
-                      <translate>Open profile</translate>&nbsp;
+                      <translate translate-context="Content/Moderation/Link/Verb">Open profile</translate>&nbsp;
                       <i class="external icon"></i>
                     </a>
                   </div>
                 </div>
               </h2>
+              <div class="header-buttons">
+                <div class="ui icon buttons">
+                  <a
+                    v-if="object.user && $store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="ui labeled icon button"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/users/user/${object.user.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                  <a
+                    v-else-if="$store.state.auth.profile && $store.state.auth.profile.is_superuser"
+                    class="ui labeled icon button"
+                    :href="$store.getters['instance/absoluteUrl'](`/api/admin/federation/actor/${object.id}`)"
+                    target="_blank" rel="noopener noreferrer">
+                    <i class="wrench icon"></i>
+                    <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate>&nbsp;
+                  </a>
+                  <div class="ui floating dropdown icon button" v-dropdown>
+                    <i class="dropdown icon"></i>
+                    <div class="menu">
+                      <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer">
+                        <i class="external icon"></i>
+                        <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate>&nbsp;
+                      </a>
+                    </div>
+                  </div>
+                </div>
+              </div>
             </div>
           </div>
           <div class="ui column">
@@ -44,16 +73,16 @@
                 <header class="ui header">
                   <h3>
                     <i class="shield icon"></i>
-                    <translate>You don't have any rule in place for this account.</translate>
+                    <translate translate-context="Content/Moderation/Card.Title">You don't have any rule in place for this account.</translate>
                   </h3>
                 </header>
-                <p><translate>Moderation policies help you control how your instance interact with a given domain or account.</translate></p>
-                <button @click="showPolicyForm = true" class="ui primary button">Add a moderation policy</button>
+                <p><translate translate-context="Content/Moderation/Card.Paragraph">Moderation policies help you control how your instance interact with a given domain or account.</translate></p>
+                <button @click="showPolicyForm = true" class="ui primary button"><translate translate-context="Content/Moderation/Button/Verb">Add a moderation policy</translate></button>
               </template>
               <instance-policy-card v-else-if="policy && !showPolicyForm" :object="policy" @update="showPolicyForm = true">
                 <header class="ui header">
                   <h3>
-                    <translate>This domain is subject to specific moderation rules</translate>
+                    <translate translate-context="Content/Moderation/Card.Title">This domain is subject to specific moderation rules</translate>
                   </h3>
                 </header>
               </instance-policy-card>
@@ -76,32 +105,32 @@
               <h3 class="ui header">
                 <i class="info icon"></i>
                 <div class="content">
-                  <translate>Account data</translate>
+                  <translate translate-context="Content/Moderation/Title">Account data</translate>
                 </div>
               </h3>
               <table class="ui very basic table">
                 <tbody>
                   <tr>
                     <td>
-                      <translate>Username</translate>
+                      <translate translate-context="Content/*/*">Username</translate>
                     </td>
                     <td>
                       {{ object.preferred_username }}
                     </td>
                   </tr>
                   <tr v-if="!object.user">
-                    <td>
-                      <translate>Domain</translate>
-                    </td>
                     <td>
                       <router-link :to="{name: 'manage.moderation.domains.detail', params: {id: object.domain }}">
-                        {{ object.domain }}
+                        <translate translate-context="Content/Moderation/*/Noun">Domain</translate>
                       </router-link>
                     </td>
+                    <td>
+                      {{ object.domain }}
+                    </td>
                   </tr>
                   <tr>
                     <td>
-                      <translate>Display name</translate>
+                      <translate translate-context="'Content/*/*/Noun'">Display name</translate>
                     </td>
                     <td>
                       {{ object.name }}
@@ -109,7 +138,7 @@
                   </tr>
                   <tr v-if="object.user">
                     <td>
-                      <translate>Email address</translate>
+                      <translate translate-context="Content/*/*">Email address</translate>
                     </td>
                     <td>
                       {{ object.user.email }}
@@ -117,7 +146,7 @@
                   </tr>
                   <tr v-if="object.user">
                     <td>
-                      <translate>Login status</translate>
+                      <translate translate-context="Content/*/*/Noun">Login status</translate>
                     </td>
                     <td>
                       <div class="ui toggle checkbox" v-if="object.user.username != $store.state.auth.profile.username">
@@ -125,17 +154,17 @@
                           @change="updateUser('is_active')"
                           v-model="object.user.is_active" type="checkbox">
                         <label>
-                          <translate v-if="object.user.is_active" key="1">Enabled</translate>
-                          <translate v-else key="2">Disabled</translate>
+                          <translate v-if="object.user.is_active" key="1" translate-context="*/*/*">Enabled</translate>
+                          <translate v-else key="2" translate-context="*/*/*">Disabled</translate>
                         </label>
                       </div>
-                      <translate v-else-if="object.user.is_active" key="1">Enabled</translate>
-                      <translate v-else key="2">Disabled</translate>
+                      <translate v-else-if="object.user.is_active" key="1" translate-context="*/*/*">Enabled</translate>
+                      <translate v-else key="2" translate-context="*/*/*">Disabled</translate>
                     </td>
                   </tr>
                   <tr v-if="object.user">
                     <td>
-                      <translate>Permissions</translate>
+                      <translate translate-context="Content/Admin/Table.Label/Noun">Permissions</translate>
                     </td>
                     <td>
                       <select
@@ -149,7 +178,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Type</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Type</translate>
                     </td>
                     <td>
                       {{ object.type }}
@@ -157,24 +186,16 @@
                   </tr>
                   <tr v-if="!object.user">
                     <td>
-                      <translate>First seen</translate>
-                    </td>
-                    <td>
-                      <human-date :date="object.creation_date"></human-date>
-                    </td>
-                  </tr>
-                  <tr v-if="!object.user">
-                    <td>
-                      <translate>Last checked</translate>
+                      <translate translate-context="Content/*/Table.Label">Last checked</translate>
                     </td>
                     <td>
                       <human-date v-if="object.last_fetch_date" :date="object.last_fetch_date"></human-date>
-                      <translate v-else>N/A</translate>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
                     </td>
                   </tr>
                   <tr v-if="object.user">
                     <td>
-                      <translate>Sign-up date</translate>
+                      <translate translate-context="Content/Admin/Table.Label/Noun">Sign-up date</translate>
                     </td>
                     <td>
                       <human-date :date="object.user.date_joined"></human-date>
@@ -182,7 +203,7 @@
                   </tr>
                   <tr v-if="object.user">
                     <td>
-                      <translate>Last activity</translate>
+                      <translate translate-context="Content/Profile/Table.Label/Short, Noun (Value is a date)">Last activity</translate>
                     </td>
                     <td>
                       <human-date :date="object.user.last_activity"></human-date>
@@ -197,7 +218,7 @@
               <h3 class="ui header">
                 <i class="feed icon"></i>
                 <div class="content">
-                  <translate>Activity</translate>&nbsp;
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
                   <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
 
                 </div>
@@ -210,9 +231,17 @@
               </div>
               <table v-else class="ui very basic table">
                 <tbody>
+                  <tr v-if="!object.user">
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
                   <tr>
                     <td>
-                      <translate>Emitted messages</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Emitted messages</translate>
                     </td>
                     <td>
                       {{ stats.outbox_activities}}
@@ -220,7 +249,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Received library follows</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Received library follows</translate>
                     </td>
                     <td>
                       {{ stats.received_library_follows}}
@@ -228,7 +257,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Emitted library follows</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Emitted library follows</translate>
                     </td>
                     <td>
                       {{ stats.emitted_library_follows}}
@@ -243,7 +272,7 @@
               <h3 class="ui header">
                 <i class="music icon"></i>
                 <div class="content">
-                  <translate>Audio content</translate>&nbsp;
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
                   <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
 
                 </div>
@@ -259,7 +288,7 @@
 
                   <tr v-if="!object.user">
                     <td>
-                      <translate>Cached size</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
                     </td>
                     <td>
                       {{ stats.media_downloaded_size | humanSize }}
@@ -267,26 +296,26 @@
                   </tr>
                   <tr v-if="object.user">
                     <td>
-                      <translate>Upload quota</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun" >Upload quota</translate>
                       <span :data-tooltip="labels.uploadQuota"><i class="question circle icon"></i></span>
                     </td>
                     <td>
                       <div class="ui right labeled input">
                         <input
-                          class="ui input"
                           @change="updateUser('upload_quota', true)"
                           v-model.number="object.user.upload_quota"
                           step="100"
+                          name="quota"
                           type="number" />
                         <div class="ui basic label">
-                          <translate>MB</translate>
+                          <translate translate-context="Content/*/*/Unit">MB</translate>
                         </div>
                       </div>
                     </td>
                   </tr>
                   <tr>
                     <td>
-                      <translate>Total size</translate>
+                      <translate translate-context="Content/Moderation/Table.Label">Total size</translate>
                     </td>
                     <td>
                       {{ stats.media_total_size | humanSize }}
@@ -295,7 +324,9 @@
 
                   <tr>
                     <td>
-                      <translate>Libraries</translate>
+                      <router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('account', object.full_username) }}">
+                        <translate translate-context="*/*/*/Noun">Libraries</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.libraries }}
@@ -303,7 +334,9 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Uploads</translate>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('account', object.full_username) }}">
+                        <translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.uploads }}
@@ -311,7 +344,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Artists</translate>
+                      <translate translate-context="*/*/*/Noun">Artists</translate>
                     </td>
                     <td>
                       {{ stats.artists }}
@@ -319,7 +352,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Albums</translate>
+                      <translate translate-context="*/*/*">Albums</translate>
                     </td>
                     <td>
                       {{ stats.albums}}
@@ -327,7 +360,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Tracks</translate>
+                      <translate translate-context="*/*/*/Noun">Tracks</translate>
                     </td>
                     <td>
                       {{ stats.tracks }}
@@ -446,30 +479,31 @@ export default {
           )
         }
       )
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
     }
   },
   computed: {
     labels() {
       return {
-        statsWarning: this.$gettext("Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account"),
-        uploadQuota: this.$gettext(
-          "Determine how much content the user can upload. Leave empty to use the default value of the instance."
-        ),
+        statsWarning: this.$pgettext('Content/Moderation/Help text', 'Statistics are computed from known activity and content on your instance, and do not reflect general activity for this account'),
+        uploadQuota: this.$pgettext('Content/Moderation/Help text', 'Determine how much content the user can upload. Leave empty to use the default value of the instance.'),
       }
     },
     allPermissions() {
       return [
         {
           code: "library",
-          label: this.$gettext("Library")
+          label: this.$pgettext('*/*/*', "Library")
         },
         {
           code: "moderation",
-          label: this.$gettext("Moderation")
+          label: this.$pgettext('*/Moderation/*', "Moderation")
         },
         {
           code: "settings",
-          label: this.$gettext("Settings")
+          label: this.$pgettext('*/*/*/Noun', "Settings")
         }
       ]
     }
@@ -489,4 +523,7 @@ export default {
 .placeholder.segment {
   width: 100%;
 }
+.ui.input input[name="quota"] {
+  max-width: 7em;
+}
 </style>
diff --git a/front/src/views/admin/moderation/AccountsList.vue b/front/src/views/admin/moderation/AccountsList.vue
index 877c96c5ee548615fdfb4720c07a4e6b5c8af211..1505619f5754cb5c1af761475d0f6688a9e2f2f5 100644
--- a/front/src/views/admin/moderation/AccountsList.vue
+++ b/front/src/views/admin/moderation/AccountsList.vue
@@ -1,7 +1,7 @@
 <template>
   <main v-title="labels.accounts">
     <section class="ui vertical stripe segment">
-      <h2 class="ui header"><translate>Accounts</translate></h2>
+      <h2 class="ui header"><translate translate-context="*/Moderation/Title">Accounts</translate></h2>
       <div class="ui hidden divider"></div>
       <accounts-table :update-url="true" :default-query="defaultQuery"></accounts-table>
     </section>
@@ -21,7 +21,7 @@ export default {
   computed: {
     labels() {
       return {
-        accounts: this.$gettext("Accounts")
+        accounts: this.$pgettext('*/Moderation/Title', "Accounts")
       }
     }
   }
diff --git a/front/src/views/admin/moderation/Base.vue b/front/src/views/admin/moderation/Base.vue
index e0bf6c1adcd41f3df44526fde5bcbf8ecbb9ce4a..564debf79ae8f7dcc42abe94e073511de237f1ac 100644
--- a/front/src/views/admin/moderation/Base.vue
+++ b/front/src/views/admin/moderation/Base.vue
@@ -3,10 +3,10 @@
     <nav class="ui secondary pointing menu" role="navigation" :aria-label="labels.secondaryMenu">
       <router-link
         class="ui item"
-        :to="{name: 'manage.moderation.domains.list'}"><translate>Domains</translate></router-link>
+        :to="{name: 'manage.moderation.domains.list'}"><translate translate-context="*/Moderation/*/Noun">Domains</translate></router-link>
       <router-link
         class="ui item"
-        :to="{name: 'manage.moderation.accounts.list'}"><translate>Accounts</translate></router-link>
+        :to="{name: 'manage.moderation.accounts.list'}"><translate translate-context="*/Moderation/Title">Accounts</translate></router-link>
 
     </nav>
     <router-view :key="$route.fullPath"></router-view>
@@ -18,8 +18,8 @@ export default {
   computed: {
     labels() {
       return {
-        moderation: this.$gettext("Moderation"),
-        secondaryMenu: this.$gettext("Secondary menu")
+        moderation: this.$pgettext('*/Moderation/*', "Moderation"),
+        secondaryMenu: this.$pgettext('Menu/*/Hidden text', "Secondary menu")
       }
     }
   }
diff --git a/front/src/views/admin/moderation/DomainsDetail.vue b/front/src/views/admin/moderation/DomainsDetail.vue
index f5f9643c8a0eddcf65098d6076ddffc9fe99aa13..575b15f93ca2bbf696b9672cbb38e7535c8b09ab 100644
--- a/front/src/views/admin/moderation/DomainsDetail.vue
+++ b/front/src/views/admin/moderation/DomainsDetail.vue
@@ -14,7 +14,7 @@
                   {{ object.name }}
                   <div class="sub header">
                     <a :href="externalUrl" target="_blank" rel="noopener noreferrer" class="logo-wrapper">
-                      <translate>Open website</translate>&nbsp;
+                      <translate translate-context="Content/Moderation/Link/Verb">Open website</translate>&nbsp;
                       <i class="external icon"></i>
                     </a>
                   </div>
@@ -37,16 +37,16 @@
                 <header class="ui header">
                   <h3>
                     <i class="shield icon"></i>
-                    <translate>You don't have any rule in place for this domain.</translate>
+                    <translate translate-context="Content/Moderation/Card.Title">You don't have any rule in place for this domain.</translate>
                   </h3>
                 </header>
-                <p><translate>Moderation policies help you control how your instance interact with a given domain or account.</translate></p>
+                <p><translate translate-context="Content/Moderation/Card.Paragraph">Moderation policies help you control how your instance interact with a given domain or account.</translate></p>
                 <button @click="showPolicyForm = true" class="ui primary button">Add a moderation policy</button>
               </template>
               <instance-policy-card v-else-if="policy && !showPolicyForm" :object="policy" @update="showPolicyForm = true">
                 <header class="ui header">
                   <h3>
-                    <translate>This domain is subject to specific moderation rules</translate>
+                    <translate translate-context="Content/Moderation/Card.Title">This domain is subject to specific moderation rules</translate>
                   </h3>
                 </header>
               </instance-policy-card>
@@ -69,62 +69,54 @@
               <h3 class="ui header">
                 <i class="info icon"></i>
                 <div class="content">
-                  <translate>Instance data</translate>
+                  <translate translate-context="Content/Moderation/Title">Instance data</translate>
                 </div>
               </h3>
               <table class="ui very basic table">
                 <tbody>
                   <tr>
                     <td>
-                      <translate>First seen</translate>
-                    </td>
-                    <td>
-                      <human-date :date="object.creation_date"></human-date>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td>
-                      <translate>Last checked</translate>
+                      <translate translate-context="Content/*/Table.Label">Last checked</translate>
                     </td>
                     <td>
                       <human-date v-if="object.nodeinfo_fetch_date" :date="object.nodeinfo_fetch_date"></human-date>
-                      <translate v-else>N/A</translate>
+                      <translate v-else translate-context="*/*/*">N/A</translate>
                     </td>
                   </tr>
 
                   <template v-if="object.nodeinfo && object.nodeinfo.status === 'ok'">
                     <tr>
                       <td>
-                        <translate>Software</translate>
+                        <translate translate-context="Content/Moderation/Table.Label">Software</translate>
                       </td>
                       <td>
-                        {{ lodash.get(object, 'nodeinfo.payload.software.name', $gettext('N/A')) }} ({{ lodash.get(object, 'nodeinfo.payload.software.version', $gettext('N/A')) }})
+                        {{ lodash.get(object, 'nodeinfo.payload.software.name', $pgettext('*/*/*', 'N/A')) }} ({{ lodash.get(object, 'nodeinfo.payload.software.version', $pgettext('*/*/*', 'N/A')) }})
                       </td>
                     </tr>
                     <tr>
                       <td>
-                        <translate>Name</translate>
+                        <translate translate-context="*/*/*/Noun">Name</translate>
                       </td>
                       <td>
-                        {{ lodash.get(object, 'nodeinfo.payload.metadata.nodeName', $gettext('N/A')) }}
+                        {{ lodash.get(object, 'nodeinfo.payload.metadata.nodeName', $pgettext('*/*/*', 'N/A')) }}
                       </td>
                     </tr>
                     <tr>
                       <td>
-                        <translate>Total users</translate>
+                        <translate translate-context="Content/*/*">Total users</translate>
                       </td>
                       <td>
-                        {{ lodash.get(object, 'nodeinfo.payload.usage.users.total', $gettext('N/A')) }}
+                        {{ lodash.get(object, 'nodeinfo.payload.usage.users.total', $pgettext('*/*/*', 'N/A')) }}
                       </td>
                     </tr>
                   </template>
                   <template v-if="object.nodeinfo && object.nodeinfo.status === 'error'">
                     <tr>
                       <td>
-                        <translate>Status</translate>
+                        <translate translate-context="Content/Moderation/Table.Label (Value is Error message)">Status</translate>
                       </td>
                       <td>
-                        <translate>Error while fetching node info</translate>&nbsp;
+                        <translate translate-context="Content/Moderation/Table">Error while fetching node info</translate>&nbsp;
 
                         <span :data-tooltip="object.nodeinfo.error"><i class="question circle icon"></i></span>
                       </td>
@@ -133,7 +125,7 @@
                 </tbody>
               </table>
               <ajax-button @action-done="refreshNodeInfo" method="get" :url="'manage/federation/domains/' + object.name + '/nodeinfo/'">
-                <translate>Refresh node info</translate>
+                <translate translate-context="Content/Moderation/Button.Label/Verb">Refresh node info</translate>
               </ajax-button>
             </section>
           </div>
@@ -142,7 +134,7 @@
               <h3 class="ui header">
                 <i class="feed icon"></i>
                 <div class="content">
-                  <translate>Activity</translate>&nbsp;
+                  <translate translate-context="Content/Moderation/Title">Activity</translate>&nbsp;
                   <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
 
                 </div>
@@ -155,11 +147,19 @@
               </div>
               <table v-else class="ui very basic table">
                 <tbody>
+                  <tr>
+                    <td>
+                      <translate translate-context="Content/Moderation/Table.Label/Short (Value is a date)">First seen</translate>
+                    </td>
+                    <td>
+                      <human-date :date="object.creation_date"></human-date>
+                    </td>
+                  </tr>
                   <tr>
                     <td>
                       <router-link
                         :to="{name: 'manage.moderation.accounts.list', query: {q: 'domain:' + object.name }}">
-                        <translate>Known accounts</translate>
+                        <translate translate-context="Content/Moderation/Table.Label.Link">Known accounts</translate>
                         </router-link>
 
                     </td>
@@ -169,7 +169,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Emitted messages</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Emitted messages</translate>
                     </td>
                     <td>
                       {{ stats.outbox_activities}}
@@ -177,7 +177,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Received library follows</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Received library follows</translate>
                     </td>
                     <td>
                       {{ stats.received_library_follows}}
@@ -185,7 +185,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Emitted library follows</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Emitted library follows</translate>
                     </td>
                     <td>
                       {{ stats.emitted_library_follows}}
@@ -200,7 +200,7 @@
               <h3 class="ui header">
                 <i class="music icon"></i>
                 <div class="content">
-                  <translate>Audio content</translate>&nbsp;
+                  <translate translate-context="Content/Moderation/Title">Audio content</translate>&nbsp;
                   <span :data-tooltip="labels.statsWarning"><i class="question circle icon"></i></span>
 
                 </div>
@@ -215,7 +215,7 @@
                 <tbody>
                   <tr>
                     <td>
-                      <translate>Cached size</translate>
+                      <translate translate-context="Content/Moderation/Table.Label/Noun">Cached size</translate>
                     </td>
                     <td>
                       {{ stats.media_downloaded_size | humanSize }}
@@ -223,7 +223,7 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Total size</translate>
+                      <translate translate-context="Content/Moderation/Table.Label">Total size</translate>
                     </td>
                     <td>
                       {{ stats.media_total_size | humanSize }}
@@ -231,7 +231,9 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Libraries</translate>
+                      <router-link :to="{name: 'manage.library.libraries', query: {q: getQuery('domain', object.name) }}">
+                        <translate translate-context="*/*/*/Noun">Libraries</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.libraries }}
@@ -239,7 +241,9 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Uploads</translate>
+                      <router-link :to="{name: 'manage.library.uploads', query: {q: getQuery('domain', object.name) }}">
+                        <translate translate-context="Content/Moderation/Table.Label/Noun">Uploads</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.uploads }}
@@ -247,7 +251,9 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Artists</translate>
+                      <router-link :to="{name: 'manage.library.artists', query: {q: getQuery('domain', object.name) }}">
+                        <translate translate-context="*/*/*/Noun">Artists</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.artists }}
@@ -255,7 +261,9 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Albums</translate>
+                      <router-link :to="{name: 'manage.library.albums', query: {q: getQuery('domain', object.name) }}">
+                        <translate translate-context="*/*/*">Albums</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.albums}}
@@ -263,7 +271,9 @@
                   </tr>
                   <tr>
                     <td>
-                      <translate>Tracks</translate>
+                      <router-link :to="{name: 'manage.library.tracks', query: {q: getQuery('domain', object.name) }}">
+                        <translate translate-context="*/*/*/Noun">Tracks</translate>
+                      </router-link>
                     </td>
                     <td>
                       {{ stats.tracks }}
@@ -350,12 +360,15 @@ export default {
     updatePolicy (policy) {
       this.policy = policy
       this.showPolicyForm = false
+    },
+    getQuery (field, value) {
+      return `${field}:"${value}"`
     }
   },
   computed: {
     labels() {
       return {
-        statsWarning: this.$gettext("Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain")
+        statsWarning: this.$pgettext('Content/Moderation/Help text', "Statistics are computed from known activity and content on your instance, and do not reflect general activity for this domain")
       }
     },
     externalUrl () {
diff --git a/front/src/views/admin/moderation/DomainsList.vue b/front/src/views/admin/moderation/DomainsList.vue
index 8872c2cdcc1372f5348dd1ae95d2d96dc177ee52..3ce8e6afc44a2e653bc5ecb88a6837c3d80181d9 100644
--- a/front/src/views/admin/moderation/DomainsList.vue
+++ b/front/src/views/admin/moderation/DomainsList.vue
@@ -1,22 +1,22 @@
 <template>
   <main v-title="labels.domains">
     <section class="ui vertical stripe segment">
-      <h2 class="ui left floated header"><translate>Domains</translate></h2>
+      <h2 class="ui left floated header"><translate translate-context="*/Moderation/*/Noun">Domains</translate></h2>
       <form class="ui right floated form" @submit.prevent="createDomain">
         <div v-if="errors && errors.length > 0" class="ui negative message">
-          <div class="header"><translate>Error while creating domain</translate></div>
+          <div class="header"><translate translate-context="Content/Moderation/Message.Title">Error while creating domain</translate></div>
           <ul class="list">
             <li v-for="error in errors">{{ error }}</li>
           </ul>
         </div>
         <div class="inline fields">
           <div class="field">
-            <label for="domain"><translate>Add a domain</translate></label>
+            <label for="domain"><translate translate-context="Content/Moderation/Form.Label/Verb">Add a domain</translate></label>
             <input type="text" name="domain" id="domain" v-model="domainName">
           </div>
           <div class="field">
             <button :class="['ui', {'loading': isCreating}, 'green', 'button']" type="submit" :disabled="isCreating">
-              <label for="domain"><translate>Add</translate></label>
+              <label for="domain"><translate translate-context="Content/Moderation/Button/Verb">Add</translate></label>
             </button>
           </div>
         </div>
@@ -45,7 +45,7 @@ export default {
   computed: {
     labels() {
       return {
-        domains: this.$gettext("Domains")
+        domains: this.$pgettext('*/Moderation/*/Noun', "Domains")
       }
     }
   },
diff --git a/front/src/views/admin/users/Base.vue b/front/src/views/admin/users/Base.vue
index 41110fb3c39c4ab5459182377f185fb9b6506f30..84d70bebb6cbc5c9afbaebbd3b6e0c25d90dd38d 100644
--- a/front/src/views/admin/users/Base.vue
+++ b/front/src/views/admin/users/Base.vue
@@ -3,10 +3,10 @@
     <nav class="ui secondary pointing menu" role="navigation" :aria-label="labels.secondaryMenu">
       <router-link
         class="ui item"
-        :to="{name: 'manage.users.users.list'}"><translate>Users</translate></router-link>
+        :to="{name: 'manage.users.users.list'}"><translate translate-context="*/*/*/Noun">Users</translate></router-link>
       <router-link
         class="ui item"
-        :to="{name: 'manage.users.invitations.list'}"><translate>Invitations</translate></router-link>
+        :to="{name: 'manage.users.invitations.list'}"><translate translate-context="*/Admin/*/Noun">Invitations</translate></router-link>
     </nav>
     <router-view :key="$route.fullPath"></router-view>
   </div>
@@ -17,8 +17,8 @@ export default {
   computed: {
     labels() {
       return {
-        manageUsers: this.$gettext("Manage users"),
-        secondaryMenu: this.$gettext("Secondary menu")
+        manageUsers: this.$pgettext('Head/Admin/Title', 'Manage users'),
+        secondaryMenu: this.$pgettext('Menu/*/Hidden text','Secondary menu')
       }
     }
   }
diff --git a/front/src/views/admin/users/InvitationsList.vue b/front/src/views/admin/users/InvitationsList.vue
index 04da76f8588af789a63fc7f8deacf2e0ff069bbc..5071dc6618f30149e90e6ad81614390bc8054a0f 100644
--- a/front/src/views/admin/users/InvitationsList.vue
+++ b/front/src/views/admin/users/InvitationsList.vue
@@ -1,7 +1,7 @@
 <template>
   <main v-title="labels.invitations">
     <section class="ui vertical stripe segment">
-      <h2 class="ui header"><translate>Invitations</translate></h2>
+      <h2 class="ui header">{{ labels.invitations }}</h2>
       <invitation-form></invitation-form>
       <div class="ui hidden divider"></div>
       <invitations-table></invitations-table>
@@ -21,7 +21,7 @@ export default {
   computed: {
     labels() {
       return {
-        invitations: this.$gettext("Invitations")
+        invitations: this.$pgettext('*/Admin/*/Noun', 'Invitations')
       }
     }
   }
diff --git a/front/src/views/admin/users/UsersList.vue b/front/src/views/admin/users/UsersList.vue
index c0ee4166cd1fd976738a1315b4bce9aa35e512c1..781a2e2d11bd500a2324c80d8afb2fd8405160d3 100644
--- a/front/src/views/admin/users/UsersList.vue
+++ b/front/src/views/admin/users/UsersList.vue
@@ -1,7 +1,7 @@
 <template>
   <main v-title="labels.users">
     <section class="ui vertical stripe segment">
-      <h2 class="ui header"><translate>Users</translate></h2>
+      <h2 class="ui header">{{ labels.users }}</h2>
       <div class="ui hidden divider"></div>
       <users-table></users-table>
     </section>
@@ -18,7 +18,7 @@ export default {
   computed: {
     labels() {
       return {
-        users: this.$gettext("Users")
+        users: this.$pgettext('*/*/*/Noun', 'Users')
       }
     }
   }
diff --git a/front/src/views/auth/EmailConfirm.vue b/front/src/views/auth/EmailConfirm.vue
index fd509272d813594fa153c6d0f25856dd94191a28..466a13c9fa899b15816c077882a3b524880342fe 100644
--- a/front/src/views/auth/EmailConfirm.vue
+++ b/front/src/views/auth/EmailConfirm.vue
@@ -2,29 +2,29 @@
   <main class="main pusher" v-title="labels.confirm">
     <section class="ui vertical stripe segment">
       <div class="ui small text container">
-        <h2><translate>Confirm your e-mail address</translate></h2>
+        <h2>{{ labels.confirm }}</h2>
         <form v-if="!success" class="ui form" @submit.prevent="submit()">
           <div v-if="errors.length > 0" class="ui negative message">
-            <div class="header"><translate>Could not confirm your e-mail address</translate></div>
+            <div class="header"><translate translate-context="Content/Signup/Paragraph">Could not confirm your e-mail address</translate></div>
             <ul class="list">
               <li v-for="error in errors">{{ error }}</li>
             </ul>
           </div>
           <div class="field">
-            <label><translate>Confirmation code</translate></label>
+            <label><translate translate-context="Content/Signup/Form.Label">Confirmation code</translate></label>
             <input name="confirmation-code" type="text" required v-model="key" />
           </div>
           <router-link :to="{path: '/login'}">
-            <translate>Return to login</translate>
+            <translate translate-context="Content/Signup/Link/Verb">Return to login</translate>
           </router-link>
           <button :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']" type="submit">
-            <translate>Confirm your e-mail address</translate></button>
+            {{ labels.confirm }}</button>
         </form>
         <div v-else class="ui positive message">
-          <div class="header"><translate>E-mail address confirmed</translate></div>
-          <p><translate>You can now use the service without limitations.</translate></p>
+          <div class="header"><translate translate-context="Content/Signup/Message">E-mail address confirmed</translate></div>
+          <p><translate translate-context="Content/Signup/Paragraph">You can now use the service without limitations.</translate></p>
           <router-link :to="{name: 'login'}">
-            <translate>Proceed to login</translate>
+            <translate translate-context="Content/Signup/Link/Verb">Proceed to login</translate>
           </router-link>
         </div>
       </div>
@@ -48,7 +48,7 @@ export default {
   computed: {
     labels() {
       return {
-        confirm: this.$gettext("Confirm your e-mail address")
+        confirm: this.$pgettext('Head/Signup/Title', "Confirm your e-mail address")
       }
     }
   },
diff --git a/front/src/views/auth/PasswordReset.vue b/front/src/views/auth/PasswordReset.vue
index 7940c170f0fcd427e3edcdbcc69c9d6b013696ed..b1aab6f855699955419f0cd29df95fb6d18fbce9 100644
--- a/front/src/views/auth/PasswordReset.vue
+++ b/front/src/views/auth/PasswordReset.vue
@@ -2,17 +2,17 @@
   <main class="main pusher" v-title="labels.reset">
     <section class="ui vertical stripe segment">
       <div class="ui small text container">
-        <h2><translate>Reset your password</translate></h2>
+        <h2><translate translate-context="*/Login/*/Verb">Reset your password</translate></h2>
         <form class="ui form" @submit.prevent="submit()">
           <div v-if="errors.length > 0" class="ui negative message">
-            <div class="header"><translate>Error while asking for a password reset</translate></div>
+            <div class="header"><translate translate-context="Content/Signup/Card.Title">Error while asking for a password reset</translate></div>
             <ul class="list">
               <li v-for="error in errors">{{ error }}</li>
             </ul>
           </div>
-          <p><translate>Use this form to request a password reset. We will send an email to the given address with instructions to reset your password.</translate></p>
+          <p><translate translate-context="Content/Signup/Paragraph">Use this form to request a password reset. We will send an email to the given address with instructions to reset your password.</translate></p>
           <div class="field">
-            <label><translate>Account's email</translate></label>
+            <label><translate translate-context="Content/Signup/Input.Label">Account's email</translate></label>
             <input
               required
               ref="email"
@@ -23,10 +23,10 @@
               v-model="email">
           </div>
           <router-link :to="{path: '/login'}">
-            <translate>Back to login</translate>
+            <translate translate-context="Content/Signup/Link">Back to login</translate>
           </router-link>
           <button :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']" type="submit">
-            <translate>Ask for a password reset</translate></button>
+            <translate translate-context="Content/Signup/Button.Label/Verb">Ask for a password reset</translate></button>
         </form>
       </div>
     </section>
@@ -50,9 +50,8 @@ export default {
   },
   computed: {
     labels() {
-      let reset = this.$gettext("Reset your password")
-      let placeholder = this.$gettext(
-        "Input the email address binded to your account"
+      let reset = this.$pgettext('*/Login/*/Verb', "Reset your password")
+      let placeholder = this.$pgettext('Content/Signup/Input.Placeholder', "Enter the email address binded to your account"
       )
       return {
         reset,
diff --git a/front/src/views/auth/PasswordResetConfirm.vue b/front/src/views/auth/PasswordResetConfirm.vue
index df0589beb8d13d909bcefaefe4268fef91bacbaf..c2a7c677818059cccd84cc2986fdb732a18cdea3 100644
--- a/front/src/views/auth/PasswordResetConfirm.vue
+++ b/front/src/views/auth/PasswordResetConfirm.vue
@@ -2,34 +2,34 @@
   <main class="main pusher" v-title="labels.changePassword">
     <section class="ui vertical stripe segment">
       <div class="ui small text container">
-        <h2><translate>Change your password</translate></h2>
+        <h2>{{ labels.changePassword }}</h2>
         <form v-if="!success" class="ui form" @submit.prevent="submit()">
           <div v-if="errors.length > 0" class="ui negative message">
-            <div class="header"><translate>Error while changing your password</translate></div>
+            <div class="header"><translate translate-context="Content/Signup/Card.Title">Error while changing your password</translate></div>
             <ul class="list">
               <li v-for="error in errors">{{ error }}</li>
             </ul>
           </div>
           <template v-if="token && uid">
             <div class="field">
-              <label><translate>New password</translate></label>
+              <label><translate translate-context="Content/Settings/Input.Label">New password</translate></label>
               <password-input v-model="newPassword" />
             </div>
             <router-link :to="{path: '/login'}">
-              <translate>Back to login</translate>
+              <translate translate-context="Content/Signup/Link">Back to login</translate>
             </router-link>
             <button :class="['ui', {'loading': isLoading}, 'right', 'floated', 'green', 'button']" type="submit">
-              <translate>Update your password</translate></button>
+              <translate translate-context="Content/Signup/Button.Label">Update your password</translate></button>
           </template>
           <template v-else>
-            <p><translate>If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes.</translate></p>
+            <p><translate translate-context="Content/Signup/Paragraph">If the email address provided in the previous step is valid and binded to a user account, you should receive an email with reset instructions in the next couple of minutes.</translate></p>
           </template>
         </form>
         <div v-else class="ui positive message">
-          <div class="header"><translate>Password updated successfully</translate></div>
-          <p><translate>Your password has been updated successfully.</translate></p>
+          <div class="header"><translate translate-context="Content/Signup/Card.Title">Password updated successfully</translate></div>
+          <p><translate translate-context="Content/Signup/Card.Paragraph">Your password has been updated successfully.</translate></p>
           <router-link :to="{name: 'login'}">
-            <translate>Proceed to login</translate>
+            <translate translate-context="Content/Signup/Link/Verb">Proceed to login</translate>
           </router-link>
         </div>
       </div>
@@ -59,7 +59,7 @@ export default {
   computed: {
     labels() {
       return {
-        changePassword: this.$gettext("Change your password")
+        changePassword: this.$pgettext('*/Signup/Title', "Change your password")
       }
     }
   },
diff --git a/front/src/views/content/Base.vue b/front/src/views/content/Base.vue
index 039e21adcd311edd99badb5443ac5f8a16f0f478..4e755ee1a8790c1311d7c0a542f44582758f56e2 100644
--- a/front/src/views/content/Base.vue
+++ b/front/src/views/content/Base.vue
@@ -3,10 +3,10 @@
     <nav class="ui secondary pointing menu" role="navigation" :aria-label="labels.secondaryMenu">
       <router-link
         class="ui item"
-        :to="{name: 'content.libraries.index'}"><translate>Libraries</translate></router-link>
+        :to="{name: 'content.libraries.index'}"><translate translate-context="*/*/*/Noun">Libraries</translate></router-link>
       <router-link
         class="ui item"
-        :to="{name: 'content.libraries.files'}"><translate>Tracks</translate></router-link>
+        :to="{name: 'content.libraries.files'}"><translate translate-context="*/*/*/Noun">Tracks</translate></router-link>
     </nav>
     <router-view :key="$route.fullPath"></router-view>
   </main>
@@ -15,8 +15,8 @@
 export default {
   computed: {
     labels() {
-      let title = this.$gettext("Add content")
-      let secondaryMenu = this.$gettext("Secondary menu")
+      let title = this.$pgettext('*/Library/*/Verb', "Add content")
+      let secondaryMenu = this.$pgettext('Menu/*/Hidden text', "Secondary menu")
       return {
         title,
         secondaryMenu
diff --git a/front/src/views/content/Home.vue b/front/src/views/content/Home.vue
index a23a0e383a1627cffdc38d74856132ef1b7ddbd1..de8a86e256e8b3d9d4bd092c58abb9afc6131895 100644
--- a/front/src/views/content/Home.vue
+++ b/front/src/views/content/Home.vue
@@ -2,22 +2,22 @@
   <section class="ui vertical aligned stripe segment" v-title="labels.title">
     <div class="ui text container">
       <h1>{{ labels.title }}</h1>
-      <p><translate>There are various ways to grab new content and make it available here.</translate></p>
+      <p><translate translate-context="Content/Library/Paragraph">There are various ways to grab new content and make it available here.</translate></p>
       <div class="ui segment">
-        <h2><translate>Upload audio content</translate></h2>
-        <p><translate>Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here.</translate></p>
+        <h2><translate translate-context="Content/Library/Title/Verb">Upload audio content</translate></h2>
+        <p><translate translate-context="Content/Library/Paragraph">Upload music files (MP3, OGG, FLAC, etc.) from your personal library directly from your browser to enjoy them here.</translate></p>
         <p>
-          <strong><translate :translate-params="{quota: defaultQuota}">This instance offers up to %{quota} of storage space for every user.</translate></strong>
+          <strong><translate translate-context="Content/Library/Paragraph" :translate-params="{quota: defaultQuota}">This instance offers up to %{quota} of storage space for every user.</translate></strong>
         </p>
         <router-link :to="{name: 'content.libraries.index'}" class="ui green button">
-          <translate>Get started</translate>
+          <translate translate-context="Content/Library/Button.Label/Verb">Get started</translate>
         </router-link>
       </div>
       <div class="ui segment">
-        <h2><translate>Follow remote libraries</translate></h2>
-        <p><translate>You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner.</translate></p>
+        <h2><translate translate-context="Content/Library/Title/Verb">Follow remote libraries</translate></h2>
+        <p><translate translate-context="Content/Library/Paragraph">You can follow libraries from other users to get access to new music. Public libraries can be followed immediatly, while following a private library requires approval from its owner.</translate></p>
         <router-link :to="{name: 'content.remote.index'}" class="ui green button">
-          <translate>Get started</translate>
+          <translate translate-context="Content/Library/Button.Label/Verb">Get started</translate>
         </router-link>
       </div>
 
@@ -32,7 +32,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Add and manage content")
+        title: this.$pgettext('Content/Library/Title/Verb', "Add and manage content")
       }
     },
     defaultQuota() {
diff --git a/front/src/views/content/libraries/Card.vue b/front/src/views/content/libraries/Card.vue
index 13523b198fcb76080825b8b87790ecd12430b721..4e1b497df25fa85b98bf9ad514782b601765c770 100644
--- a/front/src/views/content/libraries/Card.vue
+++ b/front/src/views/content/libraries/Card.vue
@@ -6,19 +6,19 @@
         <span
           v-if="library.privacy_level === 'me'"
           class="right floated"
-          :data-tooltip="labels.tooltips.me">
+          :data-tooltip="privacy_tooltips('me')">
           <i class="small lock icon"></i>
         </span>
         <span
           v-else-if="library.privacy_level === 'instance'"
           class="right floated"
-          :data-tooltip="labels.tooltips.instance">
+          :data-tooltip="privacy_tooltips('instance')">
           <i class="small circle outline icon"></i>
         </span>
         <span
           v-else-if="library.privacy_level === 'everyone'"
           class="right floated"
-          :data-tooltip="labels.tooltips.everyone">
+          :data-tooltip="privacy_tooltips('everyone')">
           <i class="small globe icon"></i>
         </span>
       </div>
@@ -29,46 +29,44 @@
         </span>
       </div>
       <div class="description">
+        {{ library.description }}
         <div class="ui hidden divider"></div>
       </div>
       <div class="content">
-        <span v-if="library.size" class="right floated" :data-tooltip="labels.tooltips.size">
+        <span v-if="library.size" class="right floated" :data-tooltip="size_label">
           <i class="database icon"></i>
           {{ library.size | humanSize }}
         </span>
         <i class="music icon"></i>
-        <translate :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
+        <translate translate-context="*/*/*" :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
       </div>
     </div>
     <div class="ui bottom basic attached buttons">
       <router-link :to="{name: 'content.libraries.detail.upload', params: {id: library.uuid}}" class="ui button">
-        <translate>Upload</translate>
+        <translate translate-context="Content/Library/Card.Button.Label/Verb">Upload</translate>
       </router-link>
       <router-link :to="{name: 'content.libraries.detail', params: {id: library.uuid}}" exact class="ui button">
-        <translate>Detail</translate>
+        <translate translate-context="Content/Library/Card.Button.Label/Noun">Details</translate>
       </router-link>
     </div>
   </div>
 </template>
+
 <script>
+import TranslationsMixin from '@/components/mixins/Translations'
+
 export default {
+  mixins: [TranslationsMixin],
   props: ['library'],
+  methods: {
+    privacy_tooltips (level) {
+      return 'Visibility: ' + this.sharedLabels.fields.privacy_level.choices[level].toLowerCase()
+    },
+  },
   computed: {
-    labels () {
-      let me = this.$gettext('Visibility: nobody except me')
-      let instance = this.$gettext('Visibility: everyone on this instance')
-      let everyone = this.$gettext('Visibility: everyone, including other instances')
-      let size = this.$gettext('Total size of the files in this library')
-
-      return {
-        tooltips: {
-          me,
-          instance,
-          everyone,
-          size
-        }
-      }
-    }
+    size_label () {
+      return this.$pgettext('Content/Library/Card.Help text', 'Total size of the files in this library')
+    },
   }
 }
 </script>
diff --git a/front/src/views/content/libraries/Detail.vue b/front/src/views/content/libraries/Detail.vue
index f0bbc2a6e791abdbc54764a851b68e499ed8e019..d879ab71c7731ae9e1aae82f0f3fc2197675267c 100644
--- a/front/src/views/content/libraries/Detail.vue
+++ b/front/src/views/content/libraries/Detail.vue
@@ -1,33 +1,33 @@
 <template>
   <section class="ui vertical aligned stripe segment">
     <div v-if="isLoadingLibrary" :class="['ui', {'active': isLoadingLibrary}, 'inverted', 'dimmer']">
-      <div class="ui text loader"><translate>Loading library data…</translate></div>
+      <div class="ui text loader"><translate translate-context="Content/Library/Paragraph">Loading library data…</translate></div>
     </div>
     <detail-area v-else :library="library">
       <div class="ui top attached tabular menu">
-        <a :class="['item', {active: currentTab === 'follows'}]" @click="currentTab = 'follows'"><translate>Followers</translate></a>
-        <a :class="['item', {active: currentTab === 'tracks'}]" @click="currentTab = 'tracks'"><translate>Tracks</translate></a>
-        <a :class="['item', {active: currentTab === 'edit'}]" @click="currentTab = 'edit'"><translate>Edit</translate></a>
+        <a :class="['item', {active: currentTab === 'follows'}]" @click="currentTab = 'follows'"><translate translate-context="Content/Federation/*/Noun">Followers</translate></a>
+        <a :class="['item', {active: currentTab === 'tracks'}]" @click="currentTab = 'tracks'"><translate translate-context="*/*/*/Noun">Tracks</translate></a>
+        <a :class="['item', {active: currentTab === 'edit'}]" @click="currentTab = 'edit'"><translate translate-context="Content/*/Button.Label/Verb">Edit</translate></a>
       </div>
       <div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'follows'}]">
         <div class="ui form">
           <div class="field">
-            <label><translate>Sharing link</translate></label>
-            <p><translate>Share this link with other users so they can request access to your library.</translate></p>
+            <label><translate translate-context="Content/Library/Title">Sharing link</translate></label>
+            <p><translate translate-context="Content/Library/Paragraph">Share this link with other users so they can request access to your library.</translate></p>
             <copy-input :value="library.fid" />
           </div>
         </div>
         <div class="ui hidden divider"></div>
         <div v-if="isLoadingFollows" :class="['ui', {'active': isLoadingFollows}, 'inverted', 'dimmer']">
-          <div class="ui text loader"><translate>Loading followers…</translate></div>
+          <div class="ui text loader"><translate translate-context="Content/Library/Paragraph">Loading followers…</translate></div>
         </div>
         <table v-else-if="follows && follows.count > 0" class="ui table">
           <thead>
             <tr>
-              <th><translate>User</translate></th>
-              <th><translate>Date</translate></th>
-              <th><translate>Status</translate></th>
-              <th><translate>Action</translate></th>
+              <th><translate translate-context="Content/Library/Table.Label">User</translate></th>
+              <th><translate translate-context="Content/Library/Table.Label">Date</translate></th>
+              <th><translate translate-context="Content/Library.Federation/Table.Label (Value is Approved/Rejected)">Status</translate></th>
+              <th><translate translate-context="Content/Library/Table.Label">Action</translate></th>
             </tr>
           </thead>
           <tr v-for="follow in follows.results" :key="follow.fid">
@@ -35,27 +35,27 @@
             <td><human-date :date="follow.creation_date" /></td>
             <td>
               <span :class="['ui', 'yellow', 'basic', 'label']" v-if="follow.approved === null">
-                <translate>Pending approval</translate>
+                <translate translate-context="Content/Library/Table/Short">Pending approval</translate>
               </span>
               <span :class="['ui', 'green', 'basic', 'label']" v-else-if="follow.approved === true">
-                <translate>Accepted</translate>
+                <translate translate-context="Content/Library/Table/Short">Accepted</translate>
               </span>
               <span :class="['ui', 'red', 'basic', 'label']" v-else-if="follow.approved === false">
-                <translate>Rejected</translate>
+                <translate translate-context="Content/Library/*/Short">Rejected</translate>
               </span>
             </td>
             <td>
               <div @click="updateApproved(follow, true)" :class="['ui', 'mini', 'icon', 'labeled', 'green', 'button']" v-if="follow.approved === null || follow.approved === false">
-                <i class="ui check icon"></i> <translate>Accept</translate>
+                <i class="ui check icon"></i> <translate translate-context="Content/Library/Button.Label">Accept</translate>
               </div>
               <div @click="updateApproved(follow, false)" :class="['ui', 'mini', 'icon', 'labeled', 'red', 'button']" v-if="follow.approved === null || follow.approved === true">
-                <i class="ui x icon"></i> <translate>Reject</translate>
+                <i class="ui x icon"></i> <translate translate-context="Content/Library/Button.Label">Reject</translate>
               </div>
             </td>
           </tr>
 
         </table>
-        <p v-else><translate>Nobody is following this library</translate></p>
+        <p v-else><translate translate-context="Content/Library/Paragraph">Nobody is following this library</translate></p>
       </div>
       <div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'tracks'}]">
         <library-files-table :filters="{library: library.uuid}"></library-files-table>
diff --git a/front/src/views/content/libraries/DetailArea.vue b/front/src/views/content/libraries/DetailArea.vue
index eb481ea881a4d0089371182866d59b89d5948cdd..0a73c90b927589c55bd1353a399febd67bb2309e 100644
--- a/front/src/views/content/libraries/DetailArea.vue
+++ b/front/src/views/content/libraries/DetailArea.vue
@@ -1,8 +1,8 @@
 <template>
   <div>
-    <div class="ui stackable grid">
-      <div class="five wide column">
-        <h3 class="ui header"><translate>Current library</translate></h3>
+    <div class="ui two column row">
+      <div class="column">
+        <h3 class="ui header"><translate translate-context="Content/Library/Title">Current library</translate></h3>
         <library-card :library="library" />
       </div>
     </div>
@@ -21,7 +21,7 @@ export default {
   },
   computed: {
     links () {
-      let upload = this.$gettext('Upload')
+      let upload = this.$pgettext('Content/Library/Card.Button.Label/Verb', 'Upload')
       return [
         {
           name: 'libraries.detail.upload',
diff --git a/front/src/views/content/libraries/FilesTable.vue b/front/src/views/content/libraries/FilesTable.vue
index dcdd4b87d2312d0acecfc35222b0c6d1e5824fb0..9ea4634adcb6360dbc5e8c454405b6deeac11527 100644
--- a/front/src/views/content/libraries/FilesTable.vue
+++ b/front/src/views/content/libraries/FilesTable.vue
@@ -3,23 +3,23 @@
     <div class="ui inline form">
       <div class="fields">
         <div class="ui six wide field">
-          <label><translate>Search</translate></label>
+          <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
           <form @submit.prevent="search.query = $refs.search.value">
             <input name="search" ref="search" type="text" :value="search.query" :placeholder="labels.searchPlaceholder" />
           </form>
         </div>
         <div class="field">
-          <label><translate>Import status</translate></label>
+          <label><translate translate-context="Content/Library/*/Noun">Import status</translate></label>
           <select class="ui dropdown" @change="addSearchToken('status', $event.target.value)" :value="getTokenValue('status', '')">
-            <option value=""><translate>All</translate></option>
-            <option value="pending"><translate>Pending</translate></option>
-            <option value="skipped"><translate>Skipped</translate></option>
-            <option value="errored"><translate>Failed</translate></option>
-            <option value="finished"><translate>Finished</translate></option>
+            <option value=""><translate translate-context="Content/*/Dropdown">All</translate></option>
+            <option value="pending"><translate translate-context="Content/Library/*/Short">Pending</translate></option>
+            <option value="skipped"><translate translate-context="Content/Library/*">Skipped</translate></option>
+            <option value="errored"><translate translate-context="Content/Library/Dropdown">Failed</translate></option>
+            <option value="finished"><translate translate-context="Content/Library/*">Finished</translate></option>
           </select>
         </div>
         <div class="field">
-          <label><translate>Ordering</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
           <select class="ui dropdown" v-model="ordering">
             <option v-for="option in orderingOptions" :value="option[0]">
               {{ sharedLabels.filters[option[1]] }}
@@ -27,14 +27,15 @@
           </select>
         </div>
         <div class="field">
-          <label><translate>Ordering direction</translate></label>
+          <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering direction</translate></label>
           <select class="ui dropdown" v-model="orderingDirection">
-            <option value="+"><translate>Ascending</translate></option>
-            <option value="-"><translate>Descending</translate></option>
+            <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+            <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
           </select>
         </div>
       </div>
     </div>
+    <import-status-modal :upload="detailedUpload" :show.sync="showUploadDetailModal" />
     <div class="dimmable">
       <div v-if="isLoading" class="ui active inverted dimmer">
           <div class="ui loader"></div>
@@ -52,13 +53,13 @@
         @refresh="fetchData"
         :filters="actionFilters">
         <template slot="header-cells">
-          <th><translate>Title</translate></th>
-          <th><translate>Artist</translate></th>
-          <th><translate>Album</translate></th>
-          <th><translate>Upload date</translate></th>
-          <th><translate>Import status</translate></th>
-          <th><translate>Duration</translate></th>
-          <th><translate>Size</translate></th>
+          <th><translate translate-context="Content/Track/*/Noun">Title</translate></th>
+          <th><translate translate-context="*/*/*/Noun">Artist</translate></th>
+          <th><translate translate-context="*/*/*">Album</translate></th>
+          <th><translate translate-context="*/*/*/Noun">Upload date</translate></th>
+          <th><translate translate-context="Content/Library/*/Noun">Import status</translate></th>
+          <th><translate translate-context="Content/*/*">Duration</translate></th>
+          <th><translate translate-context="Content/Library/*/in MB">Size</translate></th>
         </template>
         <template slot="row-cells" slot-scope="scope">
           <template v-if="scope.obj.track">
@@ -80,23 +81,25 @@
           <td>
             <human-date :date="scope.obj.creation_date"></human-date>
           </td>
-          <td :title="labels.importStatuses[scope.obj.import_status].help">
-            <span class="discrete link" @click="addSearchToken('status', scope.obj.import_status)">
-              {{ labels.importStatuses[scope.obj.import_status].label }}
-              <i class="question circle outline icon"></i>
+          <td>
+            <span class="discrete link" @click="addSearchToken('status', scope.obj.import_status)" :title="sharedLabels.fields.import_status.choices[scope.obj.import_status].help">
+              {{ sharedLabels.fields.import_status.choices[scope.obj.import_status].label }}
             </span>
+            <button class="ui tiny basic icon button" :title="sharedLabels.fields.import_status.detailTitle" @click="detailedUpload = scope.obj; showUploadDetailModal = true">
+              <i class="question circle outline icon"></i>
+            </button>
           </td>
           <td v-if="scope.obj.duration">
             {{ time.parse(scope.obj.duration) }}
           </td>
           <td v-else>
-            <translate>N/A</translate>
+            <translate translate-context="*/*/*">N/A</translate>
           </td>
           <td v-if="scope.obj.size">
             {{ scope.obj.size | humanSize }}
           </td>
           <td v-else>
-            <translate>N/A</translate>
+            <translate translate-context="*/*/*">N/A</translate>
           </td>
         </template>
       </action-table>
@@ -112,7 +115,7 @@
         ></pagination>
 
       <span v-if="result && result.results.length > 0">
-        <translate
+        <translate translate-context="Content/*/Paragraph"
           :translate-params="{start: ((page-1) * paginateBy) + 1, end: ((page-1) * paginateBy) + result.results.length, total: result.count}">
           Showing results %{ start }-%{ end } on %{ total }
         </translate>
@@ -132,6 +135,7 @@ import ActionTable from '@/components/common/ActionTable'
 import OrderingMixin from '@/components/mixins/Ordering'
 import TranslationsMixin from '@/components/mixins/Translations'
 import SmartSearchMixin from '@/components/mixins/SmartSearch'
+import ImportStatusModal from '@/components/library/ImportStatusModal'
 
 export default {
   mixins: [OrderingMixin, TranslationsMixin, SmartSearchMixin],
@@ -142,11 +146,14 @@ export default {
   },
   components: {
     Pagination,
-    ActionTable
+    ActionTable,
+    ImportStatusModal
   },
   data () {
     return {
       time,
+      detailedUpload: null,
+      showUploadDetailModal: false,
       isLoading: false,
       result: null,
       page: 1,
@@ -159,7 +166,7 @@ export default {
       ordering: 'creation_date',
       orderingOptions: [
         ['creation_date', 'creation_date'],
-        ['title', 'title'],
+        ['title', 'track_title'],
         ['size', 'size'],
         ['duration', 'duration'],
         ['bitrate', 'bitrate'],
@@ -193,30 +200,12 @@ export default {
     },
     selectPage: function (page) {
       this.page = page
-    }
+    },
   },
   computed: {
     labels () {
       return {
-        searchPlaceholder: this.$gettext('Search by title, artist, album…'),
-        importStatuses: {
-          skipped: {
-            label: this.$gettext('Skipped'),
-            help: this.$gettext('Track already present in one of your libraries'),
-          },
-          pending: {
-            label: this.$gettext('Pending'),
-            help: this.$gettext('Track uploaded, but not processed by the server yet'),
-          },
-          errored: {
-            label: this.$gettext('Errored'),
-            help: this.$gettext('Could not process this track, ensure it is tagged correctly'),
-          },
-          finished: {
-            label: this.$gettext('Finished'),
-            help: this.$gettext('Imported'),
-          },
-        }
+        searchPlaceholder: this.$pgettext('Content/Library/Input.Placeholder', 'Search by title, artist, album…'),
       }
     },
     actionFilters () {
@@ -230,8 +219,8 @@ export default {
       }
     },
     actions () {
-      let deleteMsg = this.$gettext('Delete')
-      let relaunchMsg = this.$gettext('Relaunch import')
+      let deleteMsg = this.$pgettext('*/*/*/Verb', 'Delete')
+      let relaunchMsg = this.$pgettext('Content/Library/Dropdown/Verb', 'Restart import')
       return [
         {
           name: 'delete',
diff --git a/front/src/views/content/libraries/Form.vue b/front/src/views/content/libraries/Form.vue
index d197e4d5b9c11ef0c699649d0ae8d517fe5a6d98..93530df41b875cf80c61883eaad6389b92dbc8c0 100644
--- a/front/src/views/content/libraries/Form.vue
+++ b/front/src/views/content/libraries/Form.vue
@@ -1,52 +1,54 @@
 <template>
   <form class="ui form" @submit.prevent="submit">
-    <p v-if="!library"><translate>Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family.</translate></p>
+    <p v-if="!library"><translate translate-context="Content/Library/Paragraph">Libraries help you organize and share your music collections. You can upload your own music collection to Funkwhale and share it with your friends and family.</translate></p>
     <div v-if="errors.length > 0" class="ui negative message">
-      <div class="header"><translate>Error</translate></div>
+      <div class="header"><translate translate-context="Content/*/Error message.Title">Error</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
     </div>
     <div class="required field">
-      <label><translate>Name</translate></label>
+      <label><translate translate-context="*/*/*/Noun">Name</translate></label>
       <input name="name" v-model="currentName" :placeholder="labels.namePlaceholder" required maxlength="100">
     </div>
     <div class="field">
-      <label><translate>Description</translate></label>
+      <label><translate translate-context="Content/*/Input.Label/Noun">Description</translate></label>
       <textarea v-model="currentDescription" :placeholder="labels.descriptionPlaceholder" maxlength="2000"></textarea>
     </div>
     <div class="field">
-      <label><translate>Visibility</translate></label>
-      <p><translate>You are able to share your library with other people, regardless of its visibility.</translate></p>
+      <label><translate translate-context="Content/Library/Dropdown.Label">Visibility</translate></label>
+      <p><translate translate-context="Content/Library/Paragraph">You are able to share your library with other people, regardless of its visibility.</translate></p>
       <select class="ui dropdown" v-model="currentVisibilityLevel">
-        <option :value="c" v-for="c in ['me', 'instance', 'everyone']">{{ labels.visibility[c] }}</option>
+        <option :value="c" v-for="c in ['me', 'instance', 'everyone']">{{ sharedLabels.fields.privacy_level.choices[c] }}</option>
       </select>
     </div>
     <button class="ui submit button" type="submit">
-      <translate v-if="library">Update library</translate>
-      <translate v-else>Create library</translate>
+      <translate translate-context="Content/Library/Button.Label/Verb" v-if="library">Update library</translate>
+      <translate translate-context="Content/Library/Button.Label/Verb" v-else>Create library</translate>
     </button>
     <dangerous-button v-if="library" class="right floated basic button" color='red' @confirm="remove()">
-      <translate>Delete</translate>
+      <translate translate-context="*/*/*/Verb">Delete</translate>
       <p slot="modal-header">
-        <translate>Delete this library?</translate>
+        <translate translate-context="Popup/Library/Title">Delete this library?</translate>
       </p>
       <p slot="modal-content">
-        <translate>
+        <translate translate-context="Popup/Library/Paragraph">
           The library and all its tracks will be deleted. This can not be undone.
         </translate>
       </p>
-      <p slot="modal-confirm">
-        <translate>Delete library</translate>
-      </p>
+      <div slot="modal-confirm">
+        <translate translate-context="Popup/Library/Button.Label/Verb">Delete library</translate>
+      </div>
     </dangerous-button>
   </form>
 </template>
 
 <script>
 import axios from 'axios'
+import MixinsTranslation from '@/components/mixins/Translations.vue'
 
 export default {
+  mixins: [MixinsTranslation],
   props: ['library'],
   data () {
     let d = {
@@ -67,19 +69,11 @@ export default {
   },
   computed: {
     labels () {
-      let namePlaceholder = this.$gettext('My awesome library')
-      let descriptionPlaceholder = this.$gettext('This library contains my personal music, I hope you like it.')
-      let me = this.$gettext('Nobody except me')
-      let instance = this.$gettext('Everyone on this instance')
-      let everyone = this.$gettext('Everyone, across all instances')
+      let namePlaceholder = this.$pgettext('Content/Library/Input.Placeholder', 'My awesome library')
+      let descriptionPlaceholder = this.$pgettext('Content/Library/Input.Placeholder', 'This library contains my personal music, I hope you like it.')
       return {
         namePlaceholder,
         descriptionPlaceholder,
-        visibility: {
-          me,
-          instance,
-          everyone
-        }
       }
     }
   },
@@ -103,10 +97,10 @@ export default {
         let msg
         if (self.library) {
           self.$emit('updated', response.data)
-          msg = this.$gettext('Library updated')
+          msg = this.$pgettext('Content/Library/Message', 'Library updated')
         } else {
           self.$emit('created', response.data)
-          msg = this.$gettext('Library created')
+          msg = this.$pgettext('Content/Library/Message', 'Library created')
         }
         self.$store.commit('ui/addMessage', {
           content: msg,
@@ -126,7 +120,7 @@ export default {
       let self = this
       axios.delete(`libraries/${this.library.uuid}/`).then((response) => {
         self.isLoading = false
-        let msg = this.$gettext('Library deleted')
+        let msg = this.$pgettext('Content/Library/Message', 'Library deleted')
         self.$emit('deleted', {})
         self.$store.commit('ui/addMessage', {
           content: msg,
diff --git a/front/src/views/content/libraries/Home.vue b/front/src/views/content/libraries/Home.vue
index f6eafc711ab23c331e3f42c88e09a0a072ce4a5a..69b4ce3a2863ed59aad101f3ccc2881c968bbdda 100644
--- a/front/src/views/content/libraries/Home.vue
+++ b/front/src/views/content/libraries/Home.vue
@@ -1,18 +1,18 @@
 <template>
   <section class="ui vertical aligned stripe segment">
     <div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
-      <div class="ui text loader"><translate>Loading Libraries…</translate></div>
+      <div class="ui text loader"><translate translate-context="Content/Library/Paragraph">Loading Libraries…</translate></div>
     </div>
     <div v-else class="ui text container">
-      <h1 class="ui header"><translate>My libraries</translate></h1>
+      <h1 class="ui header"><translate translate-context="Content/Library/Title">My libraries</translate></h1>
 
       <p v-if="libraries.length == 0">
-        <translate>Looks like you don't have a library, it's time to create one.</translate>
+        <translate translate-context="Content/Library/Paragraph">Looks like you don't have a library, it's time to create one.</translate>
       </p>
       <a @click="hiddenForm = !hiddenForm">
         <i class="plus icon" v-if="hiddenForm" />
         <i class="minus icon" v-else />
-        <translate>Create a new library</translate>
+        <translate translate-context="Content/Library/Link/Verb">Create a new library</translate>
       </a>
       <library-form :library="null" v-if="!hiddenForm" @created="libraryCreated" />
       <div class="ui hidden divider"></div>
diff --git a/front/src/views/content/libraries/Quota.vue b/front/src/views/content/libraries/Quota.vue
index ba747f0e664b37857829896829e58bcb74ec7ccf..687a825cf78e1d89b5770c98a7cfced695cead7e 100644
--- a/front/src/views/content/libraries/Quota.vue
+++ b/front/src/views/content/libraries/Quota.vue
@@ -1,15 +1,15 @@
 <template>
   <div class="ui segment">
-    <h3 class="ui header"><translate>Current usage</translate></h3>
+    <h3 class="ui header"><translate translate-context="Content/Library/Title">Current usage</translate></h3>
     <div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
-      <div class="ui text loader"><translate>Loading usage data…</translate></div>
+      <div class="ui text loader"><translate translate-context="Content/Library/Paragraph">Loading usage data…</translate></div>
     </div>
     <div :class="['ui', {'success': progress < 60}, {'yellow': progress >= 60 && progress < 96}, {'error': progress >= 95}, 'progress']">
       <div class="bar" :style="{width: `${progress}%`}">
         <div class="progress">{{ progress }}%</div>
       </div>
       <div class="label" v-if="quotaStatus">
-        <translate :translate-params="{max: humanSize(quotaStatus.max * 1000 * 1000), current: humanSize(quotaStatus.current * 1000 * 1000)}">%{ current } used on %{ max } allowed</translate>
+        <translate translate-context="Content/Library/Paragraph" :translate-params="{max: humanSize(quotaStatus.max * 1000 * 1000), current: humanSize(quotaStatus.current * 1000 * 1000)}">%{ current } used on %{ max } allowed</translate>
       </div>
     </div>
     <div class="ui hidden divider"></div>
@@ -20,24 +20,24 @@
             {{ humanSize(quotaStatus.pending * 1000 * 1000) }}
           </div>
           <div class="label">
-            <translate>Pending files</translate>
+            <translate translate-context="Content/Library/Label">Pending files</translate>
           </div>
         </div>
         <div>
           <router-link
             class="ui basic blue tiny button"
             :to="{name: 'content.libraries.files', query: {q: compileTokens([{field: 'status', value: 'pending'}])}}">
-            <translate>View files</translate>
+            <translate translate-context="Content/Library/Link/Verb">View files</translate>
           </router-link>
 
           <dangerous-button
             color="grey"
             class="basic tiny"
             :action="purgePendingFiles">
-            <translate>Purge</translate>
-            <p slot="modal-header"><translate>Purge pending files?</translate></p>
-            <p slot="modal-content"><translate>Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota.</translate></p>
-            <p slot="modal-confirm"><translate>Purge</translate></p>
+            <translate translate-context="*/*/*/Verb">Purge</translate>
+            <p slot="modal-header"><translate translate-context="Popup/Library/Title">Purge pending files?</translate></p>
+            <p slot="modal-content"><translate translate-context="Popup/Library/Paragraph">Removes uploaded but yet to be processed tracks completely, adding the corresponding data to your quota.</translate></p>
+            <div slot="modal-confirm"><translate translate-context="*/*/*/Verb">Purge</translate></div>
           </dangerous-button>
         </div>
       </div>
@@ -47,23 +47,23 @@
             {{ humanSize(quotaStatus.skipped * 1000 * 1000) }}
           </div>
           <div class="label">
-            <translate>Skipped files</translate>
+            <translate translate-context="Content/Library/Label">Skipped files</translate>
           </div>
         </div>
         <div>
           <router-link
             class="ui basic blue tiny button"
             :to="{name: 'content.libraries.files', query: {q: compileTokens([{field: 'status', value: 'skipped'}])}}">
-            <translate>View files</translate>
+            <translate translate-context="Content/Library/Link/Verb">View files</translate>
           </router-link>
           <dangerous-button
             color="grey"
             class="basic tiny"
             :action="purgeSkippedFiles">
-            <translate>Purge</translate>
-            <p slot="modal-header"><translate>Purge skipped files?</translate></p>
-            <p slot="modal-content"><translate>Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota.</translate></p>
-            <p slot="modal-confirm"><translate>Purge</translate></p>
+            <translate translate-context="*/*/*/Verb">Purge</translate>
+            <p slot="modal-header"><translate translate-context="Popup/Library/Title">Purge skipped files?</translate></p>
+            <p slot="modal-content"><translate translate-context="Popup/Library/Paragraph">Removes uploaded tracks skipped during the import processes completely, adding the corresponding data to your quota.</translate></p>
+            <div slot="modal-confirm"><translate translate-context="*/*/*/Verb">Purge</translate></div>
           </dangerous-button>
         </div>
       </div>
@@ -73,23 +73,23 @@
             {{ humanSize(quotaStatus.errored * 1000 * 1000) }}
           </div>
           <div class="label">
-            <translate>Errored files</translate>
+            <translate translate-context="Content/Library/Label">Errored files</translate>
           </div>
         </div>
         <div>
           <router-link
             class="ui basic blue tiny button"
             :to="{name: 'content.libraries.files', query: {q: compileTokens([{field: 'status', value: 'errored'}])}}">
-            <translate>View files</translate>
+            <translate translate-context="Content/Library/Link/Verb">View files</translate>
           </router-link>
           <dangerous-button
             color="grey"
             class="basic tiny"
             :action="purgeErroredFiles">
-            <translate>Purge</translate>
-            <p slot="modal-header"><translate>Purge errored files?</translate></p>
-            <p slot="modal-content"><translate>Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota.</translate></p>
-            <p slot="modal-confirm"><translate>Purge</translate></p>
+            <translate translate-context="*/*/*/Verb">Purge</translate>
+            <p slot="modal-header"><translate translate-context="Popup/Library/Title">Purge errored files?</translate></p>
+            <p slot="modal-content"><translate translate-context="Popup/Library/Paragraph">Removes uploaded tracks that could not be processed by the server completely, adding the corresponding data to your quota.</translate></p>
+            <div slot="modal-confirm"><translate translate-context="*/*/*/Verb">Purge</translate></div>
           </dangerous-button>
         </div>
       </div>
diff --git a/front/src/views/content/libraries/Upload.vue b/front/src/views/content/libraries/Upload.vue
index 8547aa570a3548cbd7072fb26f84ed59f554b1b5..5fc7234ecd03fe82dd3019ba18d2997c55673aeb 100644
--- a/front/src/views/content/libraries/Upload.vue
+++ b/front/src/views/content/libraries/Upload.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="ui vertical aligned stripe segment">
     <div v-if="isLoadingLibrary" :class="['ui', {'active': isLoadingLibrary}, 'inverted', 'dimmer']">
-      <div class="ui text loader"><translate>Loading library data…</translate></div>
+      <div class="ui text loader"><translate translate-context="Content/Library/Paragraph">Loading library data…</translate></div>
     </div>
     <detail-area v-else :library="library">
       <file-upload ref="fileupload" :default-import-reference="defaultImportReference" :library="library" />
diff --git a/front/src/views/content/remote/Card.vue b/front/src/views/content/remote/Card.vue
index 364783f3eae57fcd94b6b8282c2fdd0dd1e7cb4a..b78f7f220af0b02438d87740e3ab3c1d2d7981be 100644
--- a/front/src/views/content/remote/Card.vue
+++ b/front/src/views/content/remote/Card.vue
@@ -22,46 +22,50 @@
           <human-date :date="library.creation_date" />
         </span>
       </div>
+      <div class="description">
+        {{ library.description }}
+        <div class="ui hidden divider"></div>
+      </div>
       <div class="meta">
         <i class="music icon"></i>
-        <translate :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
+        <translate translate-context="*/*/*" :translate-params="{count: library.uploads_count}" :translate-n="library.uploads_count" translate-plural="%{ count } tracks">%{ count } track</translate>
       </div>
       <div v-if="displayScan && latestScan" class="meta">
         <template v-if="latestScan.status === 'pending'">
           <i class="hourglass icon"></i>
-          <translate>Scan waiting</translate>
+          <translate translate-context="Content/Library/Card.List item">Scan pending</translate>
         </template>
         <template v-if="latestScan.status === 'scanning'">
           <i class="loading spinner icon"></i>
-          <translate :translate-params="{progress: scanProgress}">Scanning… (%{ progress }%)</translate>
+          <translate translate-context="Content/Library/Card.List item" :translate-params="{progress: scanProgress}">Scanning… (%{ progress }%)</translate>
         </template>
         <template v-else-if="latestScan.status === 'errored'">
           <i class="red download icon"></i>
-          <translate>Problem during scanning</translate>
+          <translate translate-context="Content/Library/Card.List item">Problem during scanning</translate>
         </template>
         <template v-else-if="latestScan.status === 'finished' && latestScan.errored_files === 0">
           <i class="green download icon"></i>
-          <translate>Scanned</translate>
+          <translate translate-context="Content/Library/Card.List item">Scanned</translate>
         </template>
         <template v-else-if="latestScan.status === 'finished' && latestScan.errored_files > 0">
           <i class="yellow download icon"></i>
-          <translate>Scanned with errors</translate>
+          <translate translate-context="Content/Library/Card.List item">Scanned with errors</translate>
         </template>
         <span class="link right floated" @click="showScan = !showScan">
-          <translate>Details</translate>
+          <translate translate-context="Content/Library/Card.Button.Label/Noun">Details</translate>
           <i v-if="showScan" class="angle down icon" />
           <i v-else class="angle right icon" />
         </span>
         <div v-if="showScan">
           <template v-if="latestScan.modification_date">
-            <translate>Last update:</translate><human-date :date="latestScan.modification_date" /><br />
+            <translate translate-context="Content/Library/Card.List item/Noun">Last update:</translate><human-date :date="latestScan.modification_date" /><br />
           </template>
-          <translate>Failed tracks:</translate> {{ latestScan.errored_files }}
+          <translate translate-context="Content/Library/Card.List item/Noun">Failed tracks:</translate> {{ latestScan.errored_files }}
         </div>
       </div>
       <div v-if="displayScan && canLaunchScan" class="clearfix">
         <span class="right floated link" @click="launchScan">
-          <translate>Scan now</translate> <i class="paper plane icon" />
+          <translate translate-context="Content/Library/Card.Button.Label/Verb">Scan now</translate> <i class="paper plane icon" />
         </span>
       </div>
     </div>
@@ -71,40 +75,46 @@
     <div v-if="displayCopyFid" class="extra content">
       <div class="ui form">
         <div class="field">
-          <label><translate>Sharing link</translate></label>
+          <label><translate translate-context="Content/Library/Title">Sharing link</translate></label>
           <copy-input :button-classes="'basic'" :value="library.fid" />
         </div>
       </div>
     </div>
-    <div v-if="displayFollow" class="ui bottom attached buttons">
+    <div v-if="displayFollow" :class="['ui', 'bottom', {two: library.follow}, 'attached', 'buttons']">
       <button
         v-if="!library.follow"
         @click="follow()"
         :class="['ui', 'green', {'loading': isLoadingFollow}, 'button']">
-        <translate>Follow</translate>
-      </button>
-      <button
-        v-else-if="!library.follow.approved"
-        class="ui disabled button"><i class="hourglass icon"></i>
-        <translate>Follow request pending approval</translate>
+        <translate translate-context="Content/Library/Card.Button.Label/Verb">Follow</translate>
       </button>
-      <button
-        v-else-if="!library.follow.approved"
-        class="ui disabled button"><i class="check icon"></i>
-        <translate>Following</translate>
-      </button>
-      <dangerous-button
-        v-else-if="library.follow.approved"
-        color=""
-        :class="['ui', 'button']"
-        :action="unfollow">
-        <translate>Unfollow</translate>
-        <p slot="modal-header"><translate>Unfollow this library?</translate></p>
-        <div slot="modal-content">
-          <p><translate>By unfollowing this library, you loose access to its content.</translate></p>
-        </div>
-        <p slot="modal-confirm"><translate>Unfollow</translate></p>
-      </dangerous-button>
+      <template v-else-if="!library.follow.approved">
+        <button
+          class="ui disabled button"><i class="hourglass icon"></i>
+          <translate translate-context="Content/Library/Card.Paragraph">Follow request pending approval</translate>
+        </button>
+        <button
+          @click="unfollow"
+          class="ui button">
+          <translate translate-context="Content/Library/Card.Paragraph">Cancel follow request</translate>
+        </button>
+      </template>
+      <template v-else-if="library.follow.approved">
+        <button
+          class="ui disabled button"><i class="check icon"></i>
+          <translate translate-context="Content/Library/Card.Paragraph">Following</translate>
+        </button>
+        <dangerous-button
+          color=""
+          :class="['ui', 'button']"
+          :action="unfollow">
+          <translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate>
+          <p slot="modal-header"><translate translate-context="Popup/Library/Title">Unfollow this library?</translate></p>
+          <div slot="modal-content">
+            <p><translate translate-context="Popup/Library/Paragraph">By unfollowing this library, you loose access to its content.</translate></p>
+          </div>
+          <div slot="modal-confirm"><translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate></div>
+        </dangerous-button>
+      </template>
     </div>
   </div>
 </template>
@@ -128,8 +138,8 @@ export default {
   },
   computed: {
     labels () {
-      let me = this.$gettext('This library is private and your approval from its owner is needed to access its content')
-      let everyone = this.$gettext('This library is public and you can access its content freely')
+      let me = this.$pgettext('Content/Library/Card.Help text', 'This library is private and your approval from its owner is needed to access its content')
+      let everyone = this.$pgettext('Content/Library/Card.Help text', 'This library is public and you can access its content freely')
 
       return {
         tooltips: {
@@ -162,8 +172,8 @@ export default {
   methods: {
     launchScan () {
       let self = this
-      let successMsg = this.$gettext('Scan launched')
-      let skippedMsg = this.$gettext('Scan skipped (previous scan is too recent)')
+      let successMsg = this.$pgettext('Content/Library/Message', 'Scan launched')
+      let skippedMsg = this.$pgettext('Content/Library/Message', 'Scan skipped (previous scan is too recent)')
       axios.post(`federation/libraries/${this.library.uuid}/scan/`).then((response) => {
         let msg
         if (response.data.status == 'skipped') {
@@ -195,6 +205,7 @@ export default {
       this.isLoadingFollow = true
       axios.delete(`federation/follows/library/${this.library.follow.uuid}/`).then((response) => {
         self.$emit('deleted')
+        self.library.follow = null
         self.isLoadingFollow = false
       }, error => {
         self.isLoadingFollow = false
diff --git a/front/src/views/content/remote/Home.vue b/front/src/views/content/remote/Home.vue
index 007fbadcaa51a84a54c44d6d53cef852a3538733..35d56cd95c2642f4b480353739a915020ee51fcf 100644
--- a/front/src/views/content/remote/Home.vue
+++ b/front/src/views/content/remote/Home.vue
@@ -1,19 +1,19 @@
 <template>
   <div class="ui vertical aligned stripe segment">
     <div v-if="isLoading" :class="['ui', {'active': isLoading}, 'inverted', 'dimmer']">
-      <div class="ui text loader"><translate>Loading remote libraries…</translate></div>
+      <div class="ui text loader"><translate translate-context="Content/Library/Paragraph">Loading remote libraries…</translate></div>
     </div>
     <div v-else class="ui text container">
-      <h1 class="ui header"><translate>Remote libraries</translate></h1>
-      <p><translate>Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access.</translate></p>
+      <h1 class="ui header"><translate translate-context="Content/Library/Title/Noun">Remote libraries</translate></h1>
+      <p><translate translate-context="Content/Library/Paragraph">Remote libraries are owned by other users on the network. You can access them as long as they are public or you are granted access.</translate></p>
       <scan-form @scanned="scanResult = $event"></scan-form>
       <div class="ui hidden divider"></div>
       <div v-if="scanResult && scanResult.results.length > 0" class="ui two cards">
         <library-card :library="library" v-for="library in scanResult.results" :key="library.fid" />
       </div>
       <template v-if="existingFollows && existingFollows.count > 0">
-        <h2><translate>Known libraries</translate></h2>
-        <i @click="fetch()" :class="['ui', 'circular', 'refresh', 'icon']" /> <translate>Refresh</translate>
+        <h2><translate translate-context="Content/Library/Title">Known libraries</translate></h2>
+        <i @click="fetch()" :class="['ui', 'circular', 'refresh', 'icon']" /> <translate translate-context="Content/*/Button.Label/Short, Verb">Refresh</translate>
         <div class="ui hidden divider"></div>
         <div class="ui two cards">
           <library-card
diff --git a/front/src/views/content/remote/ScanForm.vue b/front/src/views/content/remote/ScanForm.vue
index dc1b2b78b730a98ed8a7940e69c135a863390389..5c68bf130872da28041ac950a25fe9a063f8280b 100644
--- a/front/src/views/content/remote/ScanForm.vue
+++ b/front/src/views/content/remote/ScanForm.vue
@@ -1,13 +1,13 @@
 <template>
   <form class="ui form" @submit.prevent="scan">
     <div v-if="errors.length > 0" class="ui negative message">
-      <div class="header"><translate>Could not fetch remote library</translate></div>
+      <div class="header"><translate translate-context="Content/Library/Error message.Title">Could not fetch remote library</translate></div>
       <ul class="list">
         <li v-for="error in errors">{{ error }}</li>
       </ul>
     </div>
     <div class="ui field">
-      <label><translate>Search a remote library</translate></label>
+      <label><translate translate-context="Content/Library/Input.Label/Verb">Search a remote library</translate></label>
       <div :class="['ui', 'action', {loading: isLoading}, 'input']">
         <input name="url" v-model="query" :placeholder="labels.placeholder" type="url">
         <button type="submit" class="ui icon button">
@@ -47,7 +47,7 @@ export default {
   },
   computed: {
     labels () {
-      let placeholder = this.$gettext('Enter a library URL')
+      let placeholder = this.$pgettext('Content/Library/Input.Placeholder', 'Enter a library URL')
       return {
         placeholder
       }
diff --git a/front/src/views/playlists/Detail.vue b/front/src/views/playlists/Detail.vue
index 69639bd18b54c968ce4a75c0d5392ef31f0ae9bc..6fe7a4c8a1874d588b30363209aaf62ed4fdfcb0 100644
--- a/front/src/views/playlists/Detail.vue
+++ b/front/src/views/playlists/Detail.vue
@@ -13,7 +13,8 @@
               <translate
                 translate-plural="Playlist containing %{ count } tracks, by %{ username }"
                 :translate-n="playlist.tracks_count"
-                :translate-params="{count: playlist.tracks_count, username: playlist.user.username}">
+                :translate-params="{count: playlist.tracks_count, username: playlist.user.username}"
+                translate-context="Content/Playlist/Header.Subtitle">
                 Playlist containing %{ count } track, by %{ username }
               </translate><br>
               <duration :seconds="playlist.duration" />
@@ -21,22 +22,22 @@
           </div>
         </h2>
         <div class="ui hidden divider"></div>
-        <play-button class="orange" :is-playable="playlist.is_playable" :tracks="tracks"><translate>Play all</translate></play-button>
+        <play-button class="orange" :is-playable="playlist.is_playable" :tracks="tracks"><translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate></play-button>
         <button
-          class="ui icon button"
+          class="ui icon labeled button"
           v-if="$store.state.auth.profile && playlist.user.id === $store.state.auth.profile.id"
           @click="edit = !edit">
           <i class="pencil icon"></i>
-          <template v-if="edit"><translate>End edition</translate></template>
-          <template v-else><translate>Edit…</translate></template>
+          <template v-if="edit"><translate translate-context="Content/Playlist/Button.Label/Verb">End edition</translate></template>
+          <template v-else><translate translate-context="Content/*/Button.Label/Verb">Edit</translate></template>
         </button>
         <dangerous-button v-if="$store.state.auth.profile && playlist.user.id === $store.state.auth.profile.id" class="labeled icon" :action="deletePlaylist">
-          <i class="trash icon"></i> <translate>Delete</translate>
-          <p slot="modal-header" v-translate="{playlist: playlist.name}" :translate-params="{playlist: playlist.name}">
+          <i class="trash icon"></i> <translate translate-context="*/*/*/Verb">Delete</translate>
+          <p slot="modal-header" v-translate="{playlist: playlist.name}" translate-context="Popup/Playlist/Title/Call to action" :translate-params="{playlist: playlist.name}">
             Do you want to delete the playlist "%{ playlist }"?
           </p>
-          <p slot="modal-content"><translate>This will completely delete this playlist and cannot be undone.</translate></p>
-          <p slot="modal-confirm"><translate>Delete playlist</translate></p>
+          <p slot="modal-content"><translate translate-context="Popup/Playlist/Paragraph">This will completely delete this playlist and cannot be undone.</translate></p>
+          <div slot="modal-confirm"><translate translate-context="Popup/Playlist/Button.Label/Verb">Delete playlist</translate></div>
         </dangerous-button>
       </div>
     </section>
@@ -48,7 +49,7 @@
           :playlist="playlist" :playlist-tracks="playlistTracks"></playlist-editor>
       </template>
       <template v-else>
-        <h2><translate>Tracks</translate></h2>
+        <h2><translate translate-context="*/*/*/Noun">Tracks</translate></h2>
         <track-table :display-position="true" :tracks="tracks"></track-table>
       </template>
     </section>
@@ -87,7 +88,7 @@ export default {
   computed: {
     labels() {
       return {
-        playlist: this.$gettext("Playlist")
+        playlist: this.$pgettext('Head/Playlist/Title', 'Playlist')
       }
     }
   },
diff --git a/front/src/views/playlists/List.vue b/front/src/views/playlists/List.vue
index 15cc94be431efd6fe67336718b7423c3628d1c67..160b7b83c3785ee44bb3b449c97ef99bc54a756b 100644
--- a/front/src/views/playlists/List.vue
+++ b/front/src/views/playlists/List.vue
@@ -1,21 +1,21 @@
 <template>
   <main v-title="labels.playlists">
     <section class="ui vertical stripe segment">
-      <h2 class="ui header"><translate>Browsing playlists</translate></h2>
+      <h2 class="ui header"><translate translate-context="Content/Playlist/Title">Browsing playlists</translate></h2>
       <div :class="['ui', {'loading': isLoading}, 'form']">
         <template v-if="$store.state.auth.authenticated">
           <button
             @click="$store.commit('playlists/chooseTrack', null)"
-            class="ui basic green button"><translate>Manage your playlists</translate></button>
+            class="ui basic green button"><translate translate-context="Content/Playlist/Button.Label/Verb">Manage your playlists</translate></button>
           <div class="ui hidden divider"></div>
         </template>
         <div class="fields">
           <div class="field">
-            <label><translate>Search</translate></label>
+            <label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
             <input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
           </div>
           <div class="field">
-            <label><translate>Ordering</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
             <select class="ui dropdown" v-model="ordering">
               <option v-for="option in orderingOptions" :value="option[0]">
                 {{ sharedLabels.filters[option[1]] }}
@@ -23,14 +23,14 @@
             </select>
           </div>
           <div class="field">
-            <label><translate>Order</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Order</translate></label>
             <select class="ui dropdown" v-model="orderingDirection">
-              <option value="+"><translate>Ascending</translate></option>
-              <option value="-"><translate>Descending</translate></option>
+              <option value="+"><translate translate-context="Content/Search/Dropdown">Ascending</translate></option>
+              <option value="-"><translate translate-context="Content/Search/Dropdown">Descending</translate></option>
             </select>
           </div>
           <div class="field">
-            <label><translate>Results per page</translate></label>
+            <label><translate translate-context="Content/Search/Dropdown.Label/Noun">Results per page</translate></label>
             <select class="ui dropdown" v-model="paginateBy">
               <option :value="parseInt(12)">12</option>
               <option :value="parseInt(25)">25</option>
@@ -103,8 +103,8 @@ export default {
   },
   computed: {
     labels() {
-      let playlists = this.$gettext("Playlists")
-      let searchPlaceholder = this.$gettext("Enter playlist name…")
+      let playlists = this.$pgettext('*/*/*', 'Playlists')
+      let searchPlaceholder = this.$pgettext('Content/Playlist/Placeholder/Call to action', 'Enter playlist name…')
       return {
         playlists,
         searchPlaceholder
diff --git a/front/src/views/radios/Detail.vue b/front/src/views/radios/Detail.vue
index 61a7553edb3efe22667a20fe35c64f99886bf8fd..d15aaf366a73477d445212ef2210c5d6d4f94a3f 100644
--- a/front/src/views/radios/Detail.vue
+++ b/front/src/views/radios/Detail.vue
@@ -18,21 +18,21 @@
         <div class="ui hidden divider"></div>
         <radio-button type="custom" :custom-radio-id="radio.id"></radio-button>
         <template v-if="$store.state.auth.username === radio.user.username">
-          <router-link class="ui icon button" :to="{name: 'library.radios.edit', params: {id: radio.id}}" exact>
+          <router-link class="ui icon labeled button" :to="{name: 'library.radios.edit', params: {id: radio.id}}" exact>
             <i class="pencil icon"></i>
             Edit…
           </router-link>
           <dangerous-button class="labeled icon" :action="deleteRadio">
             <i class="trash icon"></i> Delete
-            <p slot="modal-header" v-translate="{radio: radio.name}" :translate-params="{radio: radio.name}">Do you want to delete the radio "%{ radio }"?</p>
-            <p slot="modal-content"><translate>This will completely delete this radio and cannot be undone.</translate></p>
-            <p slot="modal-confirm"><translate>Delete radio</translate></p>
+            <p slot="modal-header" v-translate="{radio: radio.name}"  translate-context="Popup/Radio/Title" :translate-params="{radio: radio.name}">Do you want to delete the radio "%{ radio }"?</p>
+            <p slot="modal-content"><translate translate-context="Popup/Radio/Paragraph">This will completely delete this radio and cannot be undone.</translate></p>
+            <p slot="modal-confirm"><translate translate-context="Popup/Radio/Button.Label/Verb">Delete radio</translate></p>
           </dangerous-button>
         </template>
       </div>
     </section>
     <section class="ui vertical stripe segment">
-      <h2><translate>Tracks</translate></h2>
+      <h2><translate translate-context="*/*/*/Noun">Tracks</translate></h2>
       <track-table :tracks="tracks"></track-table>
       <div class="ui center aligned basic segment">
         <pagination
@@ -77,7 +77,7 @@ export default {
   computed: {
     labels() {
       return {
-        title: this.$gettext("Radio")
+        title: this.$pgettext('Head/Radio/Title', "Radio")
       }
     }
   },
diff --git a/front/yarn.lock b/front/yarn.lock
index db05be080c2249c397b35053a871a58e6162e283..5d20f4ac1bea08bd5ab6eb8cbd1fe27de24d78b4 100644
--- a/front/yarn.lock
+++ b/front/yarn.lock
@@ -2960,6 +2960,11 @@ diff@3.5.0, diff@^3.5.0:
   resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
   integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
 
+diff@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff"
+  integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==
+
 diffie-hellman@^5.0.0:
   version "5.0.3"
   resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
diff --git a/pyproject.toml b/pyproject.toml
index 68682d243c231a3fed2f52e5948b9507df9bd42f..21dd7c106dc42ca536762624c3b387610de3824b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -41,3 +41,6 @@
         directory = "misc"
         name = "Other"
         showcontent = true
+
+[tool.black]
+    exclude = "(.git|.hg|.mypy_cache|.tox|.venv|_build|buck-out|build|dist|migrations)"