feat(device-sync): USB/SD card sync page (WIP)

Adds a new Device Sync page for transferring music from Navidrome to
USB drives or SD cards. Sidebar entry is hidden by default.

- Four new Tauri commands: sync_track_to_device, compute_sync_paths,
  list_device_dir_files, delete_device_file
- Filename template engine with cross-platform path sanitization
- 4-concurrent-worker download, live progress via device:sync:progress event
- Persistent source list (albums/playlists/artists) with checkbox deletion
- Expandable artist tree in browser panel (per-album selection)
- i18n: DE + EN complete; other locales have stub keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-14 00:02:13 +02:00
parent 58f99ae846
commit 17a5c92174
15 changed files with 1341 additions and 2 deletions
+28
View File
@@ -24,6 +24,7 @@ export const nlTranslation = {
mostPlayed: 'Meest gespeeld',
radio: 'Internetradio',
folderBrowser: 'Mappenverkenner',
deviceSync: 'Apparaatsync',
libraryScope: 'Bibliotheekbereik',
allLibraries: 'Alle bibliotheken',
expandPlaylists: 'Afspeellijsten uitklappen',
@@ -1016,4 +1017,31 @@ export const nlTranslation = {
empty: 'Lege map',
error: 'Laden mislukt',
},
deviceSync: {
title: 'Apparaatsync',
targetFolder: 'Doelmap',
noFolderChosen: 'Geen map gekozen',
chooseFolder: 'Kiezen…',
filenameTemplate: 'Bestandsnaamsjabloon',
templateHint: 'Variabelen: {artist}, {album}, {title}, {track_number}, {disc_number}, {year}',
cleanupButton: 'Niet-geselecteerde bestanden verwijderen',
cleanupNothingToDelete: 'Niets te verwijderen — apparaat is al gesynchroniseerd.',
confirmCleanup: '{{count}} bestand(en) verwijderen van het apparaat die niet in de huidige selectie staan. Doorgaan?',
cleanupComplete: '{{count}} bestand(en) van het apparaat verwijderd.',
selectedSources: 'Geselecteerde bronnen',
noSourcesSelected: 'Geen bronnen geselecteerd. Klik op items in de browser om ze toe te voegen.',
clearAll: 'Alles wissen',
tabPlaylists: 'Afspeellijsten',
tabAlbums: 'Albums',
tabArtists: 'Artiesten',
searchPlaceholder: 'Zoeken…',
syncButton: 'Synchroniseren naar apparaat',
cancel: 'Annuleren',
noTargetDir: 'Kies eerst een doelmap.',
noSources: 'Selecteer minimaal één bron.',
noTracks: 'Geen nummers gevonden in de geselecteerde bronnen.',
fetchError: 'Ophalen van nummers van de server mislukt.',
syncComplete: 'Synchronisatie voltooid.',
dismiss: 'Sluiten',
},
};