feat(search): queue pasted share links from Live Search and mobile search

Implement share-link detection in search (track, queue, album, artist,
composer): enqueue tracks/queues without interrupting playback; preview
album/artist/composer without switching the active server; queue preview
modal with scrollable track list. Based on community PR #551.

Co-authored-by: Daniel Wagner <daniel.iuser@icloud.com>
This commit is contained in:
Maxim Isaev
2026-05-15 13:38:35 +03:00
parent 02fd828049
commit e7431b94b8
30 changed files with 2323 additions and 16 deletions
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Stöbern',
emptyHint: 'Was möchtest du hören?',
genres: 'Genres',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Browse',
emptyHint: 'What do you want to hear?',
genres: 'Genres',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Explorar',
emptyHint: '¿Qué quieres escuchar?',
genres: 'Géneros',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Parcourir',
emptyHint: 'Que veux-tu écouter ?',
genres: 'Genres',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Utforsk',
emptyHint: 'Hva vil du høre?',
genres: 'Sjangre',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Bladeren',
emptyHint: 'Wat wil je horen?',
genres: 'Genres',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: 'Răsfoiește',
emptyHint: 'Ce vrei să auzi?',
genres: 'Genuri',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};
+20
View File
@@ -26,4 +26,24 @@ export const search = {
browse: 'Обзор',
emptyHint: 'Что хочешь послушать?',
genres: 'Жанры',
shareLink: 'Ссылка для обмена',
shareTrackTitle: 'Общий трек',
shareQueueTitle_one: 'Общая очередь ({{count}} трек)',
shareQueueTitle_other: 'Общая очередь ({{count}} трека)',
shareQueueTitle_few: 'Общая очередь ({{count}} трека)',
shareQueueTitle_many: 'Общая очередь ({{count}} треков)',
shareQueueAction: 'Добавить в очередь',
shareQueueing: 'Добавление в очередь…',
shareQueued_one: 'В очередь добавлен {{count}} трек',
shareQueued_few: 'В очередь добавлено {{count}} трека',
shareQueued_many: 'В очередь добавлено {{count}} треков',
shareQueued_other: 'В очередь добавлено {{count}} треков',
shareQueuedPartial: 'Добавлено {{queued}} из {{total}} треков ({{skipped}} не найдено).',
shareUnsupportedTitle: 'Эту ссылку нельзя использовать здесь',
shareUnsupportedSub: 'Нужна ссылка на трек, альбом, исполнителя, композитора или очередь.',
shareFromServer: 'С сервера «{{server}}»',
shareQueuePreview: 'Просмотр треков',
shareQueuePreviewLoading: 'Загрузка треков…',
shareQueuePreviewEmpty: 'Треки из этой ссылки не найдены на сервере.',
shareQueuePreviewSkipped: '{{skipped}} из {{total}} треков не найдено на этом сервере.',
};
+16
View File
@@ -26,4 +26,20 @@ export const search = {
browse: '浏览',
emptyHint: '你想听什么?',
genres: '流派',
shareLink: 'Share link',
shareTrackTitle: 'Shared track',
shareQueueTitle_one: 'Shared queue ({{count}} track)',
shareQueueTitle_other: 'Shared queue ({{count}} tracks)',
shareQueueAction: 'Add to queue',
shareQueueing: 'Adding to queue…',
shareQueued_one: 'Added {{count}} shared track to queue',
shareQueued_other: 'Added {{count}} shared tracks to queue',
shareQueuedPartial: 'Added {{queued}} of {{total}} shared tracks to queue ({{skipped}} not found).',
shareUnsupportedTitle: 'This share link cannot be used here',
shareUnsupportedSub: 'Use a track, album, artist, composer, or queue share link.',
shareFromServer: 'From {{server}}',
shareQueuePreview: 'Preview tracks',
shareQueuePreviewLoading: 'Loading tracks…',
shareQueuePreviewEmpty: 'No tracks from this link could be found on the server.',
shareQueuePreviewSkipped: '{{skipped}} of {{total}} tracks were not found on this server.',
};