fix(analysis): persist failed tracks and reconcile progress counts (#867)

* fix(analysis): persist failed-track suppression and reduce aggressive polling

Persist unsupported/broken analysis tracks as failed entries and expose them in Settings with track metadata, export, and targeted rescan actions. Also make aggressive-mode completion checks cheap by gating re-entry on live track-count changes with a startup seed and 5-minute recheck cadence.

* fix(analysis): mark unsupported decode tracks as failed in cpu-seed

When full-seed falls back to waveform-only (no EBU loudness) or enrichment decode fails, persist analysis_track status as failed so aggressive backfill does not requeue the same unsupported tracks indefinitely.

* fix(analysis): reconcile legacy ready tracks without loudness

Auto-mark legacy ready tracks that only miss loudness as failed during needs-work checks so analysis progress converges instead of staying permanently pending.

* docs(changelog): add failed-analysis recovery notes for PR 867

Document persistent failed-track handling, analytics strategy controls, and low-cost aggressive-mode recheck behavior in the 1.47.0 changelog.

* fix(i18n): align settings locale coverage across all languages

Sync missing Settings keys for all shipped locales and replace recent English fallbacks with localized strings so analytics and backup UI text stays consistent outside en/ru.
This commit is contained in:
cucadmuh
2026-05-25 01:37:15 +03:00
committed by GitHub
parent 820f71c421
commit bc85065316
21 changed files with 1263 additions and 17 deletions
+70
View File
@@ -517,4 +517,74 @@ export const settings = {
floatingPlayerBarSub: 'Houd de spelerbalk zwevend boven de inhoud',
uiScaleTitle: 'Interface schaal',
uiScaleLabel: 'Zoom',
confirmDeleteServerLibrary: 'Ook de lokale bibliotheekindex van deze server verwijderen? Klik op Annuleren om de gecachte kopie voor offline gebruik te behouden.',
waveformCacheClearBtn: 'Waveform-cache wissen',
waveformCacheCleared: 'Waveform-cache gewist ({{count}} rijen).',
waveformCacheClearFailed: 'Waveform-cache wissen mislukt.',
useCustomTitlebar: 'Aangepaste titelbalk',
useCustomTitlebarDesc: 'Vervang de systeemtitelbalk door een ingebouwde balk die bij het app-thema past. Schakel uit om de native GNOME/GTK-titelbalk te gebruiken.',
analyticsStrategyTitle: 'Analysestrategieën',
analyticsStrategyDesc: 'Kies de analysemethode voor de bibliotheek.',
analyticsStrategyLabel: 'Strategie',
analyticsStrategyLazy: 'Lui',
analyticsStrategyLazyDesc: 'Analyseert alleen wanneer tracks worden afgespeeld of in de hot/offline-cache terechtkomen — minimaal CPU- en netwerkgebruik.',
analyticsStrategyAdvanced: 'Agressief',
analyticsStrategyAdvancedDesc: 'Agressievere achtergrondscan. Na voltooiing krijg je BPM voor alle tracks plus directe loudness- en waveform-lading.',
analyticsStrategyPriorityTitle: 'Analyseprioriteit (altijd actief)',
analyticsStrategyPriorityHigh: '1 — Nu afspelen: eerst downloaden en analyseren (playback-bytes, loudness-backfill of HTTP indien nodig).',
analyticsStrategyPriorityMiddle: '2 — Hierna: de volgende ~5 wachtrijtracks, preload-next en hot-cache-buren — analyse vanuit cache/downloads waar mogelijk; HTTP-backfill alleen bij miss.',
analyticsStrategyPriorityLow: '3 — Bibliotheekbatch (alleen Agressief): automatische achtergrondwachtrij achteraan; wordt bijgevuld via watermark (~3× workers) zonder op een lege wachtrij te wachten.',
analyticsStrategyServerLabel: 'Server',
analyticsStrategyProgressLabel: 'Analysevoortgang:',
analyticsStrategyProgressValue: '{{percent}}% ({{done}}/{{total}})',
analyticsStrategyActionsLabel: 'Acties',
analyticsStrategyParallelismLabel: 'Parallelle workers',
analyticsStrategyParallelismValue: '{{n}} threads',
analyticsStrategyParallelismDesc: 'Hoeveel tracks tegelijk worden gedownload en geanalyseerd (HTTP + CPU). Hogere waarden versnellen het inhalen van de bibliotheek, maar gebruiken meer netwerk en CPU.',
analyticsStrategyAdvancedWarning: 'Agressief gebruikt meer CPU en netwerkbandbreedte terwijl de bibliotheekbatch op de achtergrond draait.',
analyticsStrategyServerRemoved: 'Verwijderde server',
analyticsStrategyClearAction: 'Analyse wissen',
analyticsStrategyClearTitle: 'Analyse wissen?',
analyticsStrategyClearDesc: 'Analyse wissen voor {{server}} verwijdert gecachte waveforms en loudness. Deze server later opnieuw toevoegen kan een lange herindexering vereisen.',
analyticsStrategyClearCancel: 'Annuleren',
analyticsStrategyClearConfirm: 'Analyse wissen',
analyticsStrategyClearSuccess: 'Analyse gewist voor de verwijderde server.',
analyticsStrategyClearError: 'Analyse wissen voor de verwijderde server mislukt.',
analyticsStrategyProgressEmptyAfterFailed: '100% (0/0, geblokkeerd door mislukte tracks)',
analyticsFailedTracksOpenTitle: 'Mislukte tracks: {{count}}',
analyticsFailedTracksTitle: 'Mislukte analysetracks — {{server}}',
analyticsFailedTracksDesc: 'Deze tracks faalden herhaaldelijk bij decode/enrichment en zijn uitgesloten van automatische achtergrondanalyse.',
analyticsFailedTracksLoading: 'Lijst met mislukte tracks laden…',
analyticsFailedTracksEmpty: 'Geen mislukte tracks voor deze server.',
analyticsFailedTracksClose: 'Sluiten',
analyticsFailedTracksExport: 'Lijst exporteren',
analyticsFailedTracksExportSuccess: 'Lijst met mislukte tracks geëxporteerd ({{count}}).',
analyticsFailedTracksExportError: 'Lijst met mislukte tracks kon niet worden geëxporteerd.',
analyticsFailedTracksRescan: 'Mislukte tracks opnieuw scannen',
analyticsFailedTracksRescanSuccess: 'Opnieuw scannen ingepland voor {{count}} mislukte tracks.',
analyticsFailedTracksRescanError: 'Mislukte tracks opnieuw scannen mislukt.',
analyticsFailedTracksLoadError: 'Mislukte tracks konden niet worden geladen.',
backupImportAny: 'Back-up importeren',
backupImportAnyConfirm: 'Geselecteerd back-upbestand importeren en inhoud toepassen (instellingen, bibliotheekdatabases of volledig). Doorgaan?',
backupModeFull: 'Volledig',
backupModeLibrary: 'Bibliotheekdatabases',
backupModeConfig: 'Configuratie',
backupFullDesc: 'Archiveert instellingen en bibliotheekdatabases in één back-upbestand.',
backupFullExport: 'Volledige back-up exporteren',
backupFullImport: 'Volledige back-up importeren',
backupFullImportConfirm: 'Dit overschrijft instellingen, vervangt huidige bibliotheekdatabases en verplaatst ze naar .bak. Doorgaan?',
backupFullExportSuccess: 'Volledige back-up geëxporteerd.',
backupFullImportSuccess: 'Volledige back-up geïmporteerd — herladen…',
backupFullImportError: 'Volledige back-up kon niet worden geïmporteerd.',
backupLibraryExport: 'Databases exporteren',
backupLibraryExportDesc: 'Maakt een gecomprimeerd archief met schone SQLite-snapshots van bibliotheekdatabases.',
backupLibraryImport: 'Databases importeren',
backupLibraryImportDesc: 'Herstelt bibliotheekdatabases uit een archiefbestand. Huidige databases worden voor het omschakelen naar .bak verplaatst.',
backupLibraryImportConfirm: 'Dit vervangt huidige bibliotheekdatabases en verplaatst ze naar .bak. Doorgaan?',
backupLibraryExportSuccess: 'Databaseback-up geëxporteerd.',
backupLibraryImportSuccess: 'Databaseback-up geïmporteerd.',
backupLibraryImportError: 'Databaseback-up kon niet worden geïmporteerd.',
backupOverlayExportTitle: 'Back-up maken…',
backupOverlayImportTitle: 'Back-up herstellen…',
backupOverlayHint: 'Je kunt het venster open laten terwijl we bestanden verwerken. Invoer is tijdelijk vergrendeld.',
};