feat(library): local lossless index, filters, and conserve dedicated page (#871)

* feat(library): local lossless index, filters, and conserve dedicated page

Add SQLite-backed lossless album browse and advanced-search filtering,
wire All Albums and artist/album lossless drill-down mode, and hide the
standalone /lossless-albums nav entry from sidebar visibility settings
(conserved route, default off).

* docs(release): note lossless local index in CHANGELOG and credits (PR #871)
This commit is contained in:
cucadmuh
2026-05-27 00:02:46 +03:00
committed by GitHub
parent 418b25914a
commit a8cfff0b62
65 changed files with 1615 additions and 138 deletions
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Alle Alben · klicken: nur Sampler',
compilationTooltipOnly: 'Nur Sampler · klicken: Sampler ausblenden',
compilationTooltipHide: 'Sampler ausgeblendet · klicken: alle zeigen',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Nur Lossless-Alben · klicken: alle anzeigen',
losslessTooltipOff: 'Nur Lossless-Alben anzeigen',
select: 'Mehrfachauswahl',
startSelect: 'Mehrfachauswahl aktivieren',
cancelSelect: 'Abbrechen',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: 'Download fehlgeschlagen: {{name}}',
offlineQueuing: '{{count}} Album(s) für Offline einreihen…',
offlineFailed: '{{name}} konnte nicht offline hinzugefügt werden',
noFavorites: 'Keine Lieblingsalben entsprechen den aktuellen Filtern.',
noCompilations: 'Keine Sampler entsprechen den aktuellen Filtern.',
noMatchingFilters: 'Keine Alben entsprechen den aktuellen Filtern.',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'Noch keine Lossless-Alben in dieser Bibliothek.',
unsupported: 'Dieser Server liefert keine Metadaten, mit denen sich Lossless-Alben erkennen lassen.',
slowFetchHint: 'Lädt langsamer als andere Album-Seiten — Psysonic geht den gesamten Songkatalog nach Qualität durch.',
modeBanner: 'Lossless-Modus — es werden nur FLAC, WAV und andere verlustfreie Formate angezeigt.',
modeBannerExit: 'Alle Formate anzeigen',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'von',
advancedYearTo: 'bis',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: 'BPM-Filter zurücksetzen',
advancedLossless: 'Format',
advancedLosslessOnly: 'Nur Lossless',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'All albums · click: only compilations',
compilationTooltipOnly: 'Only compilations · click: hide compilations',
compilationTooltipHide: 'Compilations hidden · click: show all',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Lossless albums only · click to show all',
losslessTooltipOff: 'Show lossless albums only',
select: 'Multi-select',
startSelect: 'Enable multi-select',
cancelSelect: 'Cancel',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: 'Failed to download {{name}}',
offlineQueuing: 'Queuing {{count}} album(s) for offline…',
offlineFailed: 'Failed to add {{name}} offline',
noFavorites: 'No favorite albums match the current filters.',
noCompilations: 'No compilations match the current filters.',
noMatchingFilters: 'No albums match the current filters.',
};
+2
View File
@@ -10,7 +10,9 @@ export const artistDetail = {
noRadio: 'No similar tracks found for this artist.',
notFound: 'Artist not found.',
albumsBy: 'Albums by {{name}}',
albumsByLossless: 'Lossless albums by {{name}}',
topTracks: 'Top Tracks',
topTracksLossless: 'Lossless Tracks',
noAlbums: 'No albums found.',
trackTitle: 'Title',
trackAlbum: 'Album',
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'No lossless albums in this library yet.',
unsupported: 'This server does not expose the metadata needed to find lossless albums.',
slowFetchHint: 'Loads slower than other album pages — Psysonic walks the full song catalog by quality.',
modeBanner: 'Lossless mode — showing FLAC, WAV, and other lossless formats only.',
modeBannerExit: 'Show all formats',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'from',
advancedYearTo: 'to',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Measured analysis BPM takes priority over file tags when the local index is enabled',
advancedBpmClear: 'Clear BPM filter',
advancedLossless: 'Format',
advancedLosslessOnly: 'Lossless only',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Todos los álbumes · clic: solo recopilatorios',
compilationTooltipOnly: 'Solo recopilatorios · clic: ocultar recopilatorios',
compilationTooltipHide: 'Recopilatorios ocultos · clic: mostrar todo',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Solo álbumes lossless · clic: mostrar todo',
losslessTooltipOff: 'Mostrar solo álbumes lossless',
select: 'Selección múltiple',
startSelect: 'Activar selección múltiple',
cancelSelect: 'Cancelar',
@@ -29,5 +32,8 @@ export const albums = {
downloadZipFailed: 'Error al descargar {{name}}',
offlineQueuing: 'Encolando {{count}} álbum(es) para offline…',
offlineFailed: 'Error al agregar {{name}} offline',
noFavorites: 'Ningún álbum favorito coincide con los filtros actuales.',
noCompilations: 'Ninguna compilación coincide con los filtros actuales.',
noMatchingFilters: 'Ningún álbum coincide con los filtros actuales.',
addToPlaylist: 'Agregar a Lista de Reproducción',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'Aún no hay álbumes sin pérdidas en esta biblioteca.',
unsupported: 'Este servidor no expone los metadatos necesarios para encontrar álbumes sin pérdidas.',
slowFetchHint: 'Carga más lento que otras páginas de álbumes — Psysonic recorre todo el catálogo de canciones por calidad.',
modeBanner: 'Modo sin pérdidas — solo se muestran FLAC, WAV y otros formatos lossless.',
modeBannerExit: 'Mostrar todos los formatos',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'desde',
advancedYearTo: 'hasta',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: 'Limpiar filtro BPM',
advancedLossless: 'Formato',
advancedLosslessOnly: 'Solo sin pérdida',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Tous les albums · clic : uniquement compilations',
compilationTooltipOnly: 'Uniquement compilations · clic : masquer compilations',
compilationTooltipHide: 'Compilations masquées · clic : tout afficher',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Albums lossless uniquement · clic : tout afficher',
losslessTooltipOff: 'Afficher les albums lossless uniquement',
select: 'Sélection multiple',
startSelect: 'Activer la sélection multiple',
cancelSelect: 'Annuler',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: 'Échec du téléchargement de {{name}}',
offlineQueuing: 'Mise en file d\'attente de {{count}} album(s) hors ligne…',
offlineFailed: 'Échec de l\'ajout de {{name}} hors ligne',
noFavorites: 'Aucun album favori ne correspond aux filtres actuels.',
noCompilations: 'Aucune compilation ne correspond aux filtres actuels.',
noMatchingFilters: 'Aucun album ne correspond aux filtres actuels.',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'Aucun album lossless dans cette bibliothèque pour l\'instant.',
unsupported: 'Ce serveur n\'expose pas les métadonnées nécessaires pour trouver des albums lossless.',
slowFetchHint: 'Chargement plus lent que les autres pages d\'albums — Psysonic parcourt tout le catalogue par qualité.',
modeBanner: 'Mode lossless — affichage de FLAC, WAV et autres formats sans perte uniquement.',
modeBannerExit: 'Afficher tous les formats',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'de',
advancedYearTo: 'à',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: 'Effacer le filtre BPM',
advancedLossless: 'Format',
advancedLosslessOnly: 'Lossless uniquement',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Alle album · klikk: kun samleplater',
compilationTooltipOnly: 'Kun samleplater · klikk: skjul samleplater',
compilationTooltipHide: 'Samleplater skjult · klikk: vis alle',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Kun lossless-album · klikk: vis alle',
losslessTooltipOff: 'Vis kun lossless-album',
select: 'Multivalg',
startSelect: 'Aktiver multivalg',
cancelSelect: 'Avbryt',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: 'Kunne ikke laste ned {{name}}',
offlineQueuing: 'Legger {{count}} album i kø for offline…',
offlineFailed: 'Kunne ikke legge til {{name}} offline',
noFavorites: 'Ingen favorittalbum samsvarer med gjeldende filtre.',
noCompilations: 'Ingen samleplater samsvarer med gjeldende filtre.',
noMatchingFilters: 'Ingen album samsvarer med gjeldende filtre.',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'Ingen lossless-album i dette biblioteket ennå.',
unsupported: 'Denne serveren eksponerer ikke metadata som trengs for å finne lossless-album.',
slowFetchHint: 'Lastes saktere enn andre albumsider — Psysonic går gjennom hele sangkatalogen etter kvalitet.',
modeBanner: 'Lossless-modus — viser kun FLAC, WAV og andre tapsfrie formater.',
modeBannerExit: 'Vis alle formater',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'fra',
advancedYearTo: 'til',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: 'Tøm BPM-filter',
advancedLossless: 'Format',
advancedLosslessOnly: 'Kun lossless',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Alle albums · klik: alleen compilaties',
compilationTooltipOnly: 'Alleen compilaties · klik: compilaties verbergen',
compilationTooltipHide: 'Compilaties verborgen · klik: toon alles',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Alleen lossless-albums · klik: toon alles',
losslessTooltipOff: 'Alleen lossless-albums tonen',
select: 'Meervoudige selectie',
startSelect: 'Meervoudige selectie inschakelen',
cancelSelect: 'Annuleren',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: 'Downloaden van {{name}} mislukt',
offlineQueuing: '{{count}} album(s) in wachtrij voor offline…',
offlineFailed: 'Toevoegen van {{name}} offline mislukt',
noFavorites: 'Geen favoriete albums komen overeen met de huidige filters.',
noCompilations: 'Geen compilaties komen overeen met de huidige filters.',
noMatchingFilters: 'Geen albums komen overeen met de huidige filters.',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'Nog geen lossless-albums in deze bibliotheek.',
unsupported: 'Deze server biedt geen metadata om lossless-albums te vinden.',
slowFetchHint: 'Laadt langzamer dan andere albumpagina\'s — Psysonic doorloopt de volledige songcatalogus op kwaliteit.',
modeBanner: 'Lossless-modus — alleen FLAC, WAV en andere verliesvrije formaten.',
modeBannerExit: 'Alle formaten tonen',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'van',
advancedYearTo: 'tot',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: 'BPM-filter wissen',
advancedLossless: 'Formaat',
advancedLosslessOnly: 'Alleen lossless',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Toate albumele · clic: doar compilații',
compilationTooltipOnly: 'Doar compilații · clic: ascunde compilațiile',
compilationTooltipHide: 'Compilații ascunse · clic: arată toate',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Doar albume lossless · clic: arată toate',
losslessTooltipOff: 'Arată doar albume lossless',
select: 'Multi-selecție',
startSelect: 'Activează multi-selecția',
cancelSelect: 'Anulează',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: 'Nu s-a reușit descărcarea {{name}}',
offlineQueuing: 'Se adaugă în coadă {{count}} album(e) pentru offline…',
offlineFailed: 'Nu s-a reușit adăugarea {{name}} offline',
noFavorites: 'Niciun album favorit nu corespunde filtrelor curente.',
noCompilations: 'Nicio compilație nu corespunde filtrelor curente.',
noMatchingFilters: 'Niciun album nu corespunde filtrelor curente.',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'Niciun album lossless în această librărie încă.',
unsupported: 'Acest server nu expune metadata necesară pentru a găsi albumele lossless.',
slowFetchHint: 'Se încarcă mai încet decât alte pagini de album — Psysonic parcurge prin tot catalogul pieselor după calitate.',
modeBanner: 'Mod lossless — se afișează doar FLAC, WAV și alte formate fără pierderi.',
modeBannerExit: 'Afișează toate formatele',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'de la',
advancedYearTo: 'până la',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: 'Golește filtrul BPM',
advancedLossless: 'Format',
advancedLosslessOnly: 'Doar lossless',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: 'Все альбомы · клик: только сборники',
compilationTooltipOnly: 'Только сборники · клик: скрыть сборники',
compilationTooltipHide: 'Сборники скрыты · клик: показать всё',
losslessLabel: 'Lossless',
losslessTooltipOn: 'Только lossless-альбомы · клик: показать все',
losslessTooltipOff: 'Показать только lossless-альбомы',
select: 'Множественный выбор',
startSelect: 'Включить множественный выбор',
cancelSelect: 'Отмена',
@@ -33,4 +36,7 @@ export const albums = {
downloadZipFailed: 'Не удалось скачать {{name}}',
offlineQueuing: 'Добавление {{count}} альбом(ов) в офлайн…',
offlineFailed: 'Не удалось добавить {{name}} офлайн',
noFavorites: 'Нет избранных альбомов с текущими фильтрами.',
noCompilations: 'Нет сборников с текущими фильтрами.',
noMatchingFilters: 'Нет альбомов с текущими фильтрами.',
};
+2
View File
@@ -10,7 +10,9 @@ export const artistDetail = {
noRadio: 'Похожие треки для этого исполнителя не найдены.',
notFound: 'Исполнитель не найден.',
albumsBy: 'Альбомы — {{name}}',
albumsByLossless: 'Lossless-альбомы — {{name}}',
topTracks: 'Популярные треки',
topTracksLossless: 'Lossless-треки',
noAlbums: 'Альбомов нет.',
trackTitle: 'Название',
trackAlbum: 'Альбом',
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: 'В этой библиотеке пока нет lossless-альбомов.',
unsupported: 'Этот сервер не предоставляет метаданные, необходимые для поиска lossless-альбомов.',
slowFetchHint: 'Загружается медленнее других страниц альбомов — Psysonic проходит весь каталог песен по качеству.',
modeBanner: 'Режим lossless — показаны только FLAC, WAV и другие форматы без потерь.',
modeBannerExit: 'Показать все форматы',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: 'от',
advancedYearTo: 'до',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Тег BPM и измеренный анализ — при включённом локальном индексе; анализ приоритетнее тега',
advancedBpmClear: 'Сбросить BPM',
advancedLossless: 'Формат',
advancedLosslessOnly: 'Только lossless',
bpmSourceTag: 'BPM из тега файла',
bpmSourceAnalysis: 'BPM из анализа аудио',
advancedMoodGroup: 'Настроение',
+6
View File
@@ -14,6 +14,9 @@ export const albums = {
compilationTooltipAll: '所有专辑 · 点击:仅合辑',
compilationTooltipOnly: '仅合辑 · 点击:隐藏合辑',
compilationTooltipHide: '已隐藏合辑 · 点击:显示全部',
losslessLabel: '无损',
losslessTooltipOn: '仅无损专辑 · 点击:显示全部',
losslessTooltipOff: '仅显示无损专辑',
select: '多选',
startSelect: '启用多选',
cancelSelect: '取消',
@@ -29,4 +32,7 @@ export const albums = {
downloadZipFailed: '下载 {{name}} 失败',
offlineQueuing: '正在将 {{count}} 张专辑加入离线队列…',
offlineFailed: '添加 {{name}} 离线失败',
noFavorites: '没有符合当前筛选条件的收藏专辑。',
noCompilations: '没有符合当前筛选条件的合辑。',
noMatchingFilters: '没有符合当前筛选条件的专辑。',
};
+2
View File
@@ -2,4 +2,6 @@ export const losslessAlbums = {
empty: '此媒体库中还没有无损专辑。',
unsupported: '此服务器未公开查找无损专辑所需的元数据。',
slowFetchHint: '加载比其他专辑页面慢 — Psysonic 按音质遍历整个歌曲目录。',
modeBanner: '无损模式 — 仅显示 FLAC、WAV 等无损格式。',
modeBannerExit: '显示所有格式',
};
+2 -1
View File
@@ -23,8 +23,9 @@ export const search = {
advancedYearFrom: '从',
advancedYearTo: '至',
advancedBpm: 'BPM',
advancedBpmLocalNote: 'Uses tag BPM and measured analysis when the local index is enabled',
advancedBpmClear: '清除 BPM 筛选',
advancedLossless: '格式',
advancedLosslessOnly: '仅无损',
bpmSourceTag: 'BPM from file tag',
bpmSourceAnalysis: 'BPM from audio analysis',
advancedMoodGroup: 'Mood',