mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 14:55:43 +00:00
refactor(i18n): split locale files into per-namespace modules (Phase K) (#688)
Each src/locales/<lang>.ts (~1800 LOC) becomes a folder src/locales/<lang>/ with one module per i18n namespace (44 each) plus an index.ts barrel that reassembles <lang>Translation in the original key order. Mechanical, script-driven split with a JSON round-trip check: every locale object is byte-identical to its pre-split form. i18n.ts is unchanged — './locales/<lang>' now resolves to the folder index. The per-namespace settings.ts files land ~440-460 LOC; a single i18n namespace is the natural, non-arbitrary split unit for a flat string table, so they are intentionally left whole.
This commit is contained in:
committed by
GitHub
parent
ec112922a2
commit
2409a1fec8
-1870
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
export const albumDetail = {
|
||||
back: 'Zurück',
|
||||
orbitDoubleClickHint: 'Doppelklick fügt diesen Titel zur Orbit-Queue hinzu',
|
||||
playAll: 'Alle abspielen',
|
||||
shareAlbum: 'Album teilen',
|
||||
enqueue: 'Einreihen',
|
||||
enqueueTooltip: 'Ganzes Album zur Warteschlange hinzufügen',
|
||||
artistBio: 'Künstler-Bio',
|
||||
download: 'Download (ZIP)',
|
||||
downloading: 'Lade…',
|
||||
cacheOffline: 'Offline verfügbar machen',
|
||||
offlineCached: 'Offline verfügbar',
|
||||
offlineDownloading: 'Wird gecacht… ({{n}}/{{total}})',
|
||||
removeOffline: 'Offline-Cache löschen',
|
||||
offlineStorageFull: 'Offline-Speicher voll (Limit: {{mb}} MB). Lösche ein Album aus der Offline-Bibliothek oder erhöhe das Limit in den Einstellungen.',
|
||||
offlineStorageGoToSettings: 'Einstellungen',
|
||||
offlineStorageGoToLibrary: 'Offline-Bibliothek',
|
||||
favoriteAdd: 'Zu Favoriten hinzufügen',
|
||||
favoriteRemove: 'Aus Favoriten entfernen',
|
||||
favorite: 'Als Favorit',
|
||||
noBio: 'Keine Biografie verfügbar.',
|
||||
moreByArtist: 'Mehr von {{artist}}',
|
||||
tracksCount: '{{n}} Tracks',
|
||||
goToArtist: 'Zu {{artist}} wechseln',
|
||||
moreLabelAlbums: 'Weitere Alben von {{label}} anzeigen',
|
||||
trackTitle: 'Titel',
|
||||
trackAlbum: 'Album',
|
||||
trackArtist: 'Interpret',
|
||||
trackGenre: 'Genre',
|
||||
trackFormat: 'Format',
|
||||
trackFavorite: 'Favorit',
|
||||
trackRating: 'Bewertung',
|
||||
trackDuration: 'Dauer',
|
||||
trackTotal: 'Gesamt',
|
||||
columns: 'Spalten',
|
||||
resetColumns: 'Zurücksetzen',
|
||||
notFound: 'Album nicht gefunden.',
|
||||
bioModal: 'Künstler-Biografie',
|
||||
bioClose: 'Schließen',
|
||||
ratingLabel: 'Bewertung',
|
||||
enlargeCover: 'Vergrößern',
|
||||
filterSongs: 'Titel filtern…',
|
||||
sortNatural: 'Reihenfolge',
|
||||
sortByTitle: 'A–Z (Titel)',
|
||||
sortByArtist: 'A–Z (Künstler)',
|
||||
sortByAlbum: 'A–Z (Album)',
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
export const albums = {
|
||||
title: 'Alle Alben',
|
||||
sortByName: 'A–Z (Album)',
|
||||
sortByArtist: 'A–Z (Künstler)',
|
||||
sortNewest: 'Neueste zuerst',
|
||||
sortRandom: 'Zufällig',
|
||||
yearFrom: 'Von',
|
||||
yearTo: 'Bis',
|
||||
yearFilterClear: 'Jahresfilter zurücksetzen',
|
||||
yearFilterLabel: 'Jahr',
|
||||
compilationLabel: 'Sampler',
|
||||
compilationOnly: 'Nur Sampler',
|
||||
compilationHide: 'Ohne Sampler',
|
||||
compilationTooltipAll: 'Alle Alben · klicken: nur Sampler',
|
||||
compilationTooltipOnly: 'Nur Sampler · klicken: Sampler ausblenden',
|
||||
compilationTooltipHide: 'Sampler ausgeblendet · klicken: alle zeigen',
|
||||
select: 'Mehrfachauswahl',
|
||||
startSelect: 'Mehrfachauswahl aktivieren',
|
||||
cancelSelect: 'Abbrechen',
|
||||
selectionCount: '{{count}} ausgewählt',
|
||||
downloadZips: 'ZIPs herunterladen',
|
||||
addOffline: 'Offline hinzufügen',
|
||||
enqueueSelected_one: 'Einreihen ({{count}})',
|
||||
enqueueSelected_other: 'Einreihen ({{count}})',
|
||||
enqueueQueued_one: '{{count}} Album zur Warteschlange hinzugefügt',
|
||||
enqueueQueued_other: '{{count}} Alben zur Warteschlange hinzugefügt',
|
||||
downloadingZip: 'Lade {{current}}/{{total}} herunter: {{name}}',
|
||||
downloadZipDone: '{{count}} ZIP(s) heruntergeladen',
|
||||
downloadZipFailed: 'Download fehlgeschlagen: {{name}}',
|
||||
offlineQueuing: '{{count}} Album(s) für Offline einreihen…',
|
||||
offlineFailed: '{{name}} konnte nicht offline hinzugefügt werden',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export const artistDetail = {
|
||||
back: 'Zurück',
|
||||
albums: 'Alben',
|
||||
album: 'Album',
|
||||
playAll: 'Alle abspielen',
|
||||
shareArtist: 'Künstler teilen',
|
||||
shuffle: 'Zufallswiedergabe',
|
||||
radio: 'Radio',
|
||||
loading: 'Lädt…',
|
||||
noRadio: 'Keine ähnlichen Titel für diesen Künstler gefunden.',
|
||||
notFound: 'Künstler nicht gefunden.',
|
||||
albumsBy: 'Alben von {{name}}',
|
||||
topTracks: 'Beliebteste Titel',
|
||||
noAlbums: 'Keine Alben gefunden.',
|
||||
trackTitle: 'Titel',
|
||||
trackAlbum: 'Album',
|
||||
trackDuration: 'Dauer',
|
||||
favoriteAdd: 'Zu Favoriten hinzufügen',
|
||||
favoriteRemove: 'Aus Favoriten entfernen',
|
||||
favorite: 'Als Favorit',
|
||||
albumCount_one: '{{count}} Album',
|
||||
albumCount_other: '{{count}} Alben',
|
||||
openedInBrowser: 'Im Browser geöffnet',
|
||||
featuredOn: 'Auch enthalten auf',
|
||||
similarArtists: 'Ähnliche Künstler',
|
||||
cacheOffline: 'Diskografie offline speichern',
|
||||
offlineCached: 'Diskografie gecacht',
|
||||
offlineDownloading: 'Wird gecacht… ({{done}}/{{total}} Alben)',
|
||||
uploadImage: 'Künstlerbild hochladen',
|
||||
uploadImageError: 'Bild konnte nicht hochgeladen werden',
|
||||
releaseTypes: {
|
||||
album: 'Album',
|
||||
ep: 'EP',
|
||||
single: 'Single',
|
||||
compilation: 'Kompilation',
|
||||
live: 'Live',
|
||||
soundtrack: 'Soundtrack',
|
||||
remix: 'Remix',
|
||||
other: 'Sonstige',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
export const artists = {
|
||||
title: 'Künstler',
|
||||
search: 'Suchen…',
|
||||
all: 'Alle',
|
||||
gridView: 'Gitteransicht',
|
||||
listView: 'Listenansicht',
|
||||
imagesOn: 'Künstlerbilder aktiv — kann Netzwerk- und Systemlast erhöhen',
|
||||
imagesOff: 'Künstlerbilder deaktiviert — zeigt nur Initialen',
|
||||
loadMore: 'Mehr laden',
|
||||
notFound: 'Keine Künstler gefunden.',
|
||||
albumCount_one: '{{count}} Album',
|
||||
albumCount_other: '{{count}} Alben',
|
||||
selectionCount: '{{count}} ausgewählt',
|
||||
select: 'Mehrfachauswahl',
|
||||
startSelect: 'Mehrfachauswahl aktivieren',
|
||||
cancelSelect: 'Abbrechen',
|
||||
addToPlaylist: 'Zur Playlist hinzufügen',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export const changelog = {
|
||||
modalTitle: 'Was ist neu',
|
||||
dontShowAgain: 'Nicht mehr anzeigen',
|
||||
close: 'Verstanden',
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
export const common = {
|
||||
albums: 'Alben',
|
||||
album: 'Album',
|
||||
loading: 'Lade…',
|
||||
loadingMore: 'Lade…',
|
||||
loadingPlaylists: 'Lade Playlists…',
|
||||
noAlbums: 'Keine Alben gefunden.',
|
||||
downloading: 'Lade…',
|
||||
downloadZip: 'Download (ZIP)',
|
||||
back: 'Zurück',
|
||||
cancel: 'Abbrechen',
|
||||
close: 'Schließen',
|
||||
save: 'Speichern',
|
||||
delete: 'Löschen',
|
||||
use: 'Verwenden',
|
||||
add: 'Hinzufügen',
|
||||
new: 'Neu',
|
||||
active: 'Aktiv',
|
||||
download: 'Herunterladen',
|
||||
chooseDownloadFolder: 'Download-Ordner wählen',
|
||||
noFolderSelected: 'Kein Ordner ausgewählt',
|
||||
rememberDownloadFolder: 'Ordner merken',
|
||||
filterGenre: 'Genre-Filter',
|
||||
filterSearchGenres: 'Genres suchen…',
|
||||
filterNoGenres: 'Keine Genres gefunden',
|
||||
filterClear: 'Zurücksetzen',
|
||||
favorites: 'Favoriten',
|
||||
favoritesTooltipOff: 'Nur Favoriten anzeigen',
|
||||
favoritesTooltipOn: 'Alle anzeigen',
|
||||
play: 'Abspielen',
|
||||
bulkSelected: '{{count}} ausgewählt',
|
||||
clearSelection: 'Auswahl aufheben',
|
||||
bulkAddToPlaylist: 'Zur Playlist hinzufügen',
|
||||
bulkRemoveFromPlaylist: 'Aus Playlist entfernen',
|
||||
bulkClear: 'Auswahl aufheben',
|
||||
updaterAvailable: 'Update verfügbar',
|
||||
updaterVersion: 'v{{version}} verfügbar',
|
||||
updaterWebsite: 'Website',
|
||||
updaterModalTitle: 'Neue Version verfügbar',
|
||||
updaterChangelog: 'Was ist neu',
|
||||
updaterDownloadBtn: 'Jetzt herunterladen',
|
||||
updaterSkipBtn: 'Version überspringen',
|
||||
updaterRemindBtn: 'Später erinnern',
|
||||
updaterDone: 'Download abgeschlossen',
|
||||
updaterShowFolder: 'Im Ordner anzeigen',
|
||||
updaterInstallHint: 'Psysonic schließen und das Installationsprogramm manuell ausführen.',
|
||||
updaterAurHint: 'Update über AUR installieren:',
|
||||
updaterErrorMsg: 'Download fehlgeschlagen',
|
||||
updaterInstallNow: 'Jetzt installieren',
|
||||
updaterMacReadyTitle: 'Bereit zur Installation',
|
||||
updaterMacReady: 'Das Update wird heruntergeladen, verifiziert und direkt übernommen — keine DMG nötig. Die App startet anschließend automatisch neu.',
|
||||
updaterTrustNotarized: 'Von Apple beglaubigt',
|
||||
updaterTrustSignature: 'Signatur verifiziert',
|
||||
updaterMacDoneTitle: 'Update installiert',
|
||||
updaterRestartingIn: 'Neustart in {{n}}s …',
|
||||
updaterRestarting: 'Neustart läuft …',
|
||||
updaterRestartNow: 'Jetzt neu starten',
|
||||
updaterRetryBtn: 'Erneut versuchen',
|
||||
durationHoursMinutes: '{{hours}} Std. {{minutes}} Min.',
|
||||
durationMinutesOnly: '{{minutes}} Min.',
|
||||
updaterOpenGitHub: 'Auf GitHub öffnen',
|
||||
filters: 'Filter',
|
||||
more: 'mehr',
|
||||
yearRange: 'Jahresbereich',
|
||||
clearAll: 'Alles zurücksetzen',
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export const composerDetail = {
|
||||
back: 'Zurück',
|
||||
notFound: 'Komponist*in nicht gefunden.',
|
||||
about: 'Über diese*n Komponist*in',
|
||||
works: 'Werke',
|
||||
noWorks: 'Keine Werke gefunden.',
|
||||
workCount_one: '{{count}} Werk',
|
||||
workCount_other: '{{count}} Werke',
|
||||
shareComposer: 'Komponist*in teilen',
|
||||
unknownComposer: 'Komponist*in',
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
export const composers = {
|
||||
title: 'Komponist*innen',
|
||||
search: 'Suchen…',
|
||||
notFound: 'Keine Komponist*innen gefunden.',
|
||||
unsupported: 'Komponist-Ansicht benötigt Navidrome 0.55 oder neuer.',
|
||||
loadFailed: 'Komponist*innen konnten nicht geladen werden.',
|
||||
retry: 'Erneut versuchen',
|
||||
involvedIn_one: 'Beteiligt an {{count}} Album',
|
||||
involvedIn_other: 'Beteiligt an {{count}} Alben',
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
export const connection = {
|
||||
connected: 'Verbunden',
|
||||
connectedTo: 'Verbunden mit {{server}}',
|
||||
disconnected: 'Getrennt',
|
||||
disconnectedFrom: '{{server}} nicht erreichbar — klicken für Einstellungen',
|
||||
checking: 'Verbinde…',
|
||||
extern: 'Extern',
|
||||
offlineTitle: 'Keine Serververbindung',
|
||||
offlineSubtitle: '{{server}} ist nicht erreichbar. Prüfe Netzwerk oder Server.',
|
||||
offlineModeBanner: 'Offline-Modus — Wiedergabe aus lokalem Cache',
|
||||
offlineNoCacheBanner: 'Keine Serververbindung — {{server}} nicht erreichbar',
|
||||
offlineLibraryTitle: 'Offline-Bibliothek',
|
||||
offlineLibraryEmpty: 'Noch keine Alben gecacht. Online gehen, Album öffnen und "Offline verfügbar machen" klicken.',
|
||||
offlineAlbumCount: '{{n}} Album',
|
||||
offlineAlbumCount_plural: '{{n}} Alben',
|
||||
offlineFilterAll: 'Alle',
|
||||
offlineFilterAlbums: 'Alben',
|
||||
offlineFilterPlaylists: 'Playlists',
|
||||
offlineFilterArtists: 'Diskografien',
|
||||
retry: 'Erneut versuchen',
|
||||
serverSettings: 'Server-Einstellungen',
|
||||
switchServerTitle: 'Server wechseln',
|
||||
switchServerHint: 'Klicken, um einen anderen gespeicherten Server zu wählen.',
|
||||
manageServers: 'Server verwalten…',
|
||||
switchFailed: 'Wechsel fehlgeschlagen — Server nicht erreichbar.',
|
||||
lastfmConnected: 'Last.fm verbunden als @{{user}}',
|
||||
lastfmSessionInvalid: 'Session ungültig — klicken zum Neu-Verbinden',
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
export const contextMenu = {
|
||||
playNow: 'Direkt abspielen',
|
||||
playNext: 'Als Nächstes abspielen',
|
||||
addToQueue: 'Zur Warteschlange hinzufügen',
|
||||
enqueueAlbum: 'Ganzes Album einreihen',
|
||||
enqueueAlbums_one: '{{count}} Album einreihen',
|
||||
enqueueAlbums_other: '{{count}} Alben einreihen',
|
||||
startRadio: 'Radio starten',
|
||||
instantMix: 'Instant Mix',
|
||||
instantMixFailed: 'Instant Mix konnte nicht erstellt werden — Server- oder Pluginfehler.',
|
||||
cliMixNeedsTrack: 'Es läuft nichts — starte zuerst die Wiedergabe und führe den Mix-Befehl erneut aus.',
|
||||
lfmLove: 'Auf Last.fm liken',
|
||||
lfmUnlove: 'Last.fm-Like entfernen',
|
||||
favorite: 'Favorisieren',
|
||||
favoriteArtist: 'Künstler favorisieren',
|
||||
favoriteAlbum: 'Album favorisieren',
|
||||
unfavorite: 'Aus Favoriten entfernen',
|
||||
unfavoriteArtist: 'Künstler aus Favoriten entfernen',
|
||||
unfavoriteAlbum: 'Album aus Favoriten entfernen',
|
||||
removeFromQueue: 'Diesen Song entfernen',
|
||||
removeFromPlaylist: 'Aus Playlist entfernen',
|
||||
openAlbum: 'Album öffnen',
|
||||
goToArtist: 'Zum Künstler',
|
||||
download: 'Herunterladen (ZIP)',
|
||||
addToPlaylist: 'Zur Playlist hinzufügen',
|
||||
selectedPlaylists: '{{count}} Playlists ausgewählt',
|
||||
selectedAlbums: '{{count}} Alben ausgewählt',
|
||||
selectedArtists: '{{count}} Künstler ausgewählt',
|
||||
songInfo: 'Song-Infos',
|
||||
shareLink: 'Freigabe-Link kopieren',
|
||||
shareCopied: 'Freigabe-Link wurde in die Zwischenablage kopiert.',
|
||||
shareCopyFailed: 'Kopieren in die Zwischenablage fehlgeschlagen.',
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
export const deviceSync = {
|
||||
title: 'Gerätesync',
|
||||
targetFolder: 'Zielordner',
|
||||
noFolderChosen: 'Kein Ordner gewählt',
|
||||
selectDrive: 'Laufwerk auswählen…',
|
||||
refreshDrives: 'Laufwerke aktualisieren',
|
||||
noDrivesDetected: 'Keine Wechseldatenträger erkannt',
|
||||
browseManual: 'Manuell durchsuchen…',
|
||||
free: 'frei',
|
||||
notMountedVolume: 'Ziel befindet sich nicht auf einem eingehängten Laufwerk. Das Gerät wurde möglicherweise getrennt.',
|
||||
chooseFolder: 'Auswählen…',
|
||||
targetDevice: 'Zielgerät',
|
||||
schemaLabel: 'Benennungsschema',
|
||||
schemaHint: 'Festes Schema für zuverlässige Synchronisation über verschiedene Betriebssysteme hinweg. Playlists werden als .m3u8-Dateien geschrieben und referenzieren die Album-Tracks — keine Duplikate auf dem Gerät.',
|
||||
migrateButton: 'Bestehende Dateien re-organisieren…',
|
||||
migrateTooltip: 'Vorhandene Dateien auf dem Gerät nach dem neuen Schema umbenennen (basierend auf der alten Namensvorlage).',
|
||||
migrateTitle: 'Bestehende Dateien re-organisieren',
|
||||
migrateLoading: 'Analysiere vorhandene Dateien…',
|
||||
migrateNothingToDo: 'Alle vorhandenen Dateien entsprechen bereits dem neuen Schema — nichts zu tun.',
|
||||
migrateNoTemplate: 'Keine alte Namensvorlage auf dem Gerät gefunden. Migration ist nur möglich, wenn der Stick mit einer Psysonic-Version synchronisiert wurde, die konfigurierbare Vorlagen unterstützte.',
|
||||
migrateFilesToRename: 'Dateien werden umbenannt',
|
||||
migrateUnchanged: '{{n}} Dateien liegen bereits am korrekten Pfad',
|
||||
migrateCollisions: '{{n}} Dateien können nicht automatisch umbenannt werden (mehrere Tracks zeigen auf dasselbe Ziel). Sie bleiben unverändert — beim nächsten Sync werden sie neu heruntergeladen.',
|
||||
migratePreviewNote: 'Alte Vorlage: {{tpl}}',
|
||||
migrateExecuting: 'Dateien werden umbenannt…',
|
||||
migrateSuccess: '{{n}} Dateien erfolgreich umbenannt',
|
||||
migrateFailed: '{{n}} Umbenennungen fehlgeschlagen',
|
||||
migrateShowErrors: 'Fehler anzeigen',
|
||||
migrateStart: 'Umbenennen starten',
|
||||
onDevice: 'Auf dem Gerät',
|
||||
addSources: 'Hinzufügen…',
|
||||
colName: 'Name',
|
||||
colType: 'Typ',
|
||||
syncResult: '{{done}} übertragen, {{skipped}} bereits aktuell ({{total}} gesamt)',
|
||||
deleteFromDevice: 'Vom Gerät löschen ({{count}})',
|
||||
confirmDelete: '{{count}} Eintrag/Einträge vom Gerät löschen: {{names}}?',
|
||||
deleteComplete: '{{count}} Eintrag/Einträge vom Gerät entfernt.',
|
||||
manifestImported: '{{count}} Quelle(n) aus Geräte-Manifest importiert.',
|
||||
selectedSources: 'Ausgewählte Quellen',
|
||||
noSourcesSelected: 'Keine Quellen ausgewählt. Klicke auf Einträge im Browser um sie hinzuzufügen.',
|
||||
clearAll: 'Alle entfernen',
|
||||
tabPlaylists: 'Wiedergabelisten',
|
||||
tabAlbums: 'Alben',
|
||||
tabArtists: 'Künstler',
|
||||
searchPlaceholder: 'Suche…',
|
||||
syncButton: 'Auf Gerät übertragen',
|
||||
actionTransfer: 'Auf Gerät übertragen',
|
||||
actionDelete: 'Vom Gerät löschen',
|
||||
actionApplyAll: 'Änderungen synchronisieren',
|
||||
cancel: 'Abbrechen',
|
||||
noTargetDir: 'Bitte zuerst einen Zielordner auswählen.',
|
||||
noSources: 'Bitte mindestens eine Quelle auswählen.',
|
||||
noTracks: 'Keine Tracks in den ausgewählten Quellen gefunden.',
|
||||
fetchError: 'Fehler beim Laden der Tracks vom Server.',
|
||||
syncComplete: 'Übertragung abgeschlossen.',
|
||||
dismiss: 'Schließen',
|
||||
cancelSync: 'Abbrechen',
|
||||
syncCancelled: 'Sync abgebrochen ({{done}} / {{total}} übertragen).',
|
||||
colStatus: 'Status',
|
||||
statusSynced: 'Synchronisiert',
|
||||
statusPending: 'Ausstehend',
|
||||
statusDeletion: 'Löschung',
|
||||
markForDeletion: 'Zur Löschung markieren',
|
||||
removeSource: 'Entfernen',
|
||||
undoDeletion: 'Löschung rückgängig',
|
||||
syncInBackground: 'Sync gestartet — du kannst die Seite verlassen.',
|
||||
syncInProgress: '{{done}} / {{total}} Tracks…',
|
||||
syncSummary: 'Sync-Zusammenfassung',
|
||||
calculating: 'Payload wird berechnet…',
|
||||
filesToAdd: 'Hinzuzufügende Dateien:',
|
||||
filesToDelete: 'Zu löschende Dateien:',
|
||||
netChange: 'Nettoänderung:',
|
||||
availableSpace: 'Verfügbarer Speicher:',
|
||||
spaceWarning: 'Warnung: Das Zielgerät hat nicht genug gemeldeten Speicherplatz.',
|
||||
proceed: 'Sync durchführen',
|
||||
notEnoughSpace: 'Nicht genug physischer Speicherplatz erkannt!',
|
||||
liveSearch: 'Live',
|
||||
randomAlbumsLabel: 'Zufallsalben',
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const entityRating = {
|
||||
albumShort: 'Albumbewertung',
|
||||
artistShort: 'Künstlerbewertung',
|
||||
albumAriaLabel: 'Albumbewertung',
|
||||
artistAriaLabel: 'Künstlerbewertung',
|
||||
selectedArtistsRatingAriaLabel: 'Sternebewertung für {{count}} ausgewählte Künstler',
|
||||
selectedAlbumsRatingAriaLabel: 'Sternebewertung für {{count}} ausgewählte Alben',
|
||||
saveFailed: 'Bewertung konnte nicht gespeichert werden.',
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export const favorites = {
|
||||
title: 'Favoriten',
|
||||
empty: 'Du hast noch keine Favoriten gespeichert.',
|
||||
artists: 'Künstler',
|
||||
albums: 'Alben',
|
||||
songs: 'Songs',
|
||||
enqueueAll: 'Alle in die Warteschlange',
|
||||
playAll: 'Alle abspielen',
|
||||
removeSong: 'Aus Favoriten entfernen',
|
||||
stations: 'Radiosender',
|
||||
showingFiltered: 'Zeige {{filtered}} von {{total}} ({{artist}})',
|
||||
showingCount: 'Zeige {{filtered}} von {{total}}',
|
||||
clearArtistFilter: 'Künstlerfilter zurücksetzen',
|
||||
noFilterResults: 'Keine Ergebnisse mit den ausgewählten Filtern.',
|
||||
allArtists: 'Alle Künstler',
|
||||
topArtists: 'Top-Künstler nach Favoriten',
|
||||
topArtistsSongCount_one: '{{count}} Song',
|
||||
topArtistsSongCount_other: '{{count}} Songs',
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
export const folderBrowser = {
|
||||
empty: 'Leerer Ordner',
|
||||
error: 'Laden fehlgeschlagen',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export const genres = {
|
||||
title: 'Genres',
|
||||
genreCount: 'Genres',
|
||||
albumCount_one: '{{count}} Album',
|
||||
albumCount_other: '{{count}} Alben',
|
||||
loading: 'Genres werden geladen…',
|
||||
empty: 'Keine Genres gefunden.',
|
||||
albumsLoading: 'Alben werden geladen…',
|
||||
albumsEmpty: 'Keine Alben in diesem Genre gefunden.',
|
||||
loadMore: 'Mehr laden',
|
||||
back: 'Zurück',
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
export const help = {
|
||||
title: 'Hilfe',
|
||||
searchPlaceholder: 'Hilfe durchsuchen…',
|
||||
noResults: 'Keine passenden Themen. Versuche einen anderen Suchbegriff.',
|
||||
// ── Section 1: Erste Schritte ──────────────────────────────────────────
|
||||
s1: 'Erste Schritte',
|
||||
q1: 'Welche Server sind kompatibel?',
|
||||
a1: 'Psysonic ist primär für Navidrome gebaut und voll Subsonic-kompatibel — Gonic, Airsonic, LMS und andere Subsonic-API-Server funktionieren ebenfalls. Einige fortgeschrittene Features (Bewertungen, Smart Playlists, Magic-String-Sharing, User-Verwaltung) erfordern Navidrome.',
|
||||
q2: 'Wie füge ich einen Server hinzu?',
|
||||
a2: 'Einstellungen → Server → Server hinzufügen. URL eingeben (z. B. http://192.168.1.100:4533), Benutzername und Passwort. Psysonic testet die Verbindung vor dem Speichern — bei Fehler wird nichts gespeichert. Du kannst beliebig viele Server hinzufügen und im Header zwischen ihnen wechseln; immer ist nur einer aktiv.',
|
||||
q3: 'Schnelle UI-Tour?',
|
||||
a3: 'Sidebar (links) für Navigation, Mainstage / Seiten in der Mitte, Playerleiste unten, Warteschlangen-Panel rechts (über das Icon oben rechts neben dem Now-Playing-Indikator). Die Suche oben durchsucht die gesamte Bibliothek; "Now Playing" zeigt, was andere Nutzer auf dem gleichen Navidrome-Server gerade hören.',
|
||||
// ── Section 2: Wiedergabe & Warteschlange ──────────────────────────────
|
||||
s2: 'Wiedergabe & Warteschlange',
|
||||
q4: 'Wie nutze ich die Warteschlange?',
|
||||
a4: 'Warteschlangen-Panel oben rechts öffnen. Zeilen per Drag & Drop umsortieren, nach außen ziehen zum Entfernen, oder über die Toolbar mischen, als Playlist speichern oder zu einem Track springen. Zeilen lassen sich auch aus dem Panel heraus an andere Stellen ziehen.',
|
||||
q5: 'Gapless vs. Crossfade — was ist der Unterschied?',
|
||||
a5: 'Gapless puffert den nächsten Track vor, sodass keine Stille zwischen Songs entsteht (ideal für Live-Alben und DJ-Mixe). Crossfade blendet den aktuellen Track aus, während der nächste eingeblendet wird (1–10 s, gut für gemischte Mixe). Die zwei sind gegenseitig exklusiv — eines aktivieren deaktiviert das andere. Konfiguration in Einstellungen → Audio.',
|
||||
q6: 'Was ist die Infinite Queue?',
|
||||
a6: 'Wenn die Warteschlange leerläuft und Wiederholen aus ist, hängt Psysonic ähnliche / zufällige Tracks aus deiner Bibliothek hinten dran, sodass die Wiedergabe nie stoppt. Auto-hinzugefügte Tracks erscheinen unter dem Trenner „— Automatisch hinzugefügt —". Umschalten über das Unendlichkeits-Icon im Warteschlangen-Header; in Einstellungen → Warteschlange auf ein Genre einschränken.',
|
||||
q7: 'Mehrfachauswahl und Shift-Klick-Bereich?',
|
||||
a7: 'Im Mehrfach-Modus auf Alben / New Releases / Random Albums / Playlists: Klick toggelt einen Eintrag, dann Shift halten und einen anderen Eintrag klicken — alles dazwischen in der sichtbaren Reihenfolge wird ausgewählt. Shift-Klicks erweitern vom zuletzt geklickten Anker. Die Toolbar oben bietet Bulk-Aktionen (Queue, Download, Löschen usw.).',
|
||||
q8: 'Tastenkürzel und globale Hotkeys?',
|
||||
a8: 'Standard-In-App-Tasten: Leertaste = Play / Pause, Esc = Vollbild / Modal schließen, F1 = Shortcut-Spickzettel. Einstellungen → Eingabe lässt jede In-App-Aktion neu zuweisen (auch als Akkorde wie Strg+Shift+P) und systemweite globale Shortcuts setzen, die auch im Hintergrund oder minimiert funktionieren. Medientasten (Play/Pause, Weiter, Zurück) funktionieren auf allen Plattformen.',
|
||||
// ── Section 3: Audio-Werkzeuge ─────────────────────────────────────────
|
||||
s3: 'Audio-Werkzeuge',
|
||||
q9: 'Replay-Gain-Modi?',
|
||||
a9: 'Einstellungen → Audio → Replay Gain. Track-Modus normalisiert jeden Song auf einen Zielpegel. Album-Modus erhält die Lautstärke-Kurve innerhalb eines Albums. Auto-Modus wählt Track oder Album je nachdem, ob die Warteschlange aus einem einzelnen Album stammt. Tracks ohne Replay-Gain-Tags fallen auf einen konfigurierbaren Preamp zurück.',
|
||||
q10: 'Was ist Smart Loudness Normalization (LUFS)?',
|
||||
a10: 'Eine moderne Alternative zu Replay Gain in Einstellungen → Audio. Psysonic analysiert jeden Track nach LUFS / EBU R128 und speichert das Ergebnis, sodass die Lautstärke über die gesamte Bibliothek konsistent ist — auch bei Tracks ohne Replay-Gain-Tags. Die Cold-Cache-Analyse läuft im Hintergrund und nutzt 35–40 % CPU für ~1 Minute, danach 0. Ziel-Lautstärke (Standard −10 LUFS) einmal festlegen.',
|
||||
q11: 'EQ und AutoEQ?',
|
||||
a11: 'Ein 10-Band-Parametrik-EQ in Einstellungen → Audio → Equalizer mit manuellen Bändern und Presets. AutoEQ daneben holt ein gemessenes Korrekturprofil für dein Kopfhörermodell aus der AutoEQ-Datenbank und überträgt es automatisch auf die Bänder — Kopfhörer wählen, der EQ rastet auf der korrekten Kurve ein.',
|
||||
q12: 'Wie wechsle ich das Audio-Ausgabegerät?',
|
||||
a12: 'Einstellungen → Audio → Ausgabegerät. Psysonic listet alle verfügbaren Ausgaben und wechselt sofort beim Auswählen. Der Aktualisierungs-Button scannt nach Geräten, die nach dem Start angeschlossen wurden. Linux-ALSA-Namen wie „sysdefault" werden für die Lesbarkeit automatisch bereinigt.',
|
||||
q13: 'Was ist der Hot Cache?',
|
||||
a13: 'Der Hot Cache lädt den aktuellen Track plus die nächsten in den RAM und auf die Festplatte vor, sodass die Wiedergabe ohne Pufferverzögerung startet — besonders nützlich bei langsamen / entfernten Servern. Eviction greift, wenn das Größenlimit erreicht ist. Größe und Debounce-Verzögerung (damit schnelle Skips nicht überfetchen) in Einstellungen → Audio.',
|
||||
// ── Section 4: Bibliothek & Discovery ──────────────────────────────────
|
||||
s4: 'Bibliothek & Discovery',
|
||||
q14: 'Wie funktionieren Bewertungen und Skip-to-1★?',
|
||||
a14: 'Psysonic unterstützt 1–5-Sterne-Bewertungen über OpenSubsonic (Navidrome ≥ 0.53). Songs in Tracklisten, im Rechtsklick-Menü oder in der Playerleiste unter dem Künstlernamen bewerten; Alben auf der Albumseite; Künstler auf der Künstlerseite. Skip-to-1★ (Einstellungen → Bibliothek → Bewertungen) vergibt automatisch 1 Stern nach einer konfigurierbaren Anzahl aufeinanderfolgender Skips. Im selben Panel lässt sich eine Mindestbewertung als Filter für Random Mix und andere Mixes setzen.',
|
||||
q15: 'Wie browse ich — Ordner, Genres, Tracks?',
|
||||
a15: 'Der Ordner-Browser (Sidebar) navigiert durch das Musikverzeichnis des Servers im Miller-Column-Layout — Klick auf Ordner zum Öffnen, Klick auf Track oder Play-Icon eines Ordners zum Abspielen / Hinzufügen. Genres nutzt eine nach Track-Anzahl skalierte Tag-Cloud; Klick auf ein Genre öffnet es. Tracks ist ein flacher Library-Hub mit spaltensortierbarer virtueller Liste und Live-Suche.',
|
||||
q16: 'Suche und erweiterte Suche?',
|
||||
a16: 'Die Header-Suche läuft live während der Eingabe und durchsucht Künstler, Alben und Tracks. Die erweiterte Suche (Sidebar) bietet eine reichere Sicht: Filter nach Jahr, Genre, Bewertung, Format, Kanälen, Sample-Rate, BPM, Stimmung, kombinierbar. Rechtsklick auf jeden Treffer öffnet das gleiche Kontextmenü wie überall sonst in der App.',
|
||||
q17: 'Was sind die Mixes (Random / Genre / Super Genre / Lucky)?',
|
||||
a17: 'Random Mix erstellt eine Playlist aus zufälligen Tracks deiner Bibliothek; der Schlüsselwort-Filter schließt Hörbücher, Comedy etc. nach Genre / Titel / Album-Substrings aus. Super-Genre-Mix gruppiert deine Bibliothek in breite Stile (Rock, Metal, Electronic, Jazz, Klassik …) und erstellt einen fokussierten Mix. Lucky Mix nutzt Hörhistorie, Bewertungen und AudioMuse-AI-ähnliche Tracks, um per Klick eine sofortige Playlist zu bauen.',
|
||||
q18: 'Statistik-Seite?',
|
||||
a18: 'Statistik (Sidebar) zeigt Top-Künstler, Top-Alben, Top-Tracks, Genre-Verteilung, Hörzeit über die Zeit und pro Bibliothek, wenn mehrere Music Folder konfiguriert sind. Mehrere Ansichten lassen sich als teilbares Card-Bild exportieren.',
|
||||
q19: 'Wie lade ich ein Album als ZIP herunter?',
|
||||
a19: 'Albumseite → „Download (ZIP)". Der Server packt das Album zuerst — bei großen oder verlustfreien Alben (FLAC / WAV) erscheint der Fortschrittsbalken erst, wenn das Zippen fertig ist und der Transfer beginnt. Das ist normal.',
|
||||
// ── Section 5: Lyrics ──────────────────────────────────────────────────
|
||||
s5: 'Lyrics',
|
||||
q20: 'Woher kommen die Lyrics?',
|
||||
a20: 'Drei Quellen, konfigurierbar in Einstellungen → Lyrics: Navidrome-Server (eingebettete / OpenSubsonic-Lyrics), LRCLIB (community-gepflegte synchronisierte Texte) und NetEase Cloud Music (umfangreicher asiatischer + internationaler Katalog). Jede Quelle aktivieren / deaktivieren und per Drag & Drop priorisieren.',
|
||||
q21: 'Wie zeige ich Lyrics während der Wiedergabe?',
|
||||
a21: 'Klick auf das Mikrofon-Icon in der Playerleiste öffnet den Lyrics-Tab im Warteschlangen-Panel. Synchronisierte Lyrics scrollen automatisch und unterstützen Klick-zum-Springen; reine Texte scrollen als statischer Block. Den Vollbild-Player über das Cover in der Playerleiste öffnen für eine immersive Lyrics-Ansicht mit Mesh-Blob-Hintergrund.',
|
||||
// ── Section 6: Sharing & Social ────────────────────────────────────────
|
||||
s6: 'Sharing & Social',
|
||||
q22: 'Was sind Magic Strings?',
|
||||
a22: 'Magic Strings sind kurze Copy-Paste-Tokens, die Dinge zwischen Psysonic-Nutzern ohne Drittanbieter-Server teilen. Server-Einladungs-Strings ermöglichen einem Freund das Onboarding auf deinem Navidrome mit einem Paste; Album- / Künstler- / Queue-Magic-Strings öffnen dasselbe Album / denselben Künstler / dieselbe Queue beim Empfänger. Aus dem Teilen-Menü generieren, in die Suche einfügen zum Konsumieren.',
|
||||
q23: 'Was ist Orbit?',
|
||||
a23: 'Orbit ist synchrones Zusammenhören: ein Host spielt einen Track, alle Gäste hören ihn synchron, und Gäste können Songs vorschlagen, die der Host in die Queue annehmen kann. Session über den Orbit-Button im Header starten, Einladungslink teilen, andere können von jeder Psysonic-Installation beitreten. Der Host kontrolliert die Wiedergabe (Skip, Seek, Queue) — Gäste sehen den Stand in Echtzeit und können Vorschläge machen. Sessions sind ephemer und enden, wenn der Host sie schließt.',
|
||||
q24: 'Was ist das Now-Playing-Dropdown?',
|
||||
a24: 'Das Broadcast-Symbol oben rechts im Header zeigt, was andere Nutzer auf deinem Navidrome-Server gerade hören, aktualisiert alle 10 Sekunden. Der eigene Eintrag verschwindet sofort beim Pausieren. Per-Server — Nutzer auf einem anderen aktiven Server werden nicht angezeigt.',
|
||||
// ── Section 7: Personalisierung ────────────────────────────────────────
|
||||
s7: 'Personalisierung',
|
||||
q25: 'Themes und der Theme-Scheduler?',
|
||||
a25: 'Einstellungen → Darstellung → Theme bietet 60+ Themes in 8 Gruppen (Psysonic, Mediaplayer, Betriebssysteme, Spiele, Filme, Serien, Social Media, Open Source Classics — Catppuccin / Nord / Gruvbox / Nightfox / Dracula). Auto-Switch-Theme erlaubt das Setzen von Tag- und Nacht-Theme mit Startzeiten, sodass Psysonic automatisch wechselt.',
|
||||
q26: 'Kann ich Sidebar, Home und Künstlerseite anpassen?',
|
||||
a26: 'Ja — Einstellungen → Personalisierung. Der Sidebar-Customizer erlaubt das Umsortieren der Nav-Items per Drag und das Ausblenden ungenutzter. Der Home-Customizer schaltet jede Mainstage-Reihe (Hero, Recent, Discover, Recently Played, Starred …) ein/aus. Der Artist-Page-Customizer ordnet die Sektionen (Top Songs, Alben, Singles, Compilations, ähnliche Künstler usw.) um und blendet ungenutzte aus.',
|
||||
q27: 'Was ist der Mini-Player?',
|
||||
a27: 'Ein kleines schwebendes Fenster mit Cover, Transport-Controls und kompakter Queue. Über das Mini-Player-Icon in der Playerleiste oder das zugehörige Tastenkürzel öffnen. Das Fenster merkt sich Position und Größe zwischen Sessions. Auf Windows wird die Mini-Webview beim Start vorerstellt, sodass das Öffnen sofort geschieht; Linux / macOS aktivieren das optional über Einstellungen → Darstellung → Mini-Player vorladen.',
|
||||
q28: 'Was ist die Floating Player Bar?',
|
||||
a28: 'Eine optionale Playerleisten-Variante (Einstellungen → Darstellung), die sich mit themed Hintergrund, Akzent-Border, abgerundetem Cover und zentriertem Lautstärke-Bereich vom unteren Rand löst. Nützlich auf hohen Monitoren oder kompakten Themes.',
|
||||
q29: 'Track-Vorschau beim Hovern?',
|
||||
a29: 'Über eine Track-Zeile hovern, den kleinen Vorschau-Button auf dem Cover klicken oder die Vorschau über das Rechtsklick-Menü auslösen — Psysonic streamt die ersten ~15 s durch dieselbe Rust-Audio-Engine, sodass Loudness-Normalisierung greift. Praktisch beim Durchblättern eines neuen Albums.',
|
||||
q30: 'Sleep-Timer?',
|
||||
a30: 'Klick auf das Mond-Icon in der Playerleiste öffnet den Sleep-Timer. Eine Dauer wählen (oder „Ende des aktuellen Tracks") und Psysonic blendet aus und pausiert am Ende. Der Button zeigt einen Kreis-Ring und einen Countdown im Button, während der Timer läuft.',
|
||||
q31: 'UI-Skalierung, Schrift, Seekbar-Stil?',
|
||||
a31: 'Einstellungen → Darstellung — Anzeigeskalierung (80–125 %, ohne System-Schriftgröße zu beeinflussen), Schrift (10 UI-Schriften, u. a. IBM Plex Mono, Fira Code, Geist, Golos Text …), Seekbar-Stil (Wellenform analysiert / Pseudowave deterministisch / Linie & Punkt / Balken / Dicker Balken / Segmentiert / Neon-Glow / Pulswelle / Partikelspur / Flüssigfüllung / Retro-Tape).',
|
||||
// ── Section 8: Power User ──────────────────────────────────────────────
|
||||
s8: 'Power User',
|
||||
q32: 'CLI-Player-Steuerung?',
|
||||
a32: 'Das Psysonic-Binary kann als Fernsteuerung dienen. Beispiele: psysonic --player play / pause / next / prev, --player volume 75, --player seek 15, --player shuffle, --player repeat off|all|one, --player rating 1-5. Server, Audiogeräte, Bibliotheken wechseln; Instant Mix triggern; Künstler / Alben / Tracks suchen. Vollständige Liste mit psysonic --player --help. Shell-Completions für bash und zsh über psysonic completions.',
|
||||
q33: 'Smart Playlists (Navidrome)?',
|
||||
a33: 'Smart Playlists sind serverseitige dynamische Playlists, die durch Regeln definiert werden (Genre = Rock UND Jahr > 2020 etc.). Die Playlists-Seite in Psysonic erlaubt das Erstellen, Bearbeiten und Löschen mit visuellem Regel-Editor — Psysonic spricht dafür mit der Navidrome Native API. Sie verhalten sich wie normale Playlists im Rest der App und aktualisieren sich automatisch, wenn sich die Bibliothek ändert.',
|
||||
q34: 'Einstellungen sichern und wiederherstellen?',
|
||||
a34: 'Einstellungen → Storage → Backup & Restore exportiert Server-Profile, Themes, Tastenkürzel und andere Einstellungen in eine einzige JSON-Datei. Auf einem anderen Gerät oder nach einer Neuinstallation importieren, um alles auf einmal wiederherzustellen. Server-Passwörter sind enthalten — Datei sicher aufbewahren.',
|
||||
q35: 'Wo sehe ich alle Open-Source-Lizenzen?',
|
||||
a35: 'Einstellungen → System → Open Source Licenses. Die volle Abhängigkeitsliste (Cargo-Crates und npm-Pakete) wird mit gebündelten Lizenztexten ausgeliefert. Klick auf einen Eintrag öffnet den vollen Text; der kuratierte Highlight-Block oben hebt die User-bekannten Bibliotheken hervor (Tauri, React, rodio, symphonia usw.).',
|
||||
// ── Section 9: Offline & Sync ──────────────────────────────────────────
|
||||
s9: 'Offline & Sync',
|
||||
q36: 'Offline-Modus — Alben und Playlists cachen?',
|
||||
a36: 'Album oder Playlist öffnen und das Download-Icon im Header klicken — Psysonic cacht jeden Track lokal, sodass er ohne Netzwerkzugriff abspielt. Die Offline-Bibliothek (Sidebar) listet alles Gecachte, zeigt laufende Downloads und erlaubt das Entfernen über das Papierkorb-Icon (das nach Abschluss erscheint).',
|
||||
q37: 'Offline-Speicherlimit?',
|
||||
a37: 'Einstellungen → Bibliothek → Offline lässt eine maximale Cache-Größe setzen. Wird das Limit erreicht, zeigt die Albumseite einen Warnhinweis. Speicher freigeben durch Entfernen von Alben oder Playlists in der Offline-Bibliothek.',
|
||||
q38: 'Device Sync — Musik auf USB / SD?',
|
||||
a38: 'Device Sync (Sidebar) kopiert Alben, Playlists oder ganze Künstler auf ein externes Laufwerk für Offline-Hören auf anderen Geräten. Zielordner wählen, Quellen aus den Browser-Tabs auswählen, „Auf Gerät übertragen" klicken. Psysonic schreibt ein Manifest (psysonic-sync.json), sodass es weiß, welche Dateien bereits dort sind, auch beim Wieder-Öffnen unter einem anderen OS mit anderer Vorlage. Vorlagen unterstützen {artist} / {album} / {title} / {track_number} / {disc_number} / {year}-Tokens mit / als Ordner-Trennzeichen.',
|
||||
// ── Section 10: Integrationen & Fehlerbehebung ─────────────────────────
|
||||
s10: 'Integrationen & Fehlerbehebung',
|
||||
q39: 'Last.fm-Scrobbling?',
|
||||
a39: 'Einstellungen → Integrationen → Last.fm. Konto einmal verbinden, Psysonic scrobbelt direkt zu Last.fm — keine Navidrome-Konfiguration nötig. Ein Scrobble wird gesendet, wenn 50 % eines Tracks gehört wurden. Now-Playing-Pings gehen zu Beginn raus.',
|
||||
q40: 'Discord Rich Presence?',
|
||||
a40: 'Einstellungen → Integrationen → Discord zeigt deinen aktuellen Track auf deinem Discord-Profil. Wahl zwischen App-Icon, Cover-Art deines Servers (über getAlbumInfo2 — benötigt einen öffentlich erreichbaren Server) oder Apple-Music-Covern. Anzeige-Strings (Details, Status, Tooltip) per Token-Templates anpassen.',
|
||||
q41: 'Bandsintown-Tour-Daten?',
|
||||
a41: 'Opt-in unter Einstellungen → Integrationen → Now-Playing-Info. Der Now-Playing-Tab auf der Now-Playing-Seite zeigt dann kommende Tour-Daten für den laufenden Künstler über die Bandsintown-Widget-API. Standardmäßig aus — keine Anfragen, bevor aktiviert.',
|
||||
q42: 'Internet Radio — Live-Streams abspielen?',
|
||||
a42: 'Internet Radio (Sidebar) spielt jeden auf deinem Navidrome-Server gespeicherten Live-Stream (Sender über die Navidrome-Admin-UI hinzufügen). Wiedergabe läuft über die HTML5-Audio-Engine des Browsers — die meisten EQ- / Replay-Gain- / Loudness-Einstellungen gelten nicht für Radio, aber ICY-Metadaten (aktueller Songname) werden angezeigt. Unterstützt MP3, AAC, OGG Vorbis und die meisten HLS-Streams; Codec-Support hängt von der Plattform ab.',
|
||||
q43: 'Der Verbindungstest schlägt fehl — was tun?',
|
||||
a43: 'URL inklusive Port doppelt prüfen (z. B. http://192.168.1.100:4533). Im lokalen Netzwerk klappt http:// oft, wo https:// nicht funktioniert (kein Zertifikat). Sicherstellen, dass keine Firewall den Port blockiert und dass Benutzername und Passwort stimmen. Bei Servern hinter einem Reverse-Proxy zuerst die direkte URL probieren, um die Ursache einzugrenzen.',
|
||||
q44: 'Cover und Künstlerbilder laden langsam.',
|
||||
a44: 'Bilder werden beim ersten Aufruf vom Server geholt und dann 30 Tage lokal gecacht. Bei langsamen Server-Festplatten kann der erste Seitenaufruf einen Moment dauern; danach sind sie sofort da. Der Hot Cache hilft auch bei Tracks, der Bild-Cache ist davon unabhängig.',
|
||||
q45: 'Linux-Probleme — schwarzer Bildschirm oder kein Ton?',
|
||||
a45: 'Schwarzer Bildschirm ist meist ein GPU- / EGL-Treiberproblem in WebKitGTK — mit GDK_BACKEND=x11 WEBKIT_DISABLE_COMPOSITING_MODE=1 WEBKIT_DISABLE_DMABUF_RENDERER=1 starten (die AUR- / .deb- / .rpm-Installer setzen das automatisch). Für Audio sicherstellen, dass PipeWire oder PulseAudio läuft. Tonaussetzer nach Sleep / Wake werden mittlerweile vom Post-Sleep-Recovery-Hook automatisch behandelt.',
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export const hero = {
|
||||
eyebrow: 'Album des Augenblicks',
|
||||
playAlbum: 'Album abspielen',
|
||||
enqueue: 'Einreihen',
|
||||
enqueueTooltip: 'Ganzes Album zur Warteschlange hinzufügen',
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export const home = {
|
||||
hero: 'Featured',
|
||||
starred: 'Persönliche Favoriten',
|
||||
recent: 'Zuletzt hinzugefügt',
|
||||
mostPlayed: 'Meistgehört',
|
||||
recentlyPlayed: 'Kürzlich gespielt',
|
||||
losslessAlbums: 'Lossless-Alben',
|
||||
discover: 'Entdecken',
|
||||
discoverSongs: 'Titel entdecken',
|
||||
loadMore: 'Mehr laden',
|
||||
discoverMore: 'Mehr entdecken',
|
||||
discoverArtists: 'Künstler entdecken',
|
||||
discoverArtistsMore: 'Alle Künstler',
|
||||
becauseYouLike: 'Weil du gehört hast…',
|
||||
becauseYouLikeFor: 'Weil du {{artist}} gehört hast',
|
||||
similarTo: 'Ähnlich wie {{artist}}',
|
||||
becauseYouLikeTracks_one: '{{count}} Titel',
|
||||
becauseYouLikeTracks_other: '{{count}} Titel'
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import { sidebar } from './sidebar';
|
||||
import { home } from './home';
|
||||
import { hero } from './hero';
|
||||
import { search } from './search';
|
||||
import { nowPlaying } from './nowPlaying';
|
||||
import { contextMenu } from './contextMenu';
|
||||
import { sharePaste } from './sharePaste';
|
||||
import { albumDetail } from './albumDetail';
|
||||
import { entityRating } from './entityRating';
|
||||
import { artistDetail } from './artistDetail';
|
||||
import { favorites } from './favorites';
|
||||
import { randomLanding } from './randomLanding';
|
||||
import { randomAlbums } from './randomAlbums';
|
||||
import { genres } from './genres';
|
||||
import { randomMix } from './randomMix';
|
||||
import { luckyMix } from './luckyMix';
|
||||
import { albums } from './albums';
|
||||
import { tracks } from './tracks';
|
||||
import { artists } from './artists';
|
||||
import { composers } from './composers';
|
||||
import { composerDetail } from './composerDetail';
|
||||
import { login } from './login';
|
||||
import { connection } from './connection';
|
||||
import { common } from './common';
|
||||
import { settings } from './settings';
|
||||
import { changelog } from './changelog';
|
||||
import { whatsNew } from './whatsNew';
|
||||
import { help } from './help';
|
||||
import { queue } from './queue';
|
||||
import { miniPlayer } from './miniPlayer';
|
||||
import { statistics } from './statistics';
|
||||
import { player } from './player';
|
||||
import { nowPlayingInfo } from './nowPlayingInfo';
|
||||
import { songInfo } from './songInfo';
|
||||
import { playlists } from './playlists';
|
||||
import { smartPlaylists } from './smartPlaylists';
|
||||
import { mostPlayed } from './mostPlayed';
|
||||
import { losslessAlbums } from './losslessAlbums';
|
||||
import { radio } from './radio';
|
||||
import { folderBrowser } from './folderBrowser';
|
||||
import { deviceSync } from './deviceSync';
|
||||
import { orbit } from './orbit';
|
||||
import { tray } from './tray';
|
||||
import { licenses } from './licenses';
|
||||
|
||||
export const deTranslation = {
|
||||
sidebar,
|
||||
home,
|
||||
hero,
|
||||
search,
|
||||
nowPlaying,
|
||||
contextMenu,
|
||||
sharePaste,
|
||||
albumDetail,
|
||||
entityRating,
|
||||
artistDetail,
|
||||
favorites,
|
||||
randomLanding,
|
||||
randomAlbums,
|
||||
genres,
|
||||
randomMix,
|
||||
luckyMix,
|
||||
albums,
|
||||
tracks,
|
||||
artists,
|
||||
composers,
|
||||
composerDetail,
|
||||
login,
|
||||
connection,
|
||||
common,
|
||||
settings,
|
||||
changelog,
|
||||
whatsNew,
|
||||
help,
|
||||
queue,
|
||||
miniPlayer,
|
||||
statistics,
|
||||
player,
|
||||
nowPlayingInfo,
|
||||
songInfo,
|
||||
playlists,
|
||||
smartPlaylists,
|
||||
mostPlayed,
|
||||
losslessAlbums,
|
||||
radio,
|
||||
folderBrowser,
|
||||
deviceSync,
|
||||
orbit,
|
||||
tray,
|
||||
licenses,
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export const licenses = {
|
||||
title: 'Open-Source-Lizenzen',
|
||||
intro: 'Psysonic basiert auf Open-Source-Software. Die untenstehende Liste zeigt jede Abhängigkeit, die mit der App ausgeliefert wird, inklusive Version, Lizenz und vollständigem Lizenztext.',
|
||||
highlights: 'Wichtige Abhängigkeiten',
|
||||
searchPlaceholder: 'Suche nach Name, Version oder Lizenz…',
|
||||
noResults: 'Keine Treffer.',
|
||||
loading: 'Lizenzen werden geladen…',
|
||||
loadError: 'Lizenzdaten konnten nicht geladen werden.',
|
||||
noLicenseText: 'Für diese Abhängigkeit ist kein Lizenztext gebündelt.',
|
||||
viewSource: 'Quelle anzeigen',
|
||||
totalLine: '{{total}} Abhängigkeiten — {{cargo}} Cargo, {{npm}} npm',
|
||||
generatedAt: 'Zuletzt generiert {{date}}',
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
export const login = {
|
||||
subtitle: 'Dein Navidrome Desktop Player',
|
||||
serverName: 'Server-Name (optional)',
|
||||
serverNamePlaceholder: 'Mein Navidrome',
|
||||
serverUrl: 'Server-URL',
|
||||
serverUrlPlaceholder: '192.168.1.100:4533 oder https://music.example.com',
|
||||
username: 'Benutzername',
|
||||
usernamePlaceholder: 'admin',
|
||||
password: 'Passwort',
|
||||
showPassword: 'Passwort anzeigen',
|
||||
hidePassword: 'Passwort verstecken',
|
||||
connect: 'Verbinden',
|
||||
connecting: 'Verbinde…',
|
||||
connected: 'Verbunden!',
|
||||
error: 'Verbindung fehlgeschlagen – bitte Daten prüfen.',
|
||||
urlRequired: 'Bitte Server-URL eingeben.',
|
||||
savedServers: 'Gespeicherte Server',
|
||||
addNew: 'Oder neuen Server hinzufügen',
|
||||
orMagicString: 'Oder Magic-String',
|
||||
magicStringPlaceholder: 'Freigabe-String einfügen (psysonic1-…)',
|
||||
magicStringInvalid: 'Ungültiger oder nicht lesbarer Magic-String.',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
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.',
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export const luckyMix = {
|
||||
done: 'Glücks-Mix bereit: {{count}} Titel',
|
||||
failed: 'Glücks-Mix konnte nicht erstellt werden. Bitte erneut versuchen.',
|
||||
unavailable: 'Glücks-Mix ist für diesen Server nicht verfügbar.',
|
||||
cancelTooltip: 'Glücks-Mix-Erstellung abbrechen',
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const miniPlayer = {
|
||||
showQueue: 'Warteschlange einblenden',
|
||||
hideQueue: 'Warteschlange ausblenden',
|
||||
pinOnTop: 'Im Vordergrund halten',
|
||||
pinOff: 'Vordergrund deaktivieren',
|
||||
openMainWindow: 'Hauptfenster öffnen',
|
||||
close: 'Schließen',
|
||||
emptyQueue: 'Die Warteschlange ist leer',
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export const mostPlayed = {
|
||||
title: 'Meistgehört',
|
||||
topArtists: 'Top-Künstler',
|
||||
topAlbums: 'Top-Alben',
|
||||
plays: '{{n}}× gespielt',
|
||||
sortMost: 'Meiste Plays zuerst',
|
||||
sortLeast: 'Wenigste Plays zuerst',
|
||||
loadMore: 'Mehr Alben laden',
|
||||
noData: 'Noch keine Wiedergabedaten. Fang an zu hören!',
|
||||
noArtists: 'Alle Künstler herausgefiltert.',
|
||||
filterCompilations: 'Sampler-Künstler ausblenden (Various Artists, Soundtracks usw.)',
|
||||
filterCompilationsShort: 'Sampler ausblenden',
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
export const nowPlaying = {
|
||||
tooltip: 'Wer hört was?',
|
||||
title: 'Wer hört was?',
|
||||
loading: 'Lädt…',
|
||||
nobody: 'Gerade hört niemand Musik.',
|
||||
minutesAgo: 'vor {{n}}m',
|
||||
nothingPlaying: 'Noch nichts am Laufen. Leg einen Track auf!',
|
||||
aboutArtist: 'Über den Künstler',
|
||||
fromAlbum: 'Aus diesem Album',
|
||||
viewAlbum: 'Album öffnen',
|
||||
goToArtist: 'Zum Künstler',
|
||||
readMore: 'Mehr lesen',
|
||||
showLess: 'Weniger anzeigen',
|
||||
genreInfo: 'Genre',
|
||||
trackInfo: 'Track-Info',
|
||||
topSongs: 'Meistgespielt von diesem Künstler',
|
||||
topSongsCredit: 'Top-Tracks von {{name}}',
|
||||
trackPosition: 'Track {{pos}}',
|
||||
playsCount_one: '{{count}} Wiedergabe',
|
||||
playsCount_other: '{{count}} Wiedergaben',
|
||||
releasedYearsAgo_one: 'vor {{count}} Jahr',
|
||||
releasedYearsAgo_other: 'vor {{count}} Jahren',
|
||||
discography: 'Diskografie',
|
||||
lastfmStats: 'Last.fm-Statistik',
|
||||
thisTrack: 'Dieser Titel',
|
||||
thisArtist: 'Dieser Künstler',
|
||||
listeners: 'Hörer',
|
||||
scrobbles: 'Scrobbles',
|
||||
yourScrobbles: 'von dir',
|
||||
listenersN: '{{n}} Hörer',
|
||||
scrobblesN: '{{n}} Scrobbles',
|
||||
playsByYouN: '{{n}}× von dir gespielt',
|
||||
openTrackOnLastfm: 'Track auf Last.fm',
|
||||
openArtistOnLastfm: 'Künstler auf Last.fm',
|
||||
rgTrackTooltip: 'ReplayGain (Track)',
|
||||
rgAlbumTooltip: 'ReplayGain (Album)',
|
||||
rgAutoTooltip: 'ReplayGain (Auto)',
|
||||
showMoreTracks: '{{count}} weitere anzeigen',
|
||||
showLessTracks: 'Weniger anzeigen',
|
||||
hideCard: 'Karte ausblenden',
|
||||
layoutMenu: 'Layout',
|
||||
visibleCards: 'Sichtbare Karten',
|
||||
hiddenCards: 'Ausgeblendete Karten',
|
||||
noHiddenCards: 'Keine ausgeblendeten Karten',
|
||||
resetLayout: 'Layout zurücksetzen',
|
||||
emptyColumn: 'Karten hier ablegen',
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
export const nowPlayingInfo = {
|
||||
tab: 'Info',
|
||||
empty: 'Spiele etwas, um Infos zu sehen',
|
||||
artist: 'Künstler*in',
|
||||
songInfo: 'Songinfos',
|
||||
onTour: 'Auf Tour',
|
||||
noTourEvents: 'Keine bevorstehenden Konzerte',
|
||||
tourLoading: 'Wird geladen…',
|
||||
poweredByBandsintown: 'Tourdaten via Bandsintown',
|
||||
bioReadMore: 'Mehr anzeigen',
|
||||
bioReadLess: 'Weniger anzeigen',
|
||||
showMoreTours_one: '{{count}} weiteres anzeigen',
|
||||
showMoreTours_other: '{{count}} weitere anzeigen',
|
||||
showLessTours: 'Weniger anzeigen',
|
||||
enableBandsintownPrompt: 'Anstehende Konzerte anzeigen?',
|
||||
enableBandsintownPromptDesc: 'Optional. Lädt Tourdaten der aktuellen Künstler*in über die öffentliche Bandsintown-API.',
|
||||
enableBandsintownPrivacy: 'Beim Aktivieren wird der Name der aktuell gespielten Künstler*in an die Bandsintown-API übertragen, um Tourdaten abzurufen. Es werden keine Konto- oder persönlichen Daten gesendet.',
|
||||
enableBandsintownAction: 'Aktivieren',
|
||||
role: {
|
||||
artist: 'Hauptkünstler*in',
|
||||
albumArtist: 'Album-Künstler*in',
|
||||
composer: 'Komponist*in',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,200 @@
|
||||
export const orbit = {
|
||||
triggerLabel: 'Orbit',
|
||||
triggerTooltip: 'Gemeinsame Hör-Session starten oder beitreten',
|
||||
launchCreate: 'Session erstellen',
|
||||
launchJoin: 'Session beitreten',
|
||||
launchHelp: 'Wie funktioniert das?',
|
||||
launchHelpSoon: 'Kommt bald',
|
||||
joinModalTitle: 'Einer Orbit-Session beitreten',
|
||||
joinModalSub: 'Füge den Einladungslink ein, den dir der Host geschickt hat.',
|
||||
joinModalLinkLabel: 'Einladungslink',
|
||||
joinModalLinkPlaceholder: 'psysonic2-…',
|
||||
joinModalLinkHelper: 'Akzeptiert jeden gültigen Orbit-Link. Der Link muss zu dem Server gehören, auf dem du gerade angemeldet bist.',
|
||||
joinModalPasteTooltip: 'Aus Zwischenablage einfügen',
|
||||
joinModalSubmit: 'Beitreten',
|
||||
joinModalBusy: 'Beitreten…',
|
||||
joinErrEmpty: 'Bitte Einladungslink einfügen.',
|
||||
joinErrInvalid: 'Das sieht nicht nach einem Orbit-Einladungslink aus.',
|
||||
closeAria: 'Schließen',
|
||||
heroTitlePrefix: 'Gemeinsam hören mit',
|
||||
heroTitleBrand: 'Orbit',
|
||||
heroSub: 'Starte eine Session — andere Nutzer auf {{server}} hören im Takt mit dir und können Songs vorschlagen.',
|
||||
fallbackServer: 'diesem Server',
|
||||
tipLan: 'Du bist aktuell mit einer Heimnetz-Adresse verbunden. Gäste außerhalb deines Heimnetzes können so nicht beitreten — wechsle vor dem Start in den Servereinstellungen zu einer öffentlichen Adresse.',
|
||||
tipRemote: 'Damit Gäste außerhalb deines Heimnetzes beitreten können, muss deine Serveradresse öffentlich erreichbar sein. Ist dein Server nur intern verfügbar, wechsle vor dem Start zu einer öffentlichen Adresse.',
|
||||
labelName: 'Sessionname',
|
||||
namePlaceholder: 'Velvet Orbit',
|
||||
reshuffleTooltip: 'Neuer Vorschlag',
|
||||
reshuffleAria: 'Neuen Namen vorschlagen',
|
||||
helperName: 'So taucht die Session für deine Gäste auf — Vorschlag übernehmen oder eigenen eintippen.',
|
||||
labelMax: 'Maximale Gäste',
|
||||
helperMax: 'Du zählst nicht mit — das ist nur die Obergrenze für beitretende Gäste.',
|
||||
labelLink: 'Einladungslink',
|
||||
tooltipCopied: 'Kopiert',
|
||||
tooltipCopy: 'Kopieren',
|
||||
ariaCopyLink: 'Link kopieren',
|
||||
helperLink: 'Schicke diesen Link deinen Gästen. Sie fügen ihn mit Strg+V irgendwo in Psysonic ein.',
|
||||
labelClearQueue: 'Eigene Warteschlange vorher leeren',
|
||||
helperClearQueue: 'Mit leerer Warteschlange in die Session starten. Aus: bereits aufgereihte Titel bleiben und werden mit den Gästen geteilt.',
|
||||
btnCancel: 'Abbrechen',
|
||||
btnStarting: 'Starte…',
|
||||
btnStart: 'Orbit starten',
|
||||
btnCopyAndStart: 'Link kopieren & starten',
|
||||
errNameRequired: 'Bitte gib deiner Session einen Namen.',
|
||||
errStartFailed: 'Konnte nicht starten.',
|
||||
hostLabel: 'Gastgeber: {{name}}',
|
||||
participantsTooltip: 'Teilnehmer',
|
||||
settingsTooltip: 'Session-Einstellungen',
|
||||
shareTooltip: 'Einladungslink teilen',
|
||||
shuffleLabel: 'Warteschlange wird neu gemischt in',
|
||||
catchUpLabel: 'aufholen',
|
||||
catchUpTooltip: 'Zur aktuellen Host-Position springen',
|
||||
hostAway: 'Host offline',
|
||||
hostOnline: 'Host online',
|
||||
endTooltip: 'Session beenden',
|
||||
leaveTooltip: 'Session verlassen',
|
||||
helpTooltip: 'Wie Orbit funktioniert',
|
||||
diag: {
|
||||
openTooltip: 'Diagnose — kopierbares Ereignis-Log',
|
||||
title: 'Orbit-Diagnose',
|
||||
role: 'Rolle',
|
||||
hostTrack: 'Host-Track-ID',
|
||||
hostPos: 'Host-Position',
|
||||
guestTrack: 'Meine Track-ID',
|
||||
guestPos: 'Meine Position',
|
||||
drift: 'Versatz',
|
||||
stateAge: 'Zustand-Alter',
|
||||
eventLog: 'Ereignis-Log ({{count}})',
|
||||
copyLabel: 'Kopieren',
|
||||
copyTooltip: 'Log in Zwischenablage kopieren',
|
||||
clearLabel: 'Leeren',
|
||||
clearTooltip: 'Puffer leeren',
|
||||
empty: 'Noch keine Ereignisse — sie erscheinen sobald Orbit synchronisiert.',
|
||||
hint: 'Vor dem Reproduzieren des Problems öffnen, dann Kopieren klicken und in den Bug-Report einfügen.',
|
||||
copied: '{{count}} Zeilen kopiert',
|
||||
copyFailed: 'Konnte nicht in Zwischenablage kopieren',
|
||||
cleared: 'Puffer geleert',
|
||||
},
|
||||
helpTitle: 'Wie Orbit funktioniert',
|
||||
helpIntro: 'Orbit macht aus Psysonic einen gemeinsamen Hörraum. Der Host bestimmt die Musik; Gäste hören synchron mit und können Songs vorschlagen.',
|
||||
helpHostOnly: '(Host)',
|
||||
helpSec1Title: 'Was ist Orbit?',
|
||||
helpSec1Body: 'Ein „Listen together"-Modus — der Host steuert die Wiedergabe, die Gäste hören mit. Alles läuft über Playlists auf deinem eigenen Navidrome-Server; keine externe Infrastruktur.',
|
||||
helpSec2Title: 'Host und Gäste',
|
||||
helpSec2Body: 'Der Host steuert die Wiedergabe (Play / Pause / Skip / Seek) und entscheidet, wann die Session endet. Gäste folgen der Wiedergabe des Hosts, können Songs vorschlagen und jederzeit verlassen oder wieder beitreten. Nur der Host kann Teilnehmer kicken oder dauerhaft bannen.',
|
||||
helpSec2WarnHead: 'Wichtig: getrennte Accounts.',
|
||||
helpSec2WarnBody: 'Jeder Teilnehmer braucht einen eigenen Navidrome-Account. Benutzen Host und Gast denselben User, kollidieren ihre Einreichungen und der Host sieht keine Vorschläge vom Gast.',
|
||||
helpSec3Title: 'Session starten und einladen',
|
||||
helpSec3Body: 'Klick auf den „Orbit"-Button → Session erstellen → im Start-Modal siehst du einen fertigen Einladungslink und kannst optional die aktuelle Warteschlange leeren. Link teilen wie du magst. Während die Session läuft, kopiert der Share-Button in der Session-Leiste oben jederzeit den Link erneut.',
|
||||
helpSec4Title: 'Beitreten',
|
||||
helpSec4Body: 'Einladungslink irgendwo in Psysonic mit Ctrl+V / Cmd+V einfügen — der Beitritt-Dialog erscheint automatisch. Alternativ: „Orbit" → Session beitreten → Link ins Feld pasten. Wenn der Link auf einen Server zeigt, für den du einen Account hast, wechselt Psysonic automatisch. Bei mehreren Accounts auf demselben Server fragt ein kleiner Picker, welcher genutzt werden soll.',
|
||||
helpSec5Title: 'Songs vorschlagen',
|
||||
helpSec5Body: 'In jeder Song-Liste: Doppelklick auf eine Zeile, oder Rechtsklick → „Zur Orbit-Session hinzufügen". Ein einfacher Klick zeigt nur einen Hinweis, statt das ganze Album in die geteilte Queue zu werfen — das ist bewusst so. Explizite Bulk-Aktionen wie „Play All" oder „Play Album" fragen zuerst nach und hängen dann an (ersetzen nie).',
|
||||
helpSec6Title: 'Die geteilte Warteschlange',
|
||||
helpSec6Body: 'Die Queue zeigt die kommenden Titel des Hosts — für alle sichtbar. Neu hinzugefügte Bulk-Inhalte werden immer angehängt, damit Gast-Vorschläge nicht verloren gehen. Auto-Shuffle mischt die Queue periodisch neu (konfigurierbar: 1 / 5 / 10 / 15 / 30 Min.). Wenn deine Wiedergabe vom Host abweicht, bringt dich der „Aufholen"-Button in der Session-Leiste zurück zur Live-Position des Hosts.',
|
||||
helpSec7Title: 'Freigaben',
|
||||
helpSec7Body: 'Standardmäßig müssen Vorschläge von Gästen manuell freigegeben werden — sie erscheinen in einer „Freigabe"-Leiste oben im Queue-Panel mit Annehmen/Ablehnen-Buttons. In den Session-Einstellungen lässt sich Auto-Übernehmen aktivieren, dann landen alle Vorschläge direkt in der Queue.',
|
||||
helpSec8Title: 'Teilnehmer und Einstellungen',
|
||||
helpSec8Body: 'Das Einstellungs-Icon in der Session-Leiste öffnet Shuffle-Takt, Auto-Übernehmen und die „Jetzt mischen"-Abkürzung. Klick auf die Teilnehmerzahl zeigt wer gerade dabei ist — Kick (kann über den Link wieder beitreten) oder Bann (für die Session gesperrt). Gäste sehen die Teilnehmerliste ebenfalls, aber nur lesend.',
|
||||
helpSec9Title: 'Session beenden',
|
||||
helpSec9Body: 'Host-X → Bestätigungsdialog → Session endet für alle und die Server-Playlists werden automatisch aufgeräumt. Gast-X → der Gast verlässt, die Session läuft weiter. Wenn der Host 5 Minuten lang nichts mehr sendet, verlässt der Gast die Session automatisch mit einer Meldung; kürzere Reconnects innerhalb dieser Zeit bleiben unsichtbar.',
|
||||
participantsInviteLabel: 'Einladungslink',
|
||||
participantsCountLabel: '{{count}} in Session',
|
||||
participantsHost: 'Gastgeber',
|
||||
participantsEmpty: 'Noch keine Gäste',
|
||||
participantsKickTooltip: 'Aus Session entfernen',
|
||||
participantsKickAria: '{{user}} entfernen',
|
||||
participantsRemoveTooltip: 'Aus Session entfernen',
|
||||
participantsRemoveAria: '{{user}} aus dieser Session entfernen',
|
||||
participantsBanTooltip: 'Permanent bannen',
|
||||
participantsBanAria: '{{user}} permanent bannen',
|
||||
participantsMuteTooltip: 'Vorschläge sperren',
|
||||
participantsUnmuteTooltip: 'Vorschläge erlauben',
|
||||
participantsMuteAria: 'Vorschläge von {{user}} sperren',
|
||||
participantsUnmuteAria: 'Vorschläge von {{user}} wieder erlauben',
|
||||
confirmRemoveTitle: 'Aus Session entfernen?',
|
||||
confirmRemoveBody: '{{user}} wird aus der Session geworfen, kann aber jederzeit über deinen Einladungslink wieder beitreten.',
|
||||
confirmRemoveConfirm: 'Entfernen',
|
||||
confirmBanTitle: 'Permanent bannen?',
|
||||
confirmBanBody: '{{user}} wird entfernt und kann dieser Session nicht wieder beitreten. Für die Lebensdauer der Session nicht rückgängig zu machen.',
|
||||
confirmBanConfirm: 'Bannen',
|
||||
confirmCancel: 'Abbrechen',
|
||||
confirmJoinTitle: 'Orbit-Session beitreten?',
|
||||
confirmJoinBody: '{{host}} lädt dich zu „{{name}}" ein. Möchtest du der Session beitreten?',
|
||||
confirmJoinConfirm: 'Beitreten',
|
||||
confirmLeaveTitle: 'Session verlassen?',
|
||||
confirmLeaveBody: '„{{name}}" wirklich verlassen? Du kannst jederzeit über {{host}}s Einladungslink wieder beitreten.',
|
||||
confirmLeaveConfirm: 'Verlassen',
|
||||
confirmEndTitle: 'Session für alle beenden?',
|
||||
confirmEndBody: '„{{name}}" wird für alle Teilnehmer geschlossen. Die Session-Playlists werden automatisch aufgeräumt.',
|
||||
confirmEndConfirm: 'Session beenden',
|
||||
invalidLinkTitle: 'Einladungslink ist nicht mehr gültig',
|
||||
invalidLinkBody: 'Diese Orbit-Session existiert nicht mehr oder wurde bereits beendet. Bitte den Gastgeber um einen neuen Einladungslink.',
|
||||
settingsTitle: 'Session-Einstellungen',
|
||||
settingAutoApprove: 'Vorschläge automatisch übernehmen',
|
||||
settingAutoApproveHint: 'Neue Gäste-Vorschläge landen sofort in deiner Warteschlange. Aus: sie bleiben in der Session-Liste, du musst sie später manuell übernehmen.',
|
||||
settingAutoShuffle: 'Automatisch mischen',
|
||||
settingAutoShuffleHint: 'Periodischer Fisher-Yates-Shuffle der kommenden Warteschlange. Aus: Reihenfolge wird nur verändert, wenn du selbst sortierst.',
|
||||
settingShuffleInterval: 'Alle',
|
||||
settingShuffleIntervalHint: 'Wie oft die kommende Warteschlange während der Session neu gemischt wird.',
|
||||
suggestBlockedMuted: 'Der Host hat dich für diese Session gesperrt — keine Vorschläge möglich.',
|
||||
settingShuffleIntervalValue_one: '{{count}} Min.',
|
||||
settingShuffleIntervalValue_other: '{{count}} Min.',
|
||||
settingShuffleNow: 'Jetzt mischen',
|
||||
toastSuggested: '{{user}} hat „{{title}}" vorgeschlagen',
|
||||
toastSuggestedMany: '{{count}} neue Vorschläge in der Warteschlange',
|
||||
toastShuffled: 'Warteschlange gemischt',
|
||||
toastJoined: 'Session beigetreten',
|
||||
toastLoginFirst: 'Erst anmelden, um einer Session beizutreten',
|
||||
toastSwitchServer: 'Wechsle erst zu {{url}} und füge den Link dann erneut ein',
|
||||
toastNoAccountForServer: 'Du hast keinen Zugang zu {{url}}. Bitte den Host um einen Einladungslink.',
|
||||
toastSwitchFailed: 'Wechsel zu {{url}} fehlgeschlagen',
|
||||
accountPickerTitle: 'Welcher Account?',
|
||||
accountPickerSub: 'Du hast mehrere Accounts für {{url}}. Wähle aus, mit welchem du der Session beitreten willst.',
|
||||
toastJoinFail: 'Session konnte nicht beigetreten werden',
|
||||
joinErrNotFound: 'Session nicht gefunden',
|
||||
joinErrEnded: 'Session wurde beendet',
|
||||
joinErrFull: 'Session ist voll',
|
||||
joinErrKicked: 'Du kannst dieser Session nicht mehr beitreten',
|
||||
joinErrNoUser: 'Kein aktiver Server',
|
||||
joinErrServerError: 'Beitritt fehlgeschlagen',
|
||||
ctxAddToSession: 'Zur Orbit-Session hinzufügen',
|
||||
ctxSuggestedToast: 'An Session vorgeschlagen',
|
||||
ctxSuggestFailed: 'Vorschlag fehlgeschlagen — nicht beigetreten',
|
||||
ctxAddToSessionHost: 'Zur Orbit-Session hinzufügen',
|
||||
ctxAddedHostToast: 'Zur Session hinzugefügt',
|
||||
ctxAddHostFailed: 'Hinzufügen fehlgeschlagen',
|
||||
bulkConfirmTitle: 'Wirklich alles in die Orbit-Queue?',
|
||||
bulkConfirmBody: 'Das würde {{count}} Titel auf einmal in die geteilte Queue werfen. Für deine Gäste ist das eine Menge. Trotzdem hinzufügen?',
|
||||
bulkConfirmYes: 'Alle hinzufügen',
|
||||
bulkConfirmNo: 'Abbrechen',
|
||||
guestLive: 'Live',
|
||||
guestPlaying: 'Läuft gerade',
|
||||
guestPaused: 'Pausiert',
|
||||
guestLoading: 'Lade…',
|
||||
guestSuggestions: 'Vorschläge',
|
||||
guestUpNext: 'Als Nächstes',
|
||||
guestUpNextEmpty: 'Nichts in der Warteschlange. Öffne bei einem Song das Kontextmenü und wähle „Zur Orbit-Session hinzufügen", um etwas vorzuschlagen.',
|
||||
guestPendingTitle: 'Wartet auf Host',
|
||||
guestPendingHint: 'Vorgeschlagen — taucht in der Warteschlange auf, sobald der Host sie übernimmt.',
|
||||
approvalTitle: 'Zur Freigabe',
|
||||
approvalFrom: 'Vorgeschlagen von {{user}}',
|
||||
approvalAccept: 'Übernehmen',
|
||||
approvalDecline: 'Ablehnen',
|
||||
guestUpNextMore: '+ {{count}} weitere in der Host-Warteschlange',
|
||||
guestSubmitter: 'von {{user}}',
|
||||
queueAddedByHost: 'Vom Host hinzugefügt',
|
||||
queueAddedByYou: 'Von dir hinzugefügt',
|
||||
queueAddedByUser: 'Hinzugefügt von {{user}}',
|
||||
guestEmpty: 'Noch keine Vorschläge. Öffne bei einem Song das Kontextmenü und wähle „Zur Orbit-Session hinzufügen".',
|
||||
guestFooter: 'Die Wiedergabe wird vom Gastgeber gesteuert — du kannst die Liste nicht ändern.',
|
||||
exitKickedTitle: 'Du wurdest aus der Session gebannt',
|
||||
exitRemovedTitle: 'Du wurdest aus der Session entfernt',
|
||||
exitEndedTitle: 'Der Gastgeber hat die Session beendet',
|
||||
exitHostTimeoutTitle: 'Host nicht mehr erreichbar',
|
||||
exitHostTimeoutBody: '{{host}} hat sich länger nicht mehr gemeldet — „{{name}}" wurde auf deiner Seite beendet. Über den Einladungslink kannst du jederzeit wieder beitreten.',
|
||||
exitKickedBody: '{{host}} hat dich aus „{{name}}" gebannt. Beitritt nicht mehr möglich.',
|
||||
exitRemovedBody: '{{host}} hat dich aus „{{name}}" entfernt. Du kannst jederzeit über den Einladungslink wieder beitreten.',
|
||||
exitEndedBody: '„{{name}}" ist zu Ende. Hoffentlich war\'s schön.',
|
||||
exitOk: 'OK',
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
export const player = {
|
||||
regionLabel: 'Musikplayer',
|
||||
openFullscreen: 'Vollbild-Player öffnen',
|
||||
fullscreen: 'Vollbild-Player',
|
||||
closeFullscreen: 'Vollbild schließen',
|
||||
closeTooltip: 'Schließen (Esc)',
|
||||
noTitle: 'Kein Titel',
|
||||
stop: 'Stop',
|
||||
prev: 'Vorheriger Titel',
|
||||
play: 'Play',
|
||||
pause: 'Pause',
|
||||
previewActive: 'Vorschau läuft',
|
||||
previewLabel: 'Vorschau',
|
||||
delayModalTitle: 'Timer',
|
||||
delayPauseSection: 'Pause nach',
|
||||
delayStartSection: 'Start nach',
|
||||
delayPreviewPause: 'Pause um',
|
||||
delayPreviewStart: 'Start um',
|
||||
delaySchedulePause: 'Pause planen',
|
||||
delayScheduleStart: 'Start planen',
|
||||
delayCancelPause: 'Pause-Timer abbrechen',
|
||||
delayCancelStart: 'Start-Timer abbrechen',
|
||||
delayInactivePause: 'Nur während der Wiedergabe verfügbar.',
|
||||
delayInactiveStart: 'Nur in Pause mit geladenem Titel oder Radio.',
|
||||
delayCustomMinutes: 'Eigene Dauer (Minuten)',
|
||||
delayCustomPlaceholder: 'z. B. 2,5',
|
||||
closeDelayModal: 'Schließen',
|
||||
delayIn: 'in',
|
||||
delayFmtSec: '{{n}} s',
|
||||
delayFmtMin: '{{n}} Min',
|
||||
delayFmtHr: '{{n}} Std',
|
||||
delayCancel: 'Abbrechen',
|
||||
delayApply: 'Übernehmen',
|
||||
next: 'Nächster Titel',
|
||||
repeat: 'Wiederholen',
|
||||
repeatOff: 'Aus',
|
||||
repeatAll: 'Alle',
|
||||
repeatOne: 'Einen',
|
||||
progress: 'Songfortschritt',
|
||||
volume: 'Lautstärke',
|
||||
toggleQueue: 'Warteschlange umschalten',
|
||||
collapseQueueResize: 'Warteschlange einklappen, Breite ändern',
|
||||
moreOptions: 'Weitere Optionen',
|
||||
equalizer: 'Equalizer',
|
||||
miniPlayer: 'Mini-Player',
|
||||
lyrics: 'Lyrics',
|
||||
fsLyricsToggle: 'Lyrics im Vollbild',
|
||||
lyricsLoading: 'Lyrics werden geladen…',
|
||||
lyricsNotFound: 'Keine Lyrics für diesen Titel gefunden',
|
||||
lyricsSourceServer: 'Quelle: Server',
|
||||
lyricsSourceLrclib: 'Quelle: LRCLIB',
|
||||
lyricsSourceNetease: 'Quelle: Netease',
|
||||
lyricsSourceLyricsplus: 'Quelle: YouLyPlus',
|
||||
showDuration: 'Dauer anzeigen',
|
||||
showRemainingTime: 'Verbleibende Zeit anzeigen',
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
export const playlists = {
|
||||
title: 'Playlists',
|
||||
newPlaylist: 'Neue Playlist',
|
||||
unnamed: 'Unbenannte Playlist',
|
||||
createName: 'Playlist-Name…',
|
||||
create: 'Erstellen',
|
||||
cancel: 'Abbrechen',
|
||||
empty: 'Noch keine Playlists.',
|
||||
emptyPlaylist: 'Diese Playlist ist leer.',
|
||||
addFirstSong: 'Ersten Song hinzufügen',
|
||||
notFound: 'Playlist nicht gefunden.',
|
||||
songs: '{{n}} Songs',
|
||||
playAll: 'Alle abspielen',
|
||||
shuffle: 'Zufallswiedergabe',
|
||||
addToQueue: 'Zur Warteschlange',
|
||||
back: 'Zurück zu Playlists',
|
||||
deletePlaylist: 'Löschen',
|
||||
confirmDelete: 'Nochmals klicken zum Bestätigen',
|
||||
removeSong: 'Aus Playlist entfernen',
|
||||
addSongs: 'Songs hinzufügen',
|
||||
searchPlaceholder: 'Bibliothek durchsuchen…',
|
||||
noResults: 'Keine Ergebnisse.',
|
||||
suggestions: 'Vorgeschlagene Songs',
|
||||
noSuggestions: 'Keine Vorschläge verfügbar.',
|
||||
titleBadge: 'Playlist',
|
||||
refreshSuggestions: 'Neue Vorschläge',
|
||||
addSong: 'Zur Playlist hinzufügen',
|
||||
preview: 'Vorschau (30 s)',
|
||||
previewStop: 'Vorschau stoppen',
|
||||
playNextSuggestion: 'Als Nächstes spielen',
|
||||
suggestionsHint: 'Doppelklick auf eine Zeile fügt sie zur Playlist hinzu',
|
||||
addSelected: 'Ausgewählte hinzufügen',
|
||||
cacheOffline: 'Playlist offline speichern',
|
||||
offlineCached: 'Playlist gecacht',
|
||||
removeOffline: 'Aus Offline-Cache entfernen',
|
||||
offlineDownloading: 'Wird gecacht… ({{done}}/{{total}} Alben)',
|
||||
publicLabel: 'Öffentlich',
|
||||
privateLabel: 'Privat',
|
||||
editMeta: 'Playlist bearbeiten',
|
||||
editNamePlaceholder: 'Playlist-Name…',
|
||||
editCommentPlaceholder: 'Beschreibung hinzufügen…',
|
||||
editPublic: 'Öffentliche Playlist',
|
||||
editSave: 'Speichern',
|
||||
editCancel: 'Abbrechen',
|
||||
changeCover: 'Coverbild ändern',
|
||||
changeCoverLabel: 'Foto ändern',
|
||||
removeCover: 'Foto entfernen',
|
||||
coverUpdated: 'Cover aktualisiert',
|
||||
metaSaved: 'Playlist aktualisiert',
|
||||
downloadZip: 'Herunterladen (ZIP)',
|
||||
// Toast notifications for multi-select
|
||||
addSuccess: '{{count}} Songs zu {{playlist}} hinzugefügt',
|
||||
addPartial: '{{added}} hinzugefügt, {{skipped}} übersprungen (Duplikate)',
|
||||
addAllSkipped: 'Alle übersprungen ({{count}} Duplikate)',
|
||||
addedAsDuplicates: '{{count}} Songs zu {{playlist}} hinzugefügt (als Duplikate)',
|
||||
duplicateConfirmTitle: 'Bereits in Playlist',
|
||||
duplicateConfirmMessage: 'Alle {{count}} Songs sind bereits in "{{playlist}}". Trotzdem als Duplikate hinzufügen?',
|
||||
duplicateConfirmAction: 'Trotzdem hinzufügen',
|
||||
addError: 'Fehler beim Hinzufügen von Songs',
|
||||
createAndAddSuccess: 'Playlist "{{playlist}}" mit {{count}} Songs erstellt',
|
||||
createError: 'Fehler beim Erstellen der Playlist',
|
||||
deleteSuccess: '{{count}} Playlists gelöscht',
|
||||
deleteFailed: 'Fehler beim Löschen von {{name}}',
|
||||
deleteSelected: 'Ausgewählte löschen',
|
||||
deleteSelectedPartial: 'Nur {{n}} von {{total}} ausgewählten Playlists können gelöscht werden (die anderen gehören jemand anderem).',
|
||||
mergeSuccess: '{{count}} Songs in {{playlist}} zusammengeführt',
|
||||
mergeNoNewSongs: 'Keine neuen Songs zum Hinzufügen',
|
||||
mergeError: 'Fehler beim Zusammenführen von Playlists',
|
||||
mergeInto: 'Zusammenführen in',
|
||||
selectionCount: '{{count}} ausgewählt',
|
||||
select: 'Auswählen',
|
||||
startSelect: 'Auswahl aktivieren',
|
||||
cancelSelect: 'Abbrechen',
|
||||
loadingAlbums: '{{count}} Alben werden aufgelöst…',
|
||||
loadingArtists: '{{count}} Künstler werden aufgelöst…',
|
||||
myPlaylists: 'Meine Playlists',
|
||||
noOtherPlaylists: 'Keine anderen Playlists verfügbar',
|
||||
addToPlaylistSuccess: '{{count}} Songs zu {{playlist}} hinzugefügt',
|
||||
addToPlaylistNoNew: 'Keine neuen Songs für {{playlist}}',
|
||||
addToPlaylistError: 'Fehler beim Hinzufügen zur Playlist',
|
||||
removeSuccess: 'Song aus Playlist entfernt',
|
||||
removeError: 'Fehler beim Entfernen aus der Playlist',
|
||||
importCSV: 'CSV importieren',
|
||||
importCSVTooltip: 'Aus Spotify-CSV importieren',
|
||||
csvImportReport: 'CSV-Importbericht',
|
||||
csvImportTotal: 'Gesamt',
|
||||
csvImportAdded: 'Hinzugefügt',
|
||||
csvImportDuplicates: 'Duplikate',
|
||||
csvImportNotFound: 'Nicht gefunden',
|
||||
csvImportNetworkErrors: 'Netzwerkfehler',
|
||||
csvImportDuplicatesTitle: 'Doppelte Titel (bereits in Playlist):',
|
||||
csvImportNotFoundTitle: 'Nicht gefundene Titel:',
|
||||
csvImportNetworkErrorsTitle: 'Netzwerkfehler (Import kann wiederholt werden):',
|
||||
csvImportDownloadReport: 'Bericht herunterladen',
|
||||
csvImportClose: 'Schließen',
|
||||
csvImportNoValidTracks: 'Keine gültigen Titel in CSV-Datei gefunden',
|
||||
csvImportFailed: 'CSV-Import fehlgeschlagen',
|
||||
csvImportToast: '{{added}} hinzugefügt, {{notFound}} nicht gefunden, {{duplicates}} Duplikate',
|
||||
csvImportDownloadSuccess: 'Bericht erfolgreich heruntergeladen',
|
||||
csvImportDownloadError: 'Bericht konnte nicht heruntergeladen werden',
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
export const queue = {
|
||||
title: 'Warteschlange',
|
||||
savePlaylist: 'Playlist speichern',
|
||||
updatePlaylist: 'Playlist aktualisieren',
|
||||
filterPlaylists: 'Playlists filtern…',
|
||||
playlistName: 'Name der Playlist',
|
||||
cancel: 'Abbrechen',
|
||||
save: 'Speichern',
|
||||
loadPlaylist: 'Playlist laden',
|
||||
loading: 'Lade…',
|
||||
noPlaylists: 'Keine Playlists gefunden.',
|
||||
load: 'Warteschlange ersetzen & abspielen',
|
||||
appendToQueue: 'An Warteschlange anhängen',
|
||||
delete: 'Löschen',
|
||||
deleteConfirm: 'Playlist "{{name}}" löschen?',
|
||||
clear: 'Leeren',
|
||||
shuffle: 'Warteschlange mischen',
|
||||
gapless: 'Nahtlos',
|
||||
crossfade: 'Crossfade',
|
||||
infiniteQueue: 'Endlose Warteschlange',
|
||||
autoAdded: '— Automatisch hinzugefügt —',
|
||||
radioAdded: '— Radio —',
|
||||
hide: 'Verbergen',
|
||||
hideNowPlaying: 'Wiedergabeinformationen ausblenden',
|
||||
showNowPlaying: 'Wiedergabeinformationen anzeigen',
|
||||
close: 'Schließen',
|
||||
nextTracks: 'Nächste Titel',
|
||||
shareQueue: 'Warteschlangen-Link kopieren',
|
||||
shareQueueEmpty: 'Die Warteschlange ist leer — nichts zu teilen.',
|
||||
emptyQueue: 'Die Warteschlange ist leer.',
|
||||
trackSingular: 'Titel',
|
||||
trackPlural: 'Titel',
|
||||
showRemaining: 'Restzeit anzeigen',
|
||||
showTotal: 'Gesamtzeit anzeigen',
|
||||
showEta: 'Endzeit anzeigen',
|
||||
replayGain: 'ReplayGain',
|
||||
rgTrack: 'T {{db}} dB',
|
||||
rgAlbum: 'A {{db}} dB',
|
||||
rgPeak: 'Peak {{pk}}',
|
||||
sourceOffline: 'Wiedergabe aus der Offline-Bibliothek',
|
||||
sourceHot: 'Wiedergabe aus dem Cache',
|
||||
sourceStream: 'Wiedergabe aus dem Netzwerkstream',
|
||||
clearCachedLoudnessWaveform: 'Clear cached loudness and waveform, then re-analyze this track',
|
||||
recalculatingLoudnessWaveform: 'Recalculating loudness and waveform for this track…',
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
export const radio = {
|
||||
title: 'Internetradio',
|
||||
empty: 'Keine Radiosender konfiguriert.',
|
||||
addStation: 'Sender hinzufügen',
|
||||
editStation: 'Bearbeiten',
|
||||
deleteStation: 'Sender löschen',
|
||||
confirmDelete: 'Zum Bestätigen erneut klicken',
|
||||
stationName: 'Sendername…',
|
||||
streamUrl: 'Stream-URL…',
|
||||
homepageUrl: 'Homepage-URL (optional)',
|
||||
save: 'Speichern',
|
||||
cancel: 'Abbrechen',
|
||||
live: 'LIVE',
|
||||
liveStream: 'Internetradio',
|
||||
openHomepage: 'Homepage öffnen',
|
||||
changeCoverLabel: 'Cover ändern',
|
||||
removeCover: 'Cover entfernen',
|
||||
browseDirectory: 'Verzeichnis durchsuchen',
|
||||
directoryPlaceholder: 'Sender suchen…',
|
||||
noResults: 'Keine Sender gefunden.',
|
||||
stationAdded: 'Sender hinzugefügt',
|
||||
filterAll: 'Alle',
|
||||
filterFavorites: 'Favoriten',
|
||||
sortManual: 'Manuell',
|
||||
sortAZ: 'A → Z',
|
||||
sortZA: 'Z → A',
|
||||
sortNewest: 'Neueste',
|
||||
favorite: 'Zu Favoriten hinzufügen',
|
||||
unfavorite: 'Aus Favoriten entfernen',
|
||||
noFavorites: 'Keine Lieblingssender.',
|
||||
listenerCount_one: '{{count}} Hörer',
|
||||
listenerCount_other: '{{count}} Hörer',
|
||||
recentlyPlayed: 'Zuletzt gespielt',
|
||||
upNext: 'Als Nächstes',
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
export const randomAlbums = {
|
||||
title: 'Zufallsalben',
|
||||
refresh: 'Neu laden',
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const randomLanding = {
|
||||
title: 'Mix erstellen',
|
||||
mixByTracks: 'Mix nach Titeln',
|
||||
mixByTracksDesc: 'Zufällige Auswahl aus deiner gesamten Mediathek',
|
||||
mixByAlbums: 'Mix nach Alben',
|
||||
mixByAlbumsDesc: 'Zufällige Alben für neue Entdeckungen',
|
||||
mixByLucky: 'Glücks-Mix',
|
||||
mixByLuckyDesc: 'Smarter Instant Mix aus Top-Künstlern, Alben und Bewertungen',
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
export const randomMix = {
|
||||
title: 'Zufallsmix',
|
||||
remix: 'Neu mixen',
|
||||
remixTooltip: 'Neue Songs laden',
|
||||
remixGenre: '{{genre}} neu mixen',
|
||||
remixTooltipGenre: 'Neue {{genre}}-Songs laden',
|
||||
playAll: 'Alle abspielen',
|
||||
trackTitle: 'Titel',
|
||||
trackArtist: 'Künstler',
|
||||
trackAlbum: 'Album',
|
||||
trackFavorite: 'Favorit',
|
||||
trackDuration: 'Dauer',
|
||||
favoriteAdd: 'Zu Favoriten hinzufügen',
|
||||
favoriteRemove: 'Aus Favoriten entfernen',
|
||||
play: 'Abspielen',
|
||||
trackGenre: 'Genre',
|
||||
mixSettingsHeader: 'Mix-Einstellungen',
|
||||
exclusionsHeader: 'Ausschlüsse',
|
||||
filterPanelInexactSizeNote: 'Die Mix-Größe ist ein Ziel — bei großen Anfragen kann der Server weniger eindeutige Tracks liefern, wenn sein Zufallspool erschöpft ist.',
|
||||
mixSize: 'Playlistgröße',
|
||||
excludeAudiobooks: 'Hörbücher & Hörspiele ausschließen',
|
||||
excludeAudiobooksDesc: 'Prüft Keywords gegen Genre, Titel, Album und Künstler — z. B. Hörbuch, Audiobook, Spoken Word, …',
|
||||
genreBlocked: 'Keyword gesperrt',
|
||||
genreAddedToBlacklist: 'Zur Filterliste hinzugefügt',
|
||||
genreAlreadyBlocked: 'Bereits gesperrt',
|
||||
artistBlocked: 'Künstler gesperrt',
|
||||
artistAddedToBlacklist: 'Künstler zur Filterliste hinzugefügt',
|
||||
artistClickHint: 'Klicken um diesen Künstler zu sperren',
|
||||
blacklistToggle: 'Keyword-Filter',
|
||||
genreMixTitle: 'Genre-Mix',
|
||||
genreMixDesc: 'Top 20 Genres nach Songanzahl — klicken für einen Zufallsmix',
|
||||
genreMixAll: 'Alle Songs',
|
||||
genreMixLoadMore: '10 weitere laden',
|
||||
genreMixNoGenres: 'Keine Genres auf dem Server gefunden.',
|
||||
shuffleGenres: 'Andere Genres anzeigen',
|
||||
filterPanelTitle: 'Filter',
|
||||
filterPanelDesc: 'Genre-Tag oder Künstlername in der Liste anklicken, um ihn aus zukünftigen Mixes auszuschließen.',
|
||||
genreClickHint: 'Genre-Tag anklicken,\num es als Filter-Keyword hinzuzufügen.\nPrüft Genre, Titel, Album & Künstler.',
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
export const search = {
|
||||
placeholder: 'Suchen nach Künstler, Album oder Song…',
|
||||
noResults: 'Keine Ergebnisse für „{{query}}"',
|
||||
artists: 'Künstler',
|
||||
albums: 'Alben',
|
||||
songs: 'Songs',
|
||||
clearLabel: 'Suche leeren',
|
||||
addedToQueueToast: '„{{title}}" zur Warteschlange hinzugefügt',
|
||||
title: 'Suche',
|
||||
resultsFor: 'Ergebnisse für „{{query}}"',
|
||||
album: 'Album',
|
||||
advanced: 'Erweiterte Suche',
|
||||
advancedSearchTerm: 'Suchbegriff',
|
||||
advancedSearchPlaceholder: 'Titel, Album, Künstler…',
|
||||
advancedGenre: 'Genre',
|
||||
advancedAllGenres: 'Alle Genres',
|
||||
advancedYear: 'Jahr',
|
||||
advancedYearFrom: 'von',
|
||||
advancedYearTo: 'bis',
|
||||
advancedAll: 'Alle',
|
||||
advancedSearch: 'Suchen',
|
||||
advancedEmpty: 'Suchbegriff eingeben oder Filter wählen, um zu beginnen.',
|
||||
advancedNoResults: 'Keine Ergebnisse gefunden.',
|
||||
advancedGenreNote: 'Songs werden zufällig aus dem Genre gewählt.',
|
||||
recentSearches: 'Zuletzt gesucht',
|
||||
browse: 'Stöbern',
|
||||
emptyHint: 'Was möchtest du hören?',
|
||||
genres: 'Genres',
|
||||
};
|
||||
@@ -0,0 +1,442 @@
|
||||
export const settings = {
|
||||
title: 'Einstellungen',
|
||||
language: 'Sprache',
|
||||
languageEn: 'English',
|
||||
languageDe: 'Deutsch',
|
||||
languageEs: 'Español',
|
||||
languageFr: 'Français',
|
||||
languageNl: 'Nederlands',
|
||||
languageNb: 'Norsk',
|
||||
languageRu: 'Русский',
|
||||
languageZh: '中文',
|
||||
languageRo: 'Română',
|
||||
font: 'Schriftart',
|
||||
fontHintOpenDyslexic: 'Legasthenie-freundlich · keine Chinesisch-Unterstützung',
|
||||
theme: 'Design',
|
||||
appearance: 'Darstellung',
|
||||
servers: 'Server',
|
||||
serverName: 'Server-Name',
|
||||
serverUrl: 'Server-URL',
|
||||
serverUrlPlaceholder: '192.168.1.100:4533 oder https://music.example.com',
|
||||
serverUsername: 'Benutzername',
|
||||
serverPassword: 'Passwort',
|
||||
addServer: 'Server hinzufügen',
|
||||
addServerTitle: 'Neuen Server hinzufügen',
|
||||
useServer: 'Verwenden',
|
||||
deleteServer: 'Löschen',
|
||||
noServers: 'Keine Server gespeichert.',
|
||||
serverActive: 'Aktiv',
|
||||
confirmDeleteServer: 'Server „{{name}}" löschen?',
|
||||
serverConnecting: 'Verbinde…',
|
||||
serverConnected: 'Verbunden!',
|
||||
serverFailed: 'Verbindung fehlgeschlagen.',
|
||||
testBtn: 'Verbindung testen',
|
||||
testingBtn: 'Teste…',
|
||||
serverCompatible: 'Für Navidrome entwickelt. Andere Subsonic-kompatible Server (Gonic, Airsonic, …) funktionieren ggf. eingeschränkt, weil Psysonic viele Navidrome-spezifische API-Endpunkte nutzt.',
|
||||
userMgmtTitle: 'Benutzerverwaltung',
|
||||
userMgmtDesc: 'Benutzer auf diesem Server verwalten. Erfordert Admin-Rechte.',
|
||||
userMgmtNoAdmin: 'Du brauchst Admin-Rechte, um Benutzer auf diesem Server zu verwalten.',
|
||||
userMgmtLoadError: 'Benutzer konnten nicht geladen werden.',
|
||||
userMgmtLoadFriendly: 'Server hat nicht geantwortet — meistens ein Einzelfall.',
|
||||
userMgmtRetry: 'Erneut versuchen',
|
||||
userMgmtEmpty: 'Keine Benutzer gefunden.',
|
||||
userMgmtYouBadge: 'Du',
|
||||
userMgmtAdminBadge: 'Admin',
|
||||
userMgmtAddUser: 'Benutzer hinzufügen',
|
||||
userMgmtAddUserTitle: 'Neuen Benutzer anlegen',
|
||||
userMgmtEditUserTitle: 'Benutzer bearbeiten',
|
||||
userMgmtUsername: 'Benutzername',
|
||||
userMgmtName: 'Anzeigename',
|
||||
userMgmtEmail: 'E-Mail',
|
||||
userMgmtPassword: 'Passwort',
|
||||
userMgmtPasswordEditHint: 'Neues Passwort eingeben, um es zu ändern.',
|
||||
userMgmtRoleAdmin: 'Admin',
|
||||
userMgmtLibraries: 'Bibliotheken',
|
||||
userMgmtLibrariesAdminHint: 'Admin-Benutzer haben automatisch Zugriff auf alle Bibliotheken.',
|
||||
userMgmtLibrariesEmpty: 'Keine Bibliotheken auf diesem Server vorhanden.',
|
||||
userMgmtLibrariesValidation: 'Mindestens eine Bibliothek auswählen.',
|
||||
userMgmtLibrariesUpdateError: 'Benutzer gespeichert, aber Bibliothekszuweisung fehlgeschlagen',
|
||||
userMgmtNoLibraries: 'Keine Bibliotheken zugewiesen',
|
||||
userMgmtNeverSeen: 'Nie',
|
||||
userMgmtSave: 'Speichern',
|
||||
userMgmtCancel: 'Abbrechen',
|
||||
userMgmtDelete: 'Löschen',
|
||||
userMgmtEdit: 'Bearbeiten',
|
||||
userMgmtConfirmDelete: 'Benutzer „{{username}}" löschen? Das kann nicht rückgängig gemacht werden.',
|
||||
userMgmtCreateError: 'Benutzer konnte nicht angelegt werden.',
|
||||
userMgmtUpdateError: 'Benutzer konnte nicht aktualisiert werden.',
|
||||
userMgmtDeleteError: 'Benutzer konnte nicht gelöscht werden.',
|
||||
userMgmtCreated: 'Benutzer angelegt.',
|
||||
userMgmtUpdated: 'Benutzer aktualisiert.',
|
||||
userMgmtDeleted: 'Benutzer gelöscht.',
|
||||
userMgmtValidationMissing: 'Benutzername, Anzeigename und Passwort sind erforderlich.',
|
||||
userMgmtValidationMissingIdentity: 'Benutzername und Anzeigename sind erforderlich.',
|
||||
userMgmtMagicStringGenerate: 'Magic-String erzeugen',
|
||||
userMgmtSaveAndMagicString: 'Speichern und Magic-String kopieren',
|
||||
userMgmtMagicStringPasswordNavHint:
|
||||
'Navidrome speichert dieses Passwort für den Benutzer. Weicht es vom aktuellen ab, wird das Anmeldepasswort auf dem Server aktualisiert.',
|
||||
userMgmtMagicStringPlaintextWarning:
|
||||
'Teilen Sie den Magic-String vorsichtig: Er enthält das Passwort im Klartext (Kodierung ist keine Verschlüsselung). Wer die vollständige Zeichenkette hat, kann sich als dieser Benutzer anmelden.',
|
||||
userMgmtMagicStringCopied: 'Magic-String in die Zwischenablage kopiert.',
|
||||
userMgmtMagicStringCopyFailed: 'Kopieren in die Zwischenablage fehlgeschlagen.',
|
||||
userMgmtMagicStringLoginFailed: 'Passwortprüfung fehlgeschlagen — Anmeldedaten konnten nicht verifiziert werden.',
|
||||
userMgmtMagicStringModalTitle: 'Magic-String erzeugen',
|
||||
userMgmtMagicStringModalDesc: 'Subsonic-Passwort für „{{username}}" eingeben — es wird in den kopierten Magic-String übernommen.',
|
||||
userMgmtMagicStringModalConfirm: 'String kopieren',
|
||||
audiomuseTitle: 'AudioMuse-AI (Navidrome)',
|
||||
audiomuseDesc:
|
||||
'Aktivieren, wenn dieser Server das <pluginLink>AudioMuse-AI-Navidrome-Plugin</pluginLink> nutzt. Schaltet Instant Mix pro Titel frei und nutzt ähnliche Künstler vom Server statt Last.fm auf Künstlerseiten.',
|
||||
audiomuseIssueHint:
|
||||
'Instant Mix ist kürzlich fehlgeschlagen — Navidrome-Plugin und AudioMuse-API prüfen. Ohne Server-Treffer werden ähnliche Künstler über Last.fm geladen.',
|
||||
connected: 'Verbunden',
|
||||
failed: 'Fehlgeschlagen',
|
||||
eqTitle: 'Equalizer',
|
||||
eqEnabled: 'Equalizer aktivieren',
|
||||
eqPreset: 'Preset',
|
||||
eqPresetCustom: 'Benutzerdefiniert',
|
||||
eqPresetBuiltin: 'Eingebaute Presets',
|
||||
eqPresetCustomGroup: 'Meine Presets',
|
||||
eqSavePreset: 'Als Preset speichern',
|
||||
eqPresetName: 'Preset-Name…',
|
||||
eqDeletePreset: 'Preset löschen',
|
||||
eqResetBands: 'Auf Flat zurücksetzen',
|
||||
eqPreGain: 'Vorverstärkung',
|
||||
eqResetPreGain: 'Vorverstärkung zurücksetzen',
|
||||
eqAutoEqTitle: 'AutoEQ Kopfhörer-Suche',
|
||||
eqAutoEqPlaceholder: 'Kopfhörer / IEM Modell suchen…',
|
||||
eqAutoEqSearching: 'Suche…',
|
||||
eqAutoEqNoResults: 'Keine Ergebnisse gefunden',
|
||||
eqAutoEqError: 'Suche fehlgeschlagen',
|
||||
eqAutoEqRateLimit: 'GitHub Rate-Limit erreicht — in einer Minute erneut versuchen',
|
||||
eqAutoEqFetchError: 'EQ-Profil konnte nicht geladen werden',
|
||||
lfmTitle: 'Last.fm',
|
||||
lfmConnect: 'Mit Last.fm verbinden',
|
||||
lfmConnecting: 'Warte auf Bestätigung…',
|
||||
lfmConfirm: 'Ich habe die App autorisiert',
|
||||
lfmConnected: 'Verbunden als',
|
||||
lfmDisconnect: 'Trennen',
|
||||
lfmConnectDesc: 'Verbinde deinen Last.fm Account, um Scrobbling und Now-Playing-Updates direkt aus Psysonic heraus zu aktivieren — keine Navidrome-Konfiguration erforderlich.',
|
||||
lfmOpenBrowser: 'Es öffnet sich ein Browserfenster. Autorisiere Psysonic auf Last.fm und klicke dann unten auf den Button.',
|
||||
lfmScrobbles: '{{n}} Scrobbles',
|
||||
lfmMemberSince: 'Dabei seit {{year}}',
|
||||
scrobbleEnabled: 'Scrobbling aktiviert',
|
||||
scrobbleDesc: 'Songs nach 50% Laufzeit an Last.fm senden',
|
||||
behavior: 'App-Verhalten',
|
||||
cacheTitle: 'Max. Speichergröße',
|
||||
cacheDesc: 'Cover und Künstlerbilder. Wenn voll, werden die ältesten Einträge automatisch entfernt. Offline-Alben werden nicht automatisch gelöscht, aber beim manuellen Cache leeren entfernt.',
|
||||
cacheUsedImages: 'Bilder:',
|
||||
cacheUsedOffline: 'Offline-Tracks:',
|
||||
cacheUsedHot: 'Belegter Speicher:',
|
||||
hotCacheTrackCount: 'Titel im Cache:',
|
||||
cacheMaxLabel: 'Max. Größe',
|
||||
cacheClearBtn: 'Cache leeren',
|
||||
cacheClearWarning: 'Alle Offline-Alben werden damit aus der Bibliothek entfernt.',
|
||||
cacheClearConfirm: 'Alles löschen',
|
||||
cacheClearCancel: 'Abbrechen',
|
||||
offlineDirTitle: 'Offline-Bibliothek (In-App)',
|
||||
offlineDirDesc: 'Speicherort für Titel, die du innerhalb von Psysonic offline verfügbar machst.',
|
||||
offlineDirDefault: 'Standard (App-Daten)',
|
||||
offlineDirChange: 'Verzeichnis ändern',
|
||||
offlineDirClear: 'Auf Standard zurücksetzen',
|
||||
offlineDirHint: 'Neue Downloads werden an diesem Ort gespeichert. Bestehende Downloads verbleiben am ursprünglichen Pfad.',
|
||||
hotCacheTitle: 'Hot-Playback-Cache',
|
||||
hotCacheDisclaimer: 'Lädt kommende Warteschlangen-Titel vor und behält zuletzt gespielte. Bei aktivierter Option: Speicherplatz und Netzwerk.',
|
||||
hotCacheDirDefault: 'Standard (App-Daten)',
|
||||
hotCacheDirChange: 'Ordner ändern',
|
||||
hotCacheDirClear: 'Auf Standard zurücksetzen',
|
||||
hotCacheDirHint: 'Beim Ordnerwechsel wird der App-Index zurückgesetzt; alte Dateien bleiben am alten Ort, bis Sie sie löschen.',
|
||||
hotCacheEnabled: 'Hot-Playback-Cache aktivieren',
|
||||
hotCacheMaxMb: 'Maximale Cache-Größe',
|
||||
hotCacheDebounce: 'Debounce bei Warteschlangen-Änderungen',
|
||||
hotCacheDebounceImmediate: 'Sofort',
|
||||
hotCacheDebounceSeconds: '{{n}} s',
|
||||
hotCacheClearBtn: 'Hot-Cache leeren',
|
||||
audioOutputDevice: 'Audio-Ausgabegerät',
|
||||
audioOutputDeviceDesc: 'Wähle das Audiogerät, über das Psysonic spielt. Änderungen werden sofort übernommen und starten den aktuellen Track neu.',
|
||||
audioOutputDeviceDefault: 'Systemstandard',
|
||||
audioOutputDeviceRefresh: 'Geräteliste aktualisieren',
|
||||
audioOutputDeviceOsDefaultNow: 'aktuelle Systemausgabe',
|
||||
audioOutputDeviceListError: 'Audiogeräteliste konnte nicht geladen werden.',
|
||||
audioOutputDeviceNotInCurrentList: 'nicht in der aktuellen Liste',
|
||||
audioOutputDeviceMacNotice: 'Auf macOS folgt die Wiedergabe aus technischen Gründen zurzeit immer dem System-Ausgabegerät. Du kannst das Ziel über Systemeinstellungen → Ton oder das Lautsprecher-Symbol in der Menüleiste wechseln. Hintergrund: CoreAudio löst beim Öffnen eines nicht-Default-Streams eine Mikrofonberechtigungsabfrage aus — wir vermeiden sie, indem wir stets den System-Default verwenden.',
|
||||
hiResTitle: 'Native Hi-Res-Wiedergabe',
|
||||
hiResEnabled: 'Native Hi-Res-Wiedergabe aktivieren',
|
||||
hiResDesc: "Standardmäßig wird auf 44,1 kHz begrenzt (maximale Stabilität). Nur aktivieren, wenn Hardware und Netzwerk zuverlässig hohe Abtastraten (88,2 kHz+) unterstützen.",
|
||||
showArtistImages: 'Künstlerbilder anzeigen',
|
||||
showArtistImagesDesc: 'Lädt und zeigt Künstlerbilder in der Künstlerübersicht. Standardmäßig deaktiviert, um Server-I/O und Netzwerklast bei großen Bibliotheken zu reduzieren.',
|
||||
showOrbitTrigger: '„Orbit" im Header zeigen',
|
||||
showOrbitTriggerDesc: 'Der Kopfzeilen-Button zum Starten oder Beitreten einer gemeinsamen Hör-Session. Ausblenden, wenn du Orbit nicht nutzt — hier lässt er sich jederzeit wieder einschalten.',
|
||||
showTrayIcon: 'Tray-Icon anzeigen',
|
||||
showTrayIconDesc: 'Psysonic-Icon im System-Tray / in der Menüleiste anzeigen.',
|
||||
minimizeToTray: 'Im Tray minimieren',
|
||||
minimizeToTrayDesc: 'Beim Schließen des Fensters läuft Psysonic weiter im System-Tray statt zu beenden.',
|
||||
preloadMiniPlayer: 'Mini-Player vorladen',
|
||||
preloadMiniPlayerDesc: 'Baut das Mini-Player-Fenster beim App-Start im Hintergrund auf, damit es beim ersten Öffnen sofort Inhalt zeigt. Kostet etwas mehr RAM.',
|
||||
discordRichPresence: 'Discord Rich Presence',
|
||||
discordRichPresenceDesc: 'Zeigt den aktuell gespielten Titel im Discord-Profil an. Discord muss dafür geöffnet sein.',
|
||||
useCustomTitlebar: 'Eigene Titelleiste',
|
||||
useCustomTitlebarDesc: 'Ersetzt die System-Titelleiste durch eine eingebaute, die zum App-Theme passt. Deaktivieren, um die native GNOME/GTK-Titelleiste zu verwenden.',
|
||||
linuxWebkitSmoothScroll: 'Sanftes Mausrad (Linux)',
|
||||
linuxWebkitSmoothScrollDesc: 'An: mit Nachlauf. Aus: zeilenweise wie in GTK-Apps.',
|
||||
discordCoverSource: 'Cover-Quelle',
|
||||
discordCoverSourceDesc: 'Woher das Album-Cover für dein Discord-Profil geladen wird.',
|
||||
discordCoverNone: 'Keine (nur App-Symbol)',
|
||||
discordCoverServer: 'Server (über Album-Info)',
|
||||
discordCoverApple: 'Apple Music',
|
||||
discordOptions: 'Erweiterte Discord-Optionen',
|
||||
discordTemplates: 'Benutzerdefinierte Textvorlagen',
|
||||
discordTemplatesDesc: 'Passen Sie an, welche Informationen in Ihrem Discord-Profil angezeigt werden. Variablen: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Primäre Zeile (details)',
|
||||
discordTemplateState: 'Sekundäre Zeile (state)',
|
||||
discordTemplateLargeText: 'Album-Tooltip (largeText)',
|
||||
nowPlayingEnabled: 'Im Livefenster anzeigen',
|
||||
nowPlayingEnabledDesc: 'Überträgt den aktuell gespielten Titel an die Livehörer-Ansicht des Servers. Deaktivieren, um keine Wiedergabedaten zu senden.',
|
||||
enableBandsintown: 'Bandsintown-Tourdaten',
|
||||
enableBandsintownDesc: 'Zeigt anstehende Konzerte des aktuellen Künstlers im Info-Tab. Daten werden über die öffentliche Bandsintown-API abgerufen.',
|
||||
lyricsServerFirst: 'Server-Lyrics bevorzugen',
|
||||
lyricsServerFirstDesc: 'Server-seitige Lyrics (eingebettete Tags, Sidecar-Dateien) vor LRCLIB abfragen. Deaktivieren, um LRCLIB zuerst zu verwenden.',
|
||||
enableNeteaselyrics: 'Netease Cloud Music Lyrics',
|
||||
enableNeteaselyricsDesc: 'Netease Cloud Music als letzte Lyrics-Quelle verwenden, wenn Server und LRCLIB nichts liefern. Besonders gut für asiatische und internationale Musik.',
|
||||
lyricsSourcesTitle: 'Lyrics-Quellen',
|
||||
lyricsSourcesDesc: 'Wähle, welche Quellen für Lyrics abgefragt werden und in welcher Reihenfolge. Ziehen zum Sortieren. Deaktivierte Quellen werden übersprungen.',
|
||||
lyricsSourceServer: 'Server',
|
||||
lyricsSourceLrclib: 'LRCLIB',
|
||||
lyricsSourceNetease: 'Netease Cloud Music',
|
||||
lyricsModeStandard: 'Standard',
|
||||
lyricsModeStandardDesc: 'Drei Quellen mit frei wählbarer Reihenfolge: Server-Tags, LRCLIB, Netease.',
|
||||
lyricsModeLyricsplus: 'YouLyPlus (Karaoke)',
|
||||
lyricsModeLyricsplusDesc: 'Wort-für-Wort-Sync aus Apple Music, Spotify, Musixmatch & QQ (Community-Backend). Fällt still zurück auf die Standard-Quellen, wenn nichts gefunden wird.',
|
||||
lyricsStaticOnly: 'Nur statische Lyrics anzeigen',
|
||||
lyricsStaticOnlyDesc: 'Synchronisierte Lyrics werden ohne Auto-Scroll und ohne Wort-Hervorhebung als statischer Text dargestellt.',
|
||||
downloadsTitle: 'ZIP-Export & Archivierung',
|
||||
downloadsFolderDesc: 'Zielverzeichnis für Alben, die du als ZIP-Datei auf deinen Computer herunterlädst.',
|
||||
downloadsDefault: 'Standard-Downloads-Ordner',
|
||||
pickFolder: 'Auswählen',
|
||||
pickFolderTitle: 'Download-Ordner auswählen',
|
||||
clearFolder: 'Download-Ordner löschen',
|
||||
logout: 'Abmelden',
|
||||
aboutTitle: 'Über Psysonic',
|
||||
aboutDesc: 'Ein moderner Desktop-Musikplayer für Navidrome. Nutzt die Subsonic-API plus Navidrome-spezifische Erweiterungen. Basiert auf Tauri v2 mit einer nativen Rust-Audio-Engine — schlank und schnell, aber vollgepackt mit Features: Wellenform-Seekbar, synchronisierte Lyrics, Last.fm-Integration, 10-Band-EQ, Crossfade, nahtlose Wiedergabe, Replay Gain, Genre-Browser und eine große Theme-Bibliothek.',
|
||||
aboutLicense: 'Lizenz',
|
||||
aboutLicenseText: 'GNU GPL v3 — kostenlos nutzbar, veränderbar und unter gleicher Lizenz weiterzugeben.',
|
||||
aboutRepo: 'Quellcode auf GitHub',
|
||||
aboutVersion: 'Version',
|
||||
aboutBuiltWith: 'Gebaut mit Tauri · React · TypeScript · Rust/rodio',
|
||||
aboutMaintainersLabel: 'Projektleitung',
|
||||
aboutReleaseNotesLabel: 'Release Notes',
|
||||
aboutReleaseNotesLink: 'Neuigkeiten dieser Version öffnen',
|
||||
aboutContributorsLabel: 'Mitwirkende',
|
||||
showChangelogOnUpdate: "'Was ist neu' bei Update anzeigen",
|
||||
showChangelogOnUpdateDesc: 'Blendet nach einem Update einen dezenten Changelog-Banner über Now Playing ein. Klick öffnet die Release Notes, X blendet ihn aus.',
|
||||
randomMixTitle: 'Zufallsmix-Blacklist',
|
||||
luckyMixMenuTitle: 'Glücks-Mix im Menü anzeigen',
|
||||
luckyMixMenuDesc: 'Aktiviert Glücks-Mix im "Mix erstellen"-Hub und als separaten Menüeintrag bei getrennter Navigation. Sichtbar nur bei aktiviertem AudioMuse auf dem aktiven Server.',
|
||||
randomMixBlacklistTitle: 'Eigene Filter-Keywords',
|
||||
randomMixBlacklistDesc: 'Songs werden ausgeschlossen, wenn ein Keyword auf Genre, Titel, Album oder Künstler zutrifft (aktiv wenn die Checkbox oben an ist).',
|
||||
randomMixBlacklistPlaceholder: 'Keyword hinzufügen…',
|
||||
randomMixBlacklistAdd: 'Hinzufügen',
|
||||
randomMixBlacklistEmpty: 'Noch keine eigenen Keywords hinzugefügt.',
|
||||
randomMixHardcodedTitle: 'Eingebaute Keywords (aktiv wenn Checkbox an)',
|
||||
tabAudio: 'Audio',
|
||||
tabStorage: 'Offline & Cache',
|
||||
tabAppearance: 'Darstellung',
|
||||
tabLibrary: 'Bibliothek',
|
||||
tabServers: 'Server',
|
||||
tabLyrics: 'Songtexte',
|
||||
tabPersonalisation: 'Personalisierung',
|
||||
tabIntegrations: 'Integrationen',
|
||||
inputKeybindingsTitle: 'Tastenkombinationen',
|
||||
aboutContributorsCount_one: '{{count}} Beitrag',
|
||||
aboutContributorsCount_other: '{{count}} Beiträge',
|
||||
searchPlaceholder: 'Einstellungen durchsuchen…',
|
||||
searchNoResults: 'Keine Treffer für deine Suche.',
|
||||
integrationsPrivacyTitle: 'Hinweis zum Datenschutz',
|
||||
integrationsPrivacyBody: 'Alle Integrationen auf diesem Tab sind <strong>Opt-in</strong> und senden, sobald aktiviert, Daten an externe Dienste oder an deinen Navidrome-Server. Last.fm erhält deinen Wiedergabeverlauf, Discord zeigt den aktuell laufenden Track in deinem Profil an, Bandsintown wird pro Künstler für Tour-Daten abgefragt, und der „Jetzt läuft"-Hinweis veröffentlicht deinen aktuellen Titel für andere Benutzer deines Navidrome-Servers. Wer das nicht möchte, lässt den jeweiligen Abschnitt einfach deaktiviert.',
|
||||
homeCustomizerTitle: 'Startseite',
|
||||
queueToolbarTitle: 'Warteschlangen-Toolbar',
|
||||
queueToolbarReset: 'Zurücksetzen',
|
||||
queueToolbarSeparator: 'Trennlinie',
|
||||
sidebarTitle: 'Seitenleiste',
|
||||
sidebarReset: 'Zurücksetzen',
|
||||
artistLayoutTitle: 'Künstlerseiten-Abschnitte',
|
||||
artistLayoutDesc: 'Per Drag & Drop neu anordnen, einzelne Abschnitte der Künstlerseite ein- oder ausblenden. Abschnitte ohne Daten werden automatisch übersprungen.',
|
||||
artistLayoutReset: 'Zurücksetzen',
|
||||
artistLayoutBio: 'Künstler-Biografie',
|
||||
artistLayoutTopTracks: 'Top-Tracks',
|
||||
artistLayoutSimilar: 'Ähnliche Künstler*innen',
|
||||
artistLayoutAlbums: 'Alben',
|
||||
artistLayoutFeatured: 'Auch enthalten auf',
|
||||
sidebarDrag: 'Ziehen zum Umsortieren',
|
||||
sidebarFixed: 'Immer sichtbar',
|
||||
randomNavSplitTitle: 'Mix-Navigation aufteilen',
|
||||
randomNavSplitDesc: '"Zufallsmix", "Zufallsalben" und "Glücks-Mix" als separate Sidebar-Einträge statt als "Mix erstellen"-Hub anzeigen.',
|
||||
tabInput: 'Eingabe',
|
||||
tabUsers: 'Benutzer',
|
||||
shortcutsReset: 'Auf Standard zurücksetzen',
|
||||
shortcutListening: 'Taste drücken…',
|
||||
shortcutUnbound: '—',
|
||||
shortcutClear: 'Löschen',
|
||||
globalShortcutsTitle: 'Globale Shortcuts',
|
||||
globalShortcutsNote: 'Funktionieren systemweit, auch wenn Psysonic im Hintergrund läuft. Mindestens Ctrl, Alt oder Super als Modifier erforderlich.',
|
||||
shortcutPlayPause: 'Wiedergabe / Pause',
|
||||
shortcutNext: 'Nächster Titel',
|
||||
shortcutPrev: 'Vorheriger Titel',
|
||||
shortcutVolumeUp: 'Lautstärke erhöhen',
|
||||
shortcutVolumeDown: 'Lautstärke verringern',
|
||||
shortcutSeekForward: '10s vorspulen',
|
||||
shortcutSeekBackward: '10s zurückspulen',
|
||||
shortcutToggleQueue: 'Warteschlange ein-/ausblenden',
|
||||
shortcutOpenFolderBrowser: '{{folderBrowser}} öffnen',
|
||||
shortcutFullscreenPlayer: 'Vollbild-Player',
|
||||
shortcutNativeFullscreen: 'Nativer Vollbildmodus',
|
||||
shortcutOpenMiniPlayer: 'Mini-Player öffnen',
|
||||
shortcutStartSearch: 'Suche starten',
|
||||
shortcutStartAdvancedSearch: 'Erweiterte Suche starten',
|
||||
shortcutToggleSidebar: 'Seitenleiste umschalten',
|
||||
shortcutMuteSound: 'Stumm schalten',
|
||||
shortcutToggleEqualizer: 'Equalizer öffnen / umschalten',
|
||||
shortcutToggleRepeat: 'Wiederholen umschalten',
|
||||
shortcutOpenNowPlaying: '„Now Playing" öffnen',
|
||||
shortcutShowLyrics: 'Songtexte anzeigen',
|
||||
shortcutFavoriteCurrentTrack: 'Aktuellen Titel zu Favoriten hinzufügen',
|
||||
shortcutOpenHelp: 'Hilfe',
|
||||
tabSystem: 'System',
|
||||
loggingTitle: 'Protokollierung',
|
||||
loggingModeDesc: 'Steuert die Ausführlichkeit der Backend-Protokolle im Terminal.',
|
||||
loggingModeOff: 'Aus',
|
||||
loggingModeNormal: 'Normal',
|
||||
loggingModeDebug: 'Debug',
|
||||
loggingExport: 'Protokolle exportieren',
|
||||
loggingExportSuccess: 'Protokolle exportiert ({{count}} Zeilen).',
|
||||
loggingExportError: 'Protokolle konnten nicht exportiert werden.',
|
||||
ratingsSectionTitle: 'Bewertungen',
|
||||
ratingsSkipStarTitle: 'Skip → 1 Stern',
|
||||
ratingsSkipStarDesc:
|
||||
'Wird ein Titel mehrmals hintereinander übersprungen, bekommt er automatisch 1★. Nur für noch nicht bewertete Titel.',
|
||||
ratingsSkipStarThresholdLabel: 'Skips',
|
||||
ratingsMixFilterTitle: 'Nach Bewertung filtern',
|
||||
ratingsMixFilterDesc:
|
||||
'Gering bewertete Titel in {{mix}} und {{albums}} ausblenden. Nochmals auf den gewählten Stern klicken, um den Filter zu deaktivieren.',
|
||||
ratingsMixMinSong: 'Titel',
|
||||
ratingsMixMinAlbum: 'Alben',
|
||||
ratingsMixMinArtist: 'Interpreten',
|
||||
ratingsMixMinThresholdAria: 'Mindest-Sterne: {{label}}',
|
||||
backupTitle: 'Backup & Wiederherstellung',
|
||||
backupExport: 'Einstellungen exportieren',
|
||||
backupExportDesc: 'Speichert alle Einstellungen, Serverprofile, Last.fm-Konfiguration, Theme, EQ und Tastenkürzel in eine .psybkp-Datei. Passwörter werden im Klartext gespeichert — Datei sicher aufbewahren.',
|
||||
backupImport: 'Einstellungen importieren',
|
||||
backupImportDesc: 'Stellt Einstellungen aus einer .psybkp-Datei wieder her. Die App wird nach dem Import neu geladen.',
|
||||
backupImportConfirm: 'Alle aktuellen Einstellungen werden überschrieben. Fortfahren?',
|
||||
backupSuccess: 'Backup gespeichert',
|
||||
backupImportSuccess: 'Einstellungen wiederhergestellt — wird neu geladen…',
|
||||
backupImportError: 'Ungültige oder beschädigte Backup-Datei.',
|
||||
playbackTitle: 'Wiedergabe',
|
||||
replayGain: 'Replay Gain',
|
||||
replayGainDesc: 'Lautstärke mit ReplayGain-Metadaten normalisieren',
|
||||
replayGainMode: 'Modus',
|
||||
replayGainAuto: 'Auto',
|
||||
replayGainAutoDesc: 'Wählt Album-Gain, wenn benachbarte Tracks in der Warteschlange vom selben Album sind, sonst Track-Gain.',
|
||||
replayGainTrack: 'Track',
|
||||
replayGainAlbum: 'Album',
|
||||
replayGainPreGain: 'Pre-Gain (getaggte Dateien)',
|
||||
replayGainPreGainDesc: 'Pauschaler Boost, der auf jede ReplayGain-Berechnung aufaddiert wird. Hilft, wenn deine Bibliothek insgesamt zu leise wirkt.',
|
||||
replayGainFallback: 'Fallback (ohne Tags / Radio)',
|
||||
replayGainFallbackDesc: 'Wird auf Titel (und Radio-Streams) ohne ReplayGain-Tags angewendet, damit Untagged-Inhalt nicht lauter aus dem Mix springt.',
|
||||
normalization: 'Normalisierung',
|
||||
normalizationDesc: 'Empfundene Lautstärke über Titel, Alben und Radio angleichen.',
|
||||
normalizationOff: 'Aus',
|
||||
normalizationReplayGain: 'ReplayGain',
|
||||
normalizationLufs: 'LUFS',
|
||||
loudnessTargetLufs: 'Ziel-LUFS',
|
||||
loudnessTargetLufsDesc: 'Referenz-Lautstärke, an die alle Titel angepasst werden. Niedrigere Werte = lautere Ausgabe. Streaming-Dienste liegen meist bei etwa -14 LUFS.',
|
||||
loudnessPreAnalysisAttenuation: 'Dämpfung vor Messung',
|
||||
loudnessPreAnalysisAttenuationDesc:
|
||||
'Zusätzliche Dämpfung, bis die Loudness des Titels gespeichert ist. Beim Streamen folgen nur grobe Schätzungen, keine volle Messung. 0 dB = aus; negativer = leiser. Rechts steht der wirksame dB-Wert für die gewählte Ziel-LUFS.',
|
||||
loudnessPreAnalysisAttenuationRef: 'Wirksam {{eff}} dB bei Ziel {{tgt}} LUFS.',
|
||||
loudnessPreAnalysisAttenuationReset: 'Standard',
|
||||
loudnessFirstPlayNote:
|
||||
'Beim ersten Abspielen eines neuen Titels kann die Lautstärke kurz schwanken, während gemessen wird. Beim nächsten Mal greift die gespeicherte Messung und alles bleibt stabil. Kommende Queue-Titel werden meist schon während des vorherigen Songs analysiert — in der Praxis tritt das daher selten auf.',
|
||||
crossfade: 'Crossfade',
|
||||
crossfadeDesc: 'Überblendung zwischen Tracks',
|
||||
crossfadeSecs: '{{n}} s',
|
||||
notWithGapless: 'Nicht verfügbar wenn Nahtlose Wiedergabe aktiv ist',
|
||||
notWithCrossfade: 'Nicht verfügbar wenn Crossfade aktiv ist',
|
||||
gapless: 'Nahtlose Wiedergabe',
|
||||
gaplessDesc: 'Nächsten Track vorpuffern um Lücken zwischen Songs zu vermeiden',
|
||||
preservePlayNextOrder: '„Als Nächstes"-Reihenfolge bewahren',
|
||||
preservePlayNextOrderDesc: 'Neu hinzugefügte „Als Nächstes"-Titel reihen sich hinten an statt sich vorn einzuschieben.',
|
||||
trackPreviewsTitle: 'Track-Vorschau',
|
||||
trackPreviewsToggle: 'Track-Vorschau aktivieren',
|
||||
trackPreviewsDesc: 'Inline Play- und Vorschau-Buttons in den Tracklisten anzeigen für eine kurze Hörprobe mitten im Song.',
|
||||
trackPreviewStart: 'Startposition',
|
||||
trackPreviewStartDesc: 'Wie weit der Track schon gespielt sein soll wenn die Vorschau startet (% der Länge).',
|
||||
trackPreviewDuration: 'Dauer',
|
||||
trackPreviewDurationDesc: 'Wie lange jede Vorschau spielt bevor sie automatisch stoppt.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Wo Vorschauen erscheinen',
|
||||
trackPreviewLocationsDesc: 'Wähle aus, in welchen Listen die Vorschau-Buttons angezeigt werden.',
|
||||
trackPreviewLocation_suggestions: 'In Playlist-Vorschlägen',
|
||||
trackPreviewLocation_albums: 'In Album-Tracklisten',
|
||||
trackPreviewLocation_playlists: 'In Playlists',
|
||||
trackPreviewLocation_favorites: 'In Favoriten',
|
||||
trackPreviewLocation_artist: 'In Künstler-Top-Tracks',
|
||||
trackPreviewLocation_randomMix: 'In Random Mix',
|
||||
preloadMode: 'Nächsten Track vorpuffern',
|
||||
preloadModeDesc: 'Wann mit dem Puffern des nächsten Tracks begonnen werden soll',
|
||||
nextTrackBufferingTitle: 'Pufferung',
|
||||
preloadHotCacheMutualExclusive: 'Preload und Hot Cache erfüllen denselben Zweck – nur eine Methode kann gleichzeitig aktiv sein. Das Aktivieren einer deaktiviert die andere automatisch.',
|
||||
preloadOff: 'Aus',
|
||||
preloadBalanced: 'Ausgewogen (30 s vor Ende)',
|
||||
preloadEarly: 'Früh (nach 5 s Wiedergabe)',
|
||||
preloadCustom: 'Benutzerdefiniert',
|
||||
preloadCustomSeconds: 'Sekunden vor Ende: {{n}}',
|
||||
infiniteQueue: 'Endlose Warteschlange',
|
||||
infiniteQueueDesc: 'Automatisch Zufallstitel anhängen wenn die Warteschlange leer wird',
|
||||
experimental: 'Experimentell',
|
||||
fsPlayerSection: 'Vollbild-Player',
|
||||
fsShowArtistPortrait: 'Künstlerfoto anzeigen',
|
||||
fsShowArtistPortraitDesc: 'Künstlerfoto (oder Albumcover) auf der rechten Seite des Vollbild-Players anzeigen.',
|
||||
fsPortraitDim: 'Abdunkelung des Fotos',
|
||||
fsLyricsStyle: 'Liedtext-Stil',
|
||||
fsLyricsStyleRail: 'Schiene',
|
||||
fsLyricsStyleRailDesc: 'Klassische 5-Zeilen-Schiene.',
|
||||
fsLyricsStyleApple: 'Scrollen',
|
||||
fsLyricsStyleAppleDesc: 'Vollbild-Scrollliste.',
|
||||
sidebarLyricsStyle: 'Text-Scroll-Stil',
|
||||
sidebarLyricsStyleClassic: 'Klassisch',
|
||||
sidebarLyricsStyleClassicDesc: 'Aktive Zeile wird zentriert.',
|
||||
sidebarLyricsStyleApple: 'Apple Music-like',
|
||||
sidebarLyricsStyleAppleDesc: 'Aktive Zeile oben mit sanfter Animation.',
|
||||
seekbarStyle: 'Seekbar-Stil',
|
||||
seekbarStyleDesc: 'Aussehen der Wiedergabe-Seekbar auswählen',
|
||||
seekbarTruewave: 'Echte Wellenform',
|
||||
seekbarPseudowave: 'Pseudo-Wellenform',
|
||||
seekbarLinedot: 'Linie & Punkt',
|
||||
seekbarBar: 'Balken',
|
||||
seekbarThick: 'Dicker Balken',
|
||||
seekbarSegmented: 'Segmentiert',
|
||||
seekbarNeon: 'Neonröhre',
|
||||
seekbarPulsewave: 'Pulswelle',
|
||||
seekbarParticletrail: 'Partikel-Spur',
|
||||
seekbarLiquidfill: 'Flüssigkeit',
|
||||
seekbarRetrotape: 'Retro-Band',
|
||||
themeSchedulerTitle: 'Theme-Zeitplan',
|
||||
themeSchedulerEnable: 'Theme-Zeitplan aktivieren',
|
||||
themeSchedulerEnableSub: 'Wechselt automatisch zwischen zwei Themes basierend auf der Uhrzeit',
|
||||
themeSchedulerDayTheme: 'Tages-Theme',
|
||||
themeSchedulerDayStart: 'Tag beginnt um',
|
||||
themeSchedulerNightTheme: 'Nacht-Theme',
|
||||
themeSchedulerNightStart: 'Nacht beginnt um',
|
||||
themeSchedulerActiveHint: 'Theme-Zeitplan ist aktiv - Themes werden automatisch gewechselt.',
|
||||
visualOptionsTitle: 'Visuelle Optionen',
|
||||
coverArtBackground: 'Cover-Hintergrund',
|
||||
coverArtBackgroundSub: 'Zeigt verschwommenes Cover als Hintergrund in Album/Playlist-Kopfzeilen',
|
||||
playlistCoverPhoto: 'Playlist-Coverfoto',
|
||||
playlistCoverPhotoSub: 'Zeigt Coverfoto-Raster in der Playlist-Detailansicht',
|
||||
showBitrate: 'Bitrate anzeigen',
|
||||
showBitrateSub: 'Audio-Bitrate in Track-Listen anzeigen',
|
||||
floatingPlayerBar: 'Schwebende Player-Leiste',
|
||||
floatingPlayerBarSub: 'Player-Leiste über dem Inhalt schweben lassen',
|
||||
uiScaleTitle: 'Interface-Skalierung',
|
||||
uiScaleLabel: 'Zoom',
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
export const sharePaste = {
|
||||
notLoggedIn: 'Melde dich an und füge den Server hinzu, bevor du einen Freigabe-Link einfügst.',
|
||||
noMatchingServer: 'Kein gespeicherter Server passt zu diesem Link. Füge einen Server mit dieser Adresse hinzu: {{url}}',
|
||||
trackUnavailable: 'Dieser Titel wurde auf dem Server nicht gefunden.',
|
||||
albumUnavailable: 'Dieses Album wurde auf dem Server nicht gefunden.',
|
||||
artistUnavailable: 'Dieser Künstler wurde auf dem Server nicht gefunden.',
|
||||
composerUnavailable: 'Diese*r Komponist*in wurde auf dem Server nicht gefunden.',
|
||||
openedTrack: 'Geteilter Titel wird abgespielt.',
|
||||
openedAlbum: 'Geteiltes Album wird geöffnet.',
|
||||
openedArtist: 'Geteilter Künstler wird geöffnet.',
|
||||
openedComposer: 'Geteilte*r Komponist*in wird geöffnet.',
|
||||
openedQueue_one: '{{count}} Titel aus Freigabe-Link wird abgespielt.',
|
||||
openedQueue_other: '{{count}} Titel aus Freigabe-Link werden abgespielt.',
|
||||
openedQueuePartial:
|
||||
'{{played}} von {{total}} Titeln aus dem Link werden abgespielt ({{skipped}} auf diesem Server nicht gefunden).',
|
||||
queueAllUnavailable: 'Keiner der Titel aus diesem Link wurde auf dem Server gefunden.',
|
||||
genericError: 'Freigabe-Link konnte nicht geöffnet werden.',
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
export const sidebar = {
|
||||
library: 'Bibliothek',
|
||||
mainstage: 'Mainstage',
|
||||
newReleases: 'Neueste',
|
||||
allAlbums: 'Alle Alben',
|
||||
randomAlbums: 'Zufallsalben',
|
||||
randomPicker: 'Mix erstellen',
|
||||
artists: 'Künstler',
|
||||
composers: 'Komponist*innen',
|
||||
randomMix: 'Zufallsmix',
|
||||
favorites: 'Favoriten',
|
||||
nowPlaying: 'Now Playing',
|
||||
system: 'System',
|
||||
statistics: 'Statistiken',
|
||||
settings: 'Einstellungen',
|
||||
help: 'Hilfe',
|
||||
expand: 'Sidebar einblenden',
|
||||
collapse: 'Sidebar ausblenden',
|
||||
downloadingTracks: '{{n}} Tracks werden gecacht…',
|
||||
syncingTracks: 'Synchronisiere {{done}}/{{total}}…',
|
||||
cancelDownload: 'Download abbrechen',
|
||||
offlineLibrary: 'Offline-Bibliothek',
|
||||
genres: 'Genres',
|
||||
tracks: 'Titel',
|
||||
playlists: 'Playlists',
|
||||
mostPlayed: 'Meistgehört',
|
||||
losslessAlbums: 'Lossless',
|
||||
radio: 'Internetradio',
|
||||
folderBrowser: 'Ordner-Browser',
|
||||
deviceSync: 'Gerätesync',
|
||||
libraryScope: 'Bibliotheksumfang',
|
||||
allLibraries: 'Alle Bibliotheken',
|
||||
expandPlaylists: 'Playlists ausklappen',
|
||||
collapsePlaylists: 'Playlists einklappen',
|
||||
more: 'Mehr',
|
||||
feelingLucky: 'Glücks-Mix',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export const smartPlaylists = {
|
||||
sectionBasic: '1. Basis',
|
||||
sectionGenres: '2. Genres',
|
||||
sectionYearsAndFilters: '3. Jahre und Filter',
|
||||
genreMode: 'Genre-Modus',
|
||||
genreModeInclude: 'Genres einschließen',
|
||||
genreModeExclude: 'Genres ausschließen',
|
||||
genreSearchPlaceholder: 'Genres filtern...',
|
||||
availableGenres: 'Verfügbar',
|
||||
selectedGenres: 'Ausgewählt',
|
||||
yearMode: 'Jahresmodus',
|
||||
yearModeInclude: 'Bereich einschließen',
|
||||
yearModeExclude: 'Bereich ausschließen',
|
||||
name: 'Name (ohne Präfix)',
|
||||
limit: 'Limit',
|
||||
limitHint: 'Wie viele Songs in die Playlist aufgenommen werden (1-{{max}}, üblicherweise 50).',
|
||||
artistContains: 'Künstler enthält…',
|
||||
albumContains: 'Album enthält…',
|
||||
titleContains: 'Titel enthält…',
|
||||
minRating: 'Mindestbewertung',
|
||||
minRatingAria: 'Mindestbewertung für Smart Playlist',
|
||||
minRatingHint: '0 deaktiviert die Mindestgrenze; 1-5 behält Songs mit Bewertung über dem gewählten Wert.',
|
||||
fromYear: 'Von Jahr',
|
||||
toYear: 'Bis Jahr',
|
||||
excludeUnrated: 'Unbewertete Songs ausschließen',
|
||||
compilationOnly: 'Nur Sammlungen',
|
||||
create: 'Neue Smart Playlist',
|
||||
save: 'Smart Playlist speichern',
|
||||
created: '{{name}} erstellt',
|
||||
updated: '{{name}} aktualisiert',
|
||||
createFailed: 'Smart Playlist konnte nicht erstellt werden.',
|
||||
updateFailed: 'Smart Playlist konnte nicht aktualisiert werden.',
|
||||
navidromeOnly: 'Smart Playlists können nur auf Navidrome-Servern erstellt werden.',
|
||||
loadFailed: 'Smart Playlists konnten nicht von Navidrome geladen werden.',
|
||||
sortRandom: 'Sortierung: zufällig',
|
||||
sortTitleAsc: 'Sortierung: Titel A-Z',
|
||||
sortTitleDesc: 'Sortierung: Titel Z-A',
|
||||
sortYearDesc: 'Sortierung: Jahr absteigend',
|
||||
sortYearAsc: 'Sortierung: Jahr aufsteigend',
|
||||
sortPlayCountDesc: 'Sortierung: Wiedergaben absteigend',
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
export const songInfo = {
|
||||
title: 'Song-Infos',
|
||||
songTitle: 'Titel',
|
||||
artist: 'Künstler',
|
||||
album: 'Album',
|
||||
albumArtist: 'Album-Künstler',
|
||||
year: 'Jahr',
|
||||
genre: 'Genre',
|
||||
duration: 'Länge',
|
||||
track: 'Track',
|
||||
format: 'Format',
|
||||
bitrate: 'Bitrate',
|
||||
sampleRate: 'Abtastrate',
|
||||
bitDepth: 'Bittiefe',
|
||||
channels: 'Kanäle',
|
||||
fileSize: 'Dateigröße',
|
||||
path: 'Speicherort',
|
||||
replayGainTrack: 'RG Track Gain',
|
||||
replayGainAlbum: 'RG Album Gain',
|
||||
replayGainPeak: 'RG Track Peak',
|
||||
mono: 'Mono',
|
||||
stereo: 'Stereo',
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
export const statistics = {
|
||||
title: 'Statistiken',
|
||||
recentlyPlayed: 'Zuletzt gehört',
|
||||
mostPlayed: 'Meistgespielte Alben',
|
||||
highestRated: 'Höchstbewertete Alben',
|
||||
genreDistribution: 'Genre-Verteilung (Top 20)',
|
||||
loadMore: 'Mehr laden',
|
||||
statArtists: 'Künstler',
|
||||
statArtistsTooltip: 'Nur Album-Künstler — Künstler, die ausschließlich als Track-Künstler vorkommen (Featured, Gast usw.) und kein eigenes Album haben, werden nicht gezählt.',
|
||||
statAlbums: 'Alben',
|
||||
statSongs: 'Songs',
|
||||
statGenres: 'Genres',
|
||||
statPlaytime: 'Gesamtspielzeit',
|
||||
genreInsights: 'Genre-Einblicke',
|
||||
formatDistribution: 'Format-Verteilung',
|
||||
formatSample: 'Stichprobe von {{n}} Titeln',
|
||||
computing: 'Wird berechnet…',
|
||||
genreSongs: '{{count}} Songs',
|
||||
genreAlbums: '{{count}} Alben',
|
||||
recentlyAdded: 'Neu hinzugefügt',
|
||||
decadeDistribution: 'Alben nach Jahrzehnt',
|
||||
decadeAlbums_one: '{{count}} Album',
|
||||
decadeAlbums_other: '{{count}} Alben',
|
||||
decadeUnknown: 'Unbekannt',
|
||||
lfmTitle: 'Last.fm Statistiken',
|
||||
lfmTopArtists: 'Top-Künstler',
|
||||
lfmTopAlbums: 'Top-Alben',
|
||||
lfmTopTracks: 'Top-Titel',
|
||||
lfmPlays: '{{count}} Plays',
|
||||
lfmPeriodOverall: 'Gesamt',
|
||||
lfmPeriod7day: '7 Tage',
|
||||
lfmPeriod1month: '1 Monat',
|
||||
lfmPeriod3month: '3 Monate',
|
||||
lfmPeriod6month: '6 Monate',
|
||||
lfmPeriod12month: '12 Monate',
|
||||
lfmNotConnected: 'Verbinde Last.fm in den Einstellungen, um deine Statistiken zu sehen.',
|
||||
lfmRecentTracks: 'Zuletzt gescrobbelt',
|
||||
lfmNowPlaying: 'Läuft gerade',
|
||||
lfmJustNow: 'gerade eben',
|
||||
lfmMinutesAgo: 'vor {{n}} Min.',
|
||||
lfmHoursAgo: 'vor {{n}} Std.',
|
||||
lfmDaysAgo: 'vor {{n}} Tagen',
|
||||
topRatedSongs: 'Bestbewertete Songs',
|
||||
topRatedArtists: 'Bestbewertete Künstler',
|
||||
noRatedSongs: 'Noch keine bewerteten Songs. Songs in Album- oder Playlist-Ansicht bewerten.',
|
||||
noRatedArtists: 'Noch keine bewerteten Künstler.',
|
||||
exportShare: 'Teilen',
|
||||
exportTitle: 'Top-Alben teilen',
|
||||
exportSubtitle: 'Ein teilbares Bild deiner meistgespielten Alben erstellen.',
|
||||
exportFormat: 'Format',
|
||||
exportFormatStory: 'Story',
|
||||
exportFormatSquare: 'Quadrat',
|
||||
exportFormatTwitter: 'Twitter-Card',
|
||||
exportGrid: 'Raster',
|
||||
exportGridLabel: '{{n}}×{{n}}',
|
||||
exportPreview: 'Vorschau',
|
||||
exportGenerate: 'Erstellen',
|
||||
exportSave: 'Bild speichern…',
|
||||
exportCancel: 'Abbrechen',
|
||||
exportFooterLabel: 'Top-Alben',
|
||||
exportNotEnough: 'Für ein {{n}}×{{n}}-Raster braucht es mindestens {{count}} Alben in der Library.',
|
||||
exportSaving: 'Speichere…',
|
||||
exportSaved: 'Gespeichert.',
|
||||
exportSaveFailed: 'Bild konnte nicht gespeichert werden.',
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
export const tracks = {
|
||||
title: 'Titel',
|
||||
subtitle: 'Stöbern. Suchen. Entdecken.',
|
||||
heroEyebrow: 'Titel des Moments',
|
||||
heroReroll: 'Anderen wählen',
|
||||
playSong: 'Abspielen',
|
||||
enqueueSong: 'Zur Warteschlange',
|
||||
railRandom: 'Zufallsauswahl',
|
||||
railHighlyRated: 'Hoch bewertet',
|
||||
browseTitle: 'Alle Titel durchstöbern',
|
||||
browseUnsupported: 'Dieser Server listet nicht die ganze Bibliothek auf einmal. Nutze die Suche oben, um bestimmte Titel zu finden.',
|
||||
searchPlaceholder: 'Titel, Künstler oder Album suchen…',
|
||||
count_one: '{{count}} Titel',
|
||||
count_other: '{{count}} Titel',
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const tray = {
|
||||
playPause: 'Wiedergabe / Pause',
|
||||
nextTrack: 'Nächster Titel',
|
||||
previousTrack: 'Vorheriger Titel',
|
||||
showHide: 'Anzeigen / Verbergen',
|
||||
exitPsysonic: 'Psysonic beenden',
|
||||
nothingPlaying: 'Nichts wird abgespielt',
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const whatsNew = {
|
||||
title: 'Was ist neu',
|
||||
empty: 'Für diese Version liegt noch kein Changelog-Eintrag vor.',
|
||||
bannerTitle: 'Changelog',
|
||||
bannerCollapsed: 'Neu in v{{version}}',
|
||||
dismiss: 'Ausblenden',
|
||||
close: 'Schließen',
|
||||
};
|
||||
-1876
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
export const albumDetail = {
|
||||
back: 'Back',
|
||||
orbitDoubleClickHint: 'Double-click to add this track to the Orbit queue',
|
||||
playAll: 'Play All',
|
||||
shareAlbum: 'Share album',
|
||||
enqueue: 'Enqueue',
|
||||
enqueueTooltip: 'Add entire album to queue',
|
||||
artistBio: 'Artist Bio',
|
||||
download: 'Download (ZIP)',
|
||||
downloading: 'Loading…',
|
||||
cacheOffline: 'Make available offline',
|
||||
offlineCached: 'Available offline',
|
||||
offlineDownloading: 'Caching… ({{n}}/{{total}})',
|
||||
removeOffline: 'Remove offline cache',
|
||||
offlineStorageFull: 'Offline storage full (limit: {{mb}} MB). Free up space by deleting an album from your Offline Library, or increase the limit in Settings.',
|
||||
offlineStorageGoToLibrary: 'Offline Library',
|
||||
offlineStorageGoToSettings: 'Settings',
|
||||
favoriteAdd: 'Add to Favorites',
|
||||
favoriteRemove: 'Remove from Favorites',
|
||||
favorite: 'Favorite',
|
||||
noBio: 'No biography available.',
|
||||
moreByArtist: 'More by {{artist}}',
|
||||
tracksCount: '{{n}} Tracks',
|
||||
goToArtist: 'Go to {{artist}}',
|
||||
moreLabelAlbums: 'More albums on {{label}}',
|
||||
trackTitle: 'Title',
|
||||
trackAlbum: 'Album',
|
||||
trackArtist: 'Artist',
|
||||
trackGenre: 'Genre',
|
||||
trackFormat: 'Format',
|
||||
trackFavorite: 'Favorite',
|
||||
trackRating: 'Rating',
|
||||
trackDuration: 'Duration',
|
||||
trackTotal: 'Total',
|
||||
columns: 'Columns',
|
||||
resetColumns: 'Reset to defaults',
|
||||
notFound: 'Album not found.',
|
||||
bioModal: 'Artist Biography',
|
||||
bioClose: 'Close',
|
||||
ratingLabel: 'Rating',
|
||||
enlargeCover: 'Enlarge',
|
||||
filterSongs: 'Filter songs…',
|
||||
sortNatural: 'Natural',
|
||||
sortByTitle: 'A–Z (Title)',
|
||||
sortByArtist: 'A–Z (Artist)',
|
||||
sortByAlbum: 'A–Z (Album)',
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
export const albums = {
|
||||
title: 'All Albums',
|
||||
sortByName: 'A–Z (Album)',
|
||||
sortByArtist: 'A–Z (Artist)',
|
||||
sortNewest: 'Newest first',
|
||||
sortRandom: 'Random',
|
||||
yearFrom: 'From',
|
||||
yearTo: 'To',
|
||||
yearFilterClear: 'Clear year filter',
|
||||
yearFilterLabel: 'Year',
|
||||
compilationLabel: 'Compilations',
|
||||
compilationOnly: 'Only compilations',
|
||||
compilationHide: 'Hide compilations',
|
||||
compilationTooltipAll: 'All albums · click: only compilations',
|
||||
compilationTooltipOnly: 'Only compilations · click: hide compilations',
|
||||
compilationTooltipHide: 'Compilations hidden · click: show all',
|
||||
select: 'Multi-select',
|
||||
startSelect: 'Enable multi-select',
|
||||
cancelSelect: 'Cancel',
|
||||
selectionCount: '{{count}} selected',
|
||||
downloadZips: 'Download ZIPs',
|
||||
addOffline: 'Add Offline',
|
||||
enqueueSelected_one: 'Enqueue ({{count}})',
|
||||
enqueueSelected_other: 'Enqueue ({{count}})',
|
||||
enqueueQueued_one: 'Added {{count}} album to queue',
|
||||
enqueueQueued_other: 'Added {{count}} albums to queue',
|
||||
downloadingZip: 'Downloading {{current}}/{{total}}: {{name}}',
|
||||
downloadZipDone: '{{count}} ZIP(s) downloaded',
|
||||
downloadZipFailed: 'Failed to download {{name}}',
|
||||
offlineQueuing: 'Queuing {{count}} album(s) for offline…',
|
||||
offlineFailed: 'Failed to add {{name}} offline',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export const artistDetail = {
|
||||
back: 'Back',
|
||||
albums: 'Albums',
|
||||
album: 'Album',
|
||||
playAll: 'Play All',
|
||||
shareArtist: 'Share artist',
|
||||
shuffle: 'Shuffle',
|
||||
radio: 'Radio',
|
||||
loading: 'Loading…',
|
||||
noRadio: 'No similar tracks found for this artist.',
|
||||
notFound: 'Artist not found.',
|
||||
albumsBy: 'Albums by {{name}}',
|
||||
topTracks: 'Top Tracks',
|
||||
noAlbums: 'No albums found.',
|
||||
trackTitle: 'Title',
|
||||
trackAlbum: 'Album',
|
||||
trackDuration: 'Duration',
|
||||
favoriteAdd: 'Add to Favorites',
|
||||
favoriteRemove: 'Remove from Favorites',
|
||||
favorite: 'Favorite',
|
||||
albumCount_one: '{{count}} Album',
|
||||
albumCount_other: '{{count}} Albums',
|
||||
openedInBrowser: 'Opened in browser',
|
||||
featuredOn: 'Also Featured On',
|
||||
similarArtists: 'Similar Artists',
|
||||
cacheOffline: 'Save discography offline',
|
||||
offlineCached: 'Discography cached',
|
||||
offlineDownloading: 'Caching… ({{done}}/{{total}} albums)',
|
||||
uploadImage: 'Upload artist image',
|
||||
uploadImageError: 'Failed to upload image',
|
||||
releaseTypes: {
|
||||
album: 'Album',
|
||||
ep: 'EP',
|
||||
single: 'Single',
|
||||
compilation: 'Compilation',
|
||||
live: 'Live',
|
||||
soundtrack: 'Soundtrack',
|
||||
remix: 'Remix',
|
||||
other: 'Other',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
export const artists = {
|
||||
title: 'Artists',
|
||||
search: 'Search…',
|
||||
all: 'All',
|
||||
gridView: 'Grid view',
|
||||
listView: 'List view',
|
||||
imagesOn: 'Artist images on — may increase network and system load',
|
||||
imagesOff: 'Artist images off — showing initials only',
|
||||
loadMore: 'Load more',
|
||||
notFound: 'No artists found.',
|
||||
albumCount_one: '{{count}} Album',
|
||||
albumCount_other: '{{count}} Albums',
|
||||
selectionCount: '{{count}} selected',
|
||||
select: 'Multi-select',
|
||||
startSelect: 'Enable multi-select',
|
||||
cancelSelect: 'Cancel',
|
||||
addToPlaylist: 'Add to Playlist',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export const changelog = {
|
||||
modalTitle: "What's New",
|
||||
dontShowAgain: "Don't show again",
|
||||
close: 'Got it',
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
export const common = {
|
||||
albums: 'Albums',
|
||||
album: 'Album',
|
||||
loading: 'Loading…',
|
||||
loadingMore: 'Loading…',
|
||||
loadingPlaylists: 'Loading Playlists…',
|
||||
noAlbums: 'No albums found.',
|
||||
downloading: 'Downloading…',
|
||||
downloadZip: 'Download (ZIP)',
|
||||
back: 'Back',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
save: 'Save',
|
||||
delete: 'Delete',
|
||||
use: 'Use',
|
||||
add: 'Add',
|
||||
new: 'New',
|
||||
active: 'Active',
|
||||
download: 'Download',
|
||||
chooseDownloadFolder: 'Choose download folder',
|
||||
noFolderSelected: 'No folder selected',
|
||||
rememberDownloadFolder: 'Remember this folder',
|
||||
filterGenre: 'Genre Filter',
|
||||
filterSearchGenres: 'Search genres…',
|
||||
filterNoGenres: 'No genres match',
|
||||
filterClear: 'Clear',
|
||||
favorites: 'Favorites',
|
||||
favoritesTooltipOff: 'Show only favorites',
|
||||
favoritesTooltipOn: 'Show all',
|
||||
play: 'Play',
|
||||
bulkSelected: '{{count}} selected',
|
||||
clearSelection: 'Clear selection',
|
||||
bulkAddToPlaylist: 'Add to Playlist',
|
||||
bulkRemoveFromPlaylist: 'Remove from Playlist',
|
||||
bulkClear: 'Clear selection',
|
||||
updaterAvailable: 'Update available',
|
||||
updaterVersion: 'v{{version}} is available',
|
||||
updaterWebsite: 'Website',
|
||||
updaterModalTitle: 'New Version Available',
|
||||
updaterChangelog: "What's New",
|
||||
updaterDownloadBtn: 'Download Now',
|
||||
updaterSkipBtn: 'Skip this Version',
|
||||
updaterRemindBtn: 'Remind me Later',
|
||||
updaterDone: 'Download complete',
|
||||
updaterShowFolder: 'Show in Folder',
|
||||
updaterInstallHint: 'Close Psysonic and run the installer manually.',
|
||||
updaterAurHint: 'Install the update via AUR:',
|
||||
updaterErrorMsg: 'Download failed',
|
||||
updaterRetryBtn: 'Retry',
|
||||
updaterInstallNow: 'Install now',
|
||||
updaterMacReadyTitle: 'Ready to install',
|
||||
updaterMacReady: 'The update downloads, verifies and applies in place — no DMG needed. The app restarts automatically when done.',
|
||||
updaterTrustNotarized: 'Notarized by Apple',
|
||||
updaterTrustSignature: 'Signature verified',
|
||||
updaterMacDoneTitle: 'Update installed',
|
||||
updaterRestartingIn: 'Restarting in {{n}}s…',
|
||||
updaterRestarting: 'Restarting…',
|
||||
updaterRestartNow: 'Restart now',
|
||||
durationHoursMinutes: '{{hours}}h {{minutes}}m',
|
||||
durationMinutesOnly: '{{minutes}}m',
|
||||
updaterOpenGitHub: 'Open on GitHub',
|
||||
filters: 'Filters',
|
||||
more: 'more',
|
||||
yearRange: 'Year Range',
|
||||
clearAll: 'Clear all',
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export const composerDetail = {
|
||||
back: 'Back',
|
||||
notFound: 'Composer not found.',
|
||||
about: 'About this composer',
|
||||
works: 'Works',
|
||||
noWorks: 'No works found.',
|
||||
workCount_one: '{{count}} work',
|
||||
workCount_other: '{{count}} works',
|
||||
shareComposer: 'Share composer',
|
||||
unknownComposer: 'Composer',
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
export const composers = {
|
||||
title: 'Composers',
|
||||
search: 'Search…',
|
||||
notFound: 'No composers found.',
|
||||
unsupported: 'Browse by Composer requires Navidrome 0.55 or newer.',
|
||||
loadFailed: 'Could not load composers.',
|
||||
retry: 'Retry',
|
||||
involvedIn_one: 'Involved in {{count}} album',
|
||||
involvedIn_other: 'Involved in {{count}} albums',
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
export const connection = {
|
||||
connected: 'Connected',
|
||||
connectedTo: 'Connected to {{server}}',
|
||||
disconnected: 'Disconnected',
|
||||
disconnectedFrom: 'Cannot reach {{server}} — click to check settings',
|
||||
checking: 'Connecting…',
|
||||
extern: 'Extern',
|
||||
offlineTitle: 'No server connection',
|
||||
offlineSubtitle: 'Cannot reach {{server}}. Check your network or server.',
|
||||
offlineModeBanner: 'Offline Mode — playing from local cache',
|
||||
offlineNoCacheBanner: 'No server connection — cannot reach {{server}}',
|
||||
offlineLibraryTitle: 'Offline Library',
|
||||
offlineLibraryEmpty: 'No albums cached yet. Go online, open an album and click "Make available offline".',
|
||||
offlineAlbumCount: '{{n}} album',
|
||||
offlineAlbumCount_plural: '{{n}} albums',
|
||||
offlineFilterAll: 'All',
|
||||
offlineFilterAlbums: 'Albums',
|
||||
offlineFilterPlaylists: 'Playlists',
|
||||
offlineFilterArtists: 'Discographies',
|
||||
retry: 'Retry',
|
||||
serverSettings: 'Server Settings',
|
||||
switchServerTitle: 'Switch server',
|
||||
switchServerHint: 'Click to choose another saved server.',
|
||||
manageServers: 'Manage servers…',
|
||||
switchFailed: 'Could not switch — server unreachable.',
|
||||
lastfmConnected: 'Last.fm connected as @{{user}}',
|
||||
lastfmSessionInvalid: 'Session invalid — click to re-connect',
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
export const contextMenu = {
|
||||
playNow: 'Play Now',
|
||||
playNext: 'Play Next',
|
||||
addToQueue: 'Add to Queue',
|
||||
enqueueAlbum: 'Enqueue Album',
|
||||
enqueueAlbums_one: 'Enqueue {{count}} Album',
|
||||
enqueueAlbums_other: 'Enqueue {{count}} Albums',
|
||||
startRadio: 'Start Radio',
|
||||
instantMix: 'Instant Mix',
|
||||
instantMixFailed: 'Could not build Instant Mix — server or plugin error.',
|
||||
cliMixNeedsTrack: 'Nothing is playing — start playback first, then run the mix command again.',
|
||||
lfmLove: 'Love on Last.fm',
|
||||
lfmUnlove: 'Unlove on Last.fm',
|
||||
favorite: 'Favorite',
|
||||
favoriteArtist: 'Favorite Artist',
|
||||
favoriteAlbum: 'Favorite Album',
|
||||
unfavorite: 'Remove from Favorites',
|
||||
unfavoriteArtist: 'Remove Artist from Favorites',
|
||||
unfavoriteAlbum: 'Remove Album from Favorites',
|
||||
removeFromQueue: 'Remove from Queue',
|
||||
removeFromPlaylist: 'Remove from Playlist',
|
||||
openAlbum: 'Open Album',
|
||||
goToArtist: 'Go to Artist',
|
||||
download: 'Download (ZIP)',
|
||||
addToPlaylist: 'Add to Playlist',
|
||||
selectedPlaylists: '{{count}} playlists selected',
|
||||
selectedAlbums: '{{count}} albums selected',
|
||||
selectedArtists: '{{count}} artists selected',
|
||||
songInfo: 'Song Info',
|
||||
shareLink: 'Copy share link',
|
||||
shareCopied: 'Share link copied to the clipboard.',
|
||||
shareCopyFailed: 'Could not copy to the clipboard.',
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
export const deviceSync = {
|
||||
title: 'Device Sync',
|
||||
targetFolder: 'Target Folder',
|
||||
noFolderChosen: 'No folder chosen',
|
||||
selectDrive: 'Select a drive…',
|
||||
refreshDrives: 'Refresh drives',
|
||||
noDrivesDetected: 'No removable drives detected',
|
||||
browseManual: 'Browse manually…',
|
||||
free: 'free',
|
||||
notMountedVolume: 'Target is not on a mounted volume. The drive may have been disconnected.',
|
||||
chooseFolder: 'Choose…',
|
||||
targetDevice: 'Target Device',
|
||||
schemaLabel: 'Naming scheme',
|
||||
schemaHint: 'Fixed scheme for reliable cross-OS sync. Playlists are written as .m3u8 that reference the album tracks — no duplicates on the device.',
|
||||
migrateButton: 'Reorganize existing files…',
|
||||
migrateTooltip: 'Rename existing files on the device into the new scheme (from the old filename template).',
|
||||
migrateTitle: 'Reorganize existing files',
|
||||
migrateLoading: 'Analyzing existing files…',
|
||||
migrateNothingToDo: 'All existing files already match the new scheme — nothing to do.',
|
||||
migrateNoTemplate: 'No legacy filename template found on the device. Migration only applies when the stick was synced with a Psysonic version that supported custom templates.',
|
||||
migrateFilesToRename: 'files will be renamed',
|
||||
migrateUnchanged: '{{n}} files are already at the correct path',
|
||||
migrateCollisions: '{{n}} files cannot be renamed automatically (multiple tracks map to the same target). They will be left untouched — the next sync re-downloads them into the correct location.',
|
||||
migratePreviewNote: 'Old template: {{tpl}}',
|
||||
migrateExecuting: 'Renaming files…',
|
||||
migrateSuccess: '{{n}} files renamed successfully',
|
||||
migrateFailed: '{{n}} renames failed',
|
||||
migrateShowErrors: 'Show errors',
|
||||
migrateStart: 'Start renaming',
|
||||
onDevice: 'Device Manager',
|
||||
addSources: 'Add…',
|
||||
colName: 'Name',
|
||||
colType: 'Type',
|
||||
colStatus: 'Status',
|
||||
syncResult: '{{done}} transferred, {{skipped}} already up to date ({{total}} total)',
|
||||
deleteFromDevice: 'Mark for deletion ({{count}})',
|
||||
confirmDelete: 'Delete {{count}} item(s) from the device: {{names}}?',
|
||||
deleteComplete: '{{count}} item(s) removed from device.',
|
||||
manifestImported: 'Imported {{count}} source(s) from device manifest.',
|
||||
selectedSources: 'Selected Sources',
|
||||
noSourcesSelected: 'No sources selected. Click items in the browser to add them.',
|
||||
clearAll: 'Clear all',
|
||||
tabPlaylists: 'Playlists',
|
||||
tabAlbums: 'Albums',
|
||||
tabArtists: 'Artists',
|
||||
searchPlaceholder: 'Search…',
|
||||
syncButton: 'Sync to Device',
|
||||
actionTransfer: 'Transfer to Device',
|
||||
actionDelete: 'Delete from Device',
|
||||
actionApplyAll: 'Apply All Changes',
|
||||
cancel: 'Cancel',
|
||||
noTargetDir: 'Please choose a target folder first.',
|
||||
noSources: 'Please select at least one source.',
|
||||
noTracks: 'No tracks found in the selected sources.',
|
||||
fetchError: 'Failed to fetch tracks from server.',
|
||||
syncComplete: 'Sync complete.',
|
||||
dismiss: 'Dismiss',
|
||||
cancelSync: 'Cancel',
|
||||
syncCancelled: 'Sync cancelled ({{done}} / {{total}} transferred).',
|
||||
statusSynced: 'Synced',
|
||||
statusPending: 'Pending',
|
||||
statusDeletion: 'Deletion',
|
||||
markForDeletion: 'Mark for deletion',
|
||||
undoDeletion: 'Undo deletion',
|
||||
removeSource: 'Remove',
|
||||
syncInBackground: 'Sync started in background — you can navigate away.',
|
||||
syncInProgress: '{{done}} / {{total}} tracks…',
|
||||
scanningDevice: 'Scanning device…',
|
||||
syncSummary: 'Sync Summary',
|
||||
calculating: 'Calculating required payload…',
|
||||
filesToAdd: 'Files to Add:',
|
||||
filesToDelete: 'Files to Delete:',
|
||||
netChange: 'Net Change:',
|
||||
availableSpace: 'Available Disk Space:',
|
||||
spaceWarning: 'Warning: Target device does not have enough reported space.',
|
||||
proceed: 'Proceed with Sync',
|
||||
notEnoughSpace: 'Not enough physical disk space detected!',
|
||||
liveSearch: 'Live',
|
||||
randomAlbumsLabel: 'Random Albums',
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const entityRating = {
|
||||
albumShort: 'Album rating',
|
||||
artistShort: 'Artist rating',
|
||||
albumAriaLabel: 'Album rating',
|
||||
artistAriaLabel: 'Artist rating',
|
||||
selectedArtistsRatingAriaLabel: 'Star rating for {{count}} selected artists',
|
||||
selectedAlbumsRatingAriaLabel: 'Star rating for {{count}} selected albums',
|
||||
saveFailed: 'Could not save rating.',
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export const favorites = {
|
||||
title: 'Favorites',
|
||||
empty: "You haven't saved any favorites yet.",
|
||||
artists: 'Artists',
|
||||
albums: 'Albums',
|
||||
songs: 'Songs',
|
||||
enqueueAll: 'Add all to queue',
|
||||
playAll: 'Play all',
|
||||
removeSong: 'Remove from favorites',
|
||||
stations: 'Radio Stations',
|
||||
showingFiltered: 'Showing {{filtered}} of {{total}} ({{artist}})',
|
||||
showingCount: 'Showing {{filtered}} of {{total}}',
|
||||
clearArtistFilter: 'Clear artist filter',
|
||||
noFilterResults: 'No results with selected filters.',
|
||||
allArtists: 'All Artists',
|
||||
topArtists: 'Top Artists by Favorites',
|
||||
topArtistsSongCount_one: '{{count}} song',
|
||||
topArtistsSongCount_other: '{{count}} songs',
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
export const folderBrowser = {
|
||||
empty: 'Empty folder',
|
||||
error: 'Failed to load',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
export const genres = {
|
||||
title: 'Genres',
|
||||
genreCount: 'Genres',
|
||||
albumCount_one: '{{count}} album',
|
||||
albumCount_other: '{{count}} albums',
|
||||
loading: 'Loading genres…',
|
||||
empty: 'No genres found.',
|
||||
albumsLoading: 'Loading albums…',
|
||||
albumsEmpty: 'No albums found for this genre.',
|
||||
loadMore: 'Load more',
|
||||
back: 'Back',
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
export const help = {
|
||||
title: 'Help',
|
||||
searchPlaceholder: 'Search Help…',
|
||||
noResults: 'No matching topics. Try a different search term.',
|
||||
// ── Section 1: Getting Started ─────────────────────────────────────────
|
||||
s1: 'Getting Started',
|
||||
q1: 'Which servers are compatible?',
|
||||
a1: 'Psysonic is built first and foremost for Navidrome and is fully Subsonic-compatible — Gonic, Airsonic, LMS and other Subsonic-API servers also work. Some advanced features (ratings, smart playlists, magic-string sharing, user management) require Navidrome.',
|
||||
q2: 'How do I add a server?',
|
||||
a2: 'Settings → Servers → Add Server. Enter the URL (e.g. http://192.168.1.100:4533), username, and password. Psysonic tests the connection before saving — nothing is stored if it fails. You can add as many servers as you like and switch between them in the header at any time; only one is active at a time.',
|
||||
q3: 'Quick tour of the UI?',
|
||||
a3: 'Sidebar (left) for navigation, Mainstage / pages in the middle, Player Bar at the bottom, and the Queue Panel on the right (toggle from the top-right header next to the Now-Playing indicator). The search bar at the top searches your whole library; "Now Playing" shows what other users on the same Navidrome server are listening to right now.',
|
||||
// ── Section 2: Playback & Queue ────────────────────────────────────────
|
||||
s2: 'Playback & Queue',
|
||||
q4: 'How do I use the queue?',
|
||||
a4: 'Open the Queue Panel from the top-right header. Drag rows to reorder them, drop them outside to remove, or use the queue toolbar to shuffle, save the queue as a playlist, or jump to a track. Drag rows out of the panel to drop them somewhere else as a transfer.',
|
||||
q5: 'Gapless vs Crossfade — what is the difference?',
|
||||
a5: 'Gapless pre-buffers the next track so there is zero silence between songs (best for live albums and DJ mixes). Crossfade fades the current track out while the next fades in over 1–10 s (best for shuffled mixes). They are mutually exclusive — enabling one disables the other. Configure both in Settings → Audio.',
|
||||
q6: 'What is Infinite Queue?',
|
||||
a6: 'When the queue runs out and Repeat is off, Psysonic silently appends similar / random tracks from your library so playback never stops. Auto-added tracks appear below a "— Added automatically —" divider. Toggle it with the infinity icon in the queue header; restrict auto-additions to a genre in Settings → Queue.',
|
||||
q7: 'Multi-select and Shift-click range selection?',
|
||||
a7: 'Activate "Select" on Albums / New Releases / Random Albums / Playlists. Click an item to toggle it, then hold Shift and click another item to select everything between them in the visible order. Shift-clicks extend from the most recently clicked anchor. The toolbar above the grid offers bulk actions (queue, download, delete, etc.).',
|
||||
q8: 'Keyboard shortcuts and global hotkeys?',
|
||||
a8: 'Default in-app keys: Space = Play / Pause, Esc = close fullscreen / modals, F1 = shortcuts cheat-sheet. Settings → Input lets you rebind every in-app action (also as chords like Ctrl+Shift+P) and set system-wide global shortcuts that work even when Psysonic is in the background or minimized. Media keys (Play/Pause, Next, Previous) work on all platforms.',
|
||||
// ── Section 3: Audio Tools ─────────────────────────────────────────────
|
||||
s3: 'Audio Tools',
|
||||
q9: 'Replay Gain modes?',
|
||||
a9: 'Settings → Audio → Replay Gain. Track mode normalises every song to a target level. Album mode preserves the loudness curve within an album. Auto mode picks Track or Album based on whether the queue is from a single album. Tracks without Replay Gain tags fall back to a configurable preamp.',
|
||||
q10: 'What is Smart Loudness Normalization (LUFS)?',
|
||||
a10: 'A modern alternative to Replay Gain in Settings → Audio. Psysonic analyses each track to LUFS / EBU R128 and stores the result, so volume is consistent across your whole library — including tracks without Replay Gain tags. Cold-cache analysis runs in the background and uses 35–40 % CPU for ~1 minute, then drops to 0. Set your target loudness (default −10 LUFS) once.',
|
||||
q11: 'EQ and AutoEQ?',
|
||||
a11: 'A 10-band parametric EQ lives in Settings → Audio → Equalizer with manual bands and presets. AutoEQ next to it pulls a measured correction profile for your headphone model from the AutoEQ database and applies it to the bands automatically — pick your headphones and the EQ snaps to the correct curve.',
|
||||
q12: 'How do I switch the audio output device?',
|
||||
a12: 'Settings → Audio → Output Device. Psysonic lists every available output and switches instantly when you pick one. The refresh button rescans devices that were plugged in after launch. Linux ALSA names like "sysdefault" are auto-cleaned for readability.',
|
||||
q13: 'What is Hot Cache?',
|
||||
a13: 'Hot Cache preloads the current track plus the next several into RAM and onto disk so playback starts with no buffering — especially useful on slow / remote servers. Eviction kicks in when the size limit is reached. Configure size and the debounce delay (so quick skips do not over-fetch) in Settings → Audio.',
|
||||
// ── Section 4: Library & Discovery ─────────────────────────────────────
|
||||
s4: 'Library & Discovery',
|
||||
q14: 'How do ratings and Skip-to-1★ work?',
|
||||
a14: 'Psysonic supports 1–5 star ratings via OpenSubsonic (Navidrome ≥ 0.53). Rate songs in track lists, in the right-click menu, or in the player bar below the artist name; albums on the album page; artists on the artist page. Skip-to-1★ (Settings → Library → Ratings) auto-assigns 1 star after a configurable number of consecutive skips. The same panel lets you set a minimum rating filter for Random Mix and other generated mixes.',
|
||||
q15: 'How do I browse — Folders, Genres, Tracks?',
|
||||
a15: 'Folder Browser (sidebar) walks your server\'s music directory in a Miller-column layout — click a folder to drill in, click a track or a folder\'s play icon to play / enqueue. Genres uses a tag-cloud view scaled by track count; click a genre to open it. Tracks is a flat library hub with column-sortable virtual list and live search.',
|
||||
q16: 'Search and Advanced Search?',
|
||||
a16: 'The header search bar runs a fast live search across artists, albums and tracks as you type. Open Advanced Search (sidebar) for a richer view: filter by year, genre, rating, format, channels, sample rate, BPM, mood, and combine criteria. Right-click any result for the same context menu used elsewhere in the app.',
|
||||
q17: 'What are the Mixes (Random / Genre / Super Genre / Lucky)?',
|
||||
a17: 'Random Mix builds a playlist of random tracks from your library; the Keyword Filter excludes audiobooks, comedy, etc. by genre / title / album substrings. Super Genre Mix groups your library into broad styles (Rock, Metal, Electronic, Jazz, Classical…) and builds a focused mix from one. Lucky Mix uses your listening history, ratings and AudioMuse-AI similar tracks to assemble an instant playlist with one click.',
|
||||
q18: 'Statistics page?',
|
||||
a18: 'Statistics (sidebar) shows top artists, top albums, top tracks, genre breakdown, listening time over time, and per-library scope when you have more than one music folder configured. Several views are exportable as a sharable card image.',
|
||||
q19: 'How do I download an album as a ZIP?',
|
||||
a19: 'Album page → "Download (ZIP)". The server compresses the album first — for large or lossless albums (FLAC / WAV) the progress bar appears only after zipping completes and the transfer starts. This is normal.',
|
||||
// ── Section 5: Lyrics ──────────────────────────────────────────────────
|
||||
s5: 'Lyrics',
|
||||
q20: 'Where do lyrics come from?',
|
||||
a20: 'Three sources, configurable in Settings → Lyrics: your Navidrome server (embedded / OpenSubsonic lyrics), LRCLIB (community-contributed synced lyrics), and NetEase Cloud Music (large Asian + international catalog). Each source can be enabled / disabled and re-ordered by drag.',
|
||||
q21: 'How do I view lyrics during playback?',
|
||||
a21: 'Click the microphone icon in the player bar to open the Lyrics tab inside the queue panel. Synced lyrics auto-scroll and support click-to-seek; plain-text lyrics scroll as a static block. Toggle the Fullscreen Player from the player-bar artwork for an immersive lyrics view with mesh-blob background.',
|
||||
// ── Section 6: Sharing & Social ────────────────────────────────────────
|
||||
s6: 'Sharing & Social',
|
||||
q22: 'What are Magic Strings?',
|
||||
a22: 'Magic Strings are short copy-paste tokens that share things between Psysonic users without any third-party server. Server-Invite strings let a friend onboard onto your Navidrome with one paste; Album / Artist / Queue Magic Strings open the same album / artist / queue on the recipient\'s installed Psysonic. Generate them from the share menu, paste them into the search bar to consume.',
|
||||
q23: 'What is Orbit?',
|
||||
a23: 'Orbit is synchronized listen-together: a host plays a track, every guest hears it in sync, and guests can suggest songs the host can accept into the queue. Start a session from the header Orbit button, share the invite link, and others can join from any Psysonic install. The host owns playback (skip, seek, queue) — guests get a real-time view and a suggestion box. Sessions are ephemeral and end when the host closes them.',
|
||||
q24: 'What is the Now Playing dropdown?',
|
||||
a24: 'The broadcast icon in the top-right header shows what other users on your Navidrome server are currently listening to, refreshed every 10 seconds. Your own entry disappears the moment you pause. It is per-server, so users on a different active server are not shown.',
|
||||
// ── Section 7: Personalization ─────────────────────────────────────────
|
||||
s7: 'Personalization',
|
||||
q25: 'Themes and the Theme Scheduler?',
|
||||
a25: 'Settings → Appearance → Theme picks from 60+ themes across 8 groups (Psysonic, Mediaplayer, Operating Systems, Games, Movies, Series, Social Media, Open Source Classics — Catppuccin / Nord / Gruvbox / Nightfox / Dracula). Auto-Switch Theme lets you set a day theme + night theme with start times so Psysonic flips automatically.',
|
||||
q26: 'Can I customize the Sidebar, Home and Artist pages?',
|
||||
a26: 'Yes — Settings → Personalisation. The sidebar customizer lets you drag nav items into the order you want and hide ones you do not use. The Home customizer toggles each Mainstage rail (Hero, Recent, Discover, Recently Played, Starred…). The Artist page customizer reorders the sections (Top Songs, Albums, Singles, Compilations, Similar Artists, etc.) and lets you hide ones you never look at.',
|
||||
q27: 'What is the Mini Player?',
|
||||
a27: 'A small floating window with cover art, transport controls and a compact queue. Open it from the player-bar mini-player icon or with its keyboard shortcut. The window remembers its position and size between sessions. On Windows the mini-webview is pre-created at startup so opening is instant; Linux / macOS opt in via Settings → Appearance → Preload mini player.',
|
||||
q28: 'What is the Floating Player Bar?',
|
||||
a28: 'An optional player-bar style (Settings → Appearance) that detaches from the bottom edge with a themed background, accent border, rounded album art and a centered volume section. Useful on tall monitors or compact themes.',
|
||||
q29: 'Track Preview on hover?',
|
||||
a29: 'Hover over a track row, click the small preview button on the cover, or trigger preview from the right-click menu — Psysonic streams the first ~15 s through the same Rust audio engine so loudness normalisation applies. Useful for skimming an album you have not heard before.',
|
||||
q30: 'Sleep timer?',
|
||||
a30: 'Click the moon icon in the player bar to open the sleep timer. Pick a duration (or "end of current track") and Psysonic fades out and pauses at the end. The button shows a circular ring and an in-button countdown while the timer runs.',
|
||||
q31: 'UI scale, font, seekbar style?',
|
||||
a31: 'Settings → Appearance — Interface Scale (80–125 % without affecting system font size), Font (10 UI fonts including IBM Plex Mono, Fira Code, Geist, Golos Text…), Seekbar Style (Waveform analysed / pseudowave deterministic / Line & Dot / Bar / Thick Bar / Segmented / Neon Glow / Pulse Wave / Particle Trail / Liquid Fill / Retro Tape).',
|
||||
// ── Section 8: Power User ──────────────────────────────────────────────
|
||||
s8: 'Power User',
|
||||
q32: 'CLI player controls?',
|
||||
a32: 'The Psysonic binary doubles as a remote control. Examples: psysonic --player play / pause / next / prev, --player volume 75, --player seek 15, --player shuffle, --player repeat off|all|one, --player rating 1-5. Switch servers, audio devices, libraries; trigger Instant Mix; search artists / albums / tracks. Run psysonic --player --help for the full list. Shell completions for bash and zsh via psysonic completions.',
|
||||
q33: 'Smart Playlists (Navidrome)?',
|
||||
a33: 'Smart Playlists are Navidrome-side dynamic playlists defined by rules (genre = Rock AND year > 2020, etc.). The Playlists page in Psysonic lets you create, edit and delete them with a visual rule editor — Psysonic talks to the Navidrome native API for that. They behave like normal playlists in the rest of the app and update automatically as your library changes.',
|
||||
q34: 'Backup and restore settings?',
|
||||
a34: 'Settings → Storage → Backup & Restore exports server profiles, themes, keybindings and other settings to a single JSON file. Import the file on another machine or after a reinstall to restore everything at once. Server passwords are included — keep the file private.',
|
||||
q35: 'Where do I see all open-source licenses?',
|
||||
a35: 'Settings → System → Open Source Licenses. The full dependency list (cargo crates and npm packages) ships in the build with bundled license texts. Click an entry for the full text; the curated highlight block at the top calls out the user-recognisable libraries (Tauri, React, rodio, symphonia, etc.).',
|
||||
// ── Section 9: Offline & Sync ──────────────────────────────────────────
|
||||
s9: 'Offline & Sync',
|
||||
q36: 'Offline Mode — caching albums and playlists?',
|
||||
a36: 'Open any album or playlist and click the download icon in the header — Psysonic caches every track locally so it plays from disk with no network call. The Offline Library page (sidebar) lists everything cached, shows progress in flight, and lets you remove entries with the trash icon (which appears once a download completes).',
|
||||
q37: 'Offline storage limit?',
|
||||
a37: 'Settings → Library → Offline lets you set a maximum cache size. When the limit is reached, the album-page download button shows a warning banner. Free space by removing albums or playlists from the Offline Library page.',
|
||||
q38: 'Device Sync — copy music to USB / SD?',
|
||||
a38: 'Device Sync (sidebar) copies albums, playlists or whole artists to an external drive for offline listening on other devices. Pick a target folder, choose sources from the browser tabs, click "Transfer to Device". Psysonic writes a manifest (psysonic-sync.json) so it knows which files are already there even if you reopen Device Sync on a different OS with a different filename template. Templates support {artist} / {album} / {title} / {track_number} / {disc_number} / {year} tokens with / for folder separators.',
|
||||
// ── Section 10: Integrations & Troubleshooting ─────────────────────────
|
||||
s10: 'Integrations & Troubleshooting',
|
||||
q39: 'Last.fm scrobbling?',
|
||||
a39: 'Settings → Integrations → Last.fm. Connect your account once and Psysonic scrobbles directly to Last.fm — no Navidrome configuration needed. A scrobble is sent after you have heard 50 % of a track. Now-playing pings are sent at the start.',
|
||||
q40: 'Discord Rich Presence?',
|
||||
a40: 'Settings → Integrations → Discord shows your current track on your Discord profile. Choose between the app icon, your server\'s cover art (via getAlbumInfo2 — needs a publicly reachable server), or Apple Music covers. Customize the display strings (details, state, tooltip) with token templates.',
|
||||
q41: 'Bandsintown tour dates?',
|
||||
a41: 'Opt in under Settings → Integrations → Now-Playing Info. The Now Playing tab on the Now Playing page then shows upcoming tour dates for the playing artist via the Bandsintown widget API. Off by default — no requests are made until you enable it.',
|
||||
q42: 'Internet Radio — playing live streams?',
|
||||
a42: 'Internet Radio (sidebar) plays any live stream stored on your Navidrome server (add stations via the Navidrome admin UI). Playback runs through the browser HTML5 audio engine — most EQ / Replay Gain / Loudness settings do not apply to radio, but ICY metadata (current song name) does show up. Supports MP3, AAC, OGG Vorbis and most HLS streams; codec support depends on the platform.',
|
||||
q43: 'The connection test fails — what now?',
|
||||
a43: 'Double-check the URL including port (e.g. http://192.168.1.100:4533). On a local network http:// often works where https:// does not (no certificate). Make sure no firewall blocks the port and that the username and password are correct. If your server is behind a reverse proxy, try the direct URL first to isolate the cause.',
|
||||
q44: 'Cover art and artist images load slowly.',
|
||||
a44: 'Images are fetched from your server on first view and then cached locally for 30 days. If your server\'s storage is slow, the first visit to a page can take a moment; subsequent visits are instant. The Hot Cache also helps for tracks but image cache is independent.',
|
||||
q45: 'Linux issues — black screen or no audio?',
|
||||
a45: 'Black screen is usually a GPU / EGL driver issue in WebKitGTK — launch with GDK_BACKEND=x11 WEBKIT_DISABLE_COMPOSITING_MODE=1 WEBKIT_DISABLE_DMABUF_RENDERER=1 (the AUR / .deb / .rpm installers set these automatically). For audio, make sure PipeWire or PulseAudio is running. If audio drops out after sleep / wake, this is now handled automatically by the post-sleep recovery hook.',
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export const hero = {
|
||||
eyebrow: 'Featured Album',
|
||||
playAlbum: 'Play Album',
|
||||
enqueue: 'Enqueue',
|
||||
enqueueTooltip: 'Add entire album to queue',
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export const home = {
|
||||
hero: 'Featured',
|
||||
starred: 'Personal Favorites',
|
||||
recent: 'Recently Added',
|
||||
mostPlayed: 'Most Played',
|
||||
recentlyPlayed: 'Recently Played',
|
||||
losslessAlbums: 'Lossless Albums',
|
||||
discover: 'Discover',
|
||||
discoverSongs: 'Discover Songs',
|
||||
loadMore: 'Load More',
|
||||
discoverMore: 'Discover More',
|
||||
discoverArtists: 'Discover Artists',
|
||||
discoverArtistsMore: 'All Artists',
|
||||
becauseYouLike: 'Because you listened…',
|
||||
becauseYouLikeFor: 'Because you listened to {{artist}}',
|
||||
similarTo: 'Similar to {{artist}}',
|
||||
becauseYouLikeTracks_one: '{{count}} track',
|
||||
becauseYouLikeTracks_other: '{{count}} tracks'
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import { sidebar } from './sidebar';
|
||||
import { home } from './home';
|
||||
import { hero } from './hero';
|
||||
import { search } from './search';
|
||||
import { nowPlaying } from './nowPlaying';
|
||||
import { contextMenu } from './contextMenu';
|
||||
import { sharePaste } from './sharePaste';
|
||||
import { albumDetail } from './albumDetail';
|
||||
import { entityRating } from './entityRating';
|
||||
import { artistDetail } from './artistDetail';
|
||||
import { favorites } from './favorites';
|
||||
import { randomLanding } from './randomLanding';
|
||||
import { randomAlbums } from './randomAlbums';
|
||||
import { genres } from './genres';
|
||||
import { randomMix } from './randomMix';
|
||||
import { luckyMix } from './luckyMix';
|
||||
import { albums } from './albums';
|
||||
import { tracks } from './tracks';
|
||||
import { artists } from './artists';
|
||||
import { composers } from './composers';
|
||||
import { composerDetail } from './composerDetail';
|
||||
import { login } from './login';
|
||||
import { connection } from './connection';
|
||||
import { common } from './common';
|
||||
import { settings } from './settings';
|
||||
import { changelog } from './changelog';
|
||||
import { whatsNew } from './whatsNew';
|
||||
import { help } from './help';
|
||||
import { queue } from './queue';
|
||||
import { miniPlayer } from './miniPlayer';
|
||||
import { statistics } from './statistics';
|
||||
import { player } from './player';
|
||||
import { nowPlayingInfo } from './nowPlayingInfo';
|
||||
import { songInfo } from './songInfo';
|
||||
import { playlists } from './playlists';
|
||||
import { smartPlaylists } from './smartPlaylists';
|
||||
import { mostPlayed } from './mostPlayed';
|
||||
import { losslessAlbums } from './losslessAlbums';
|
||||
import { radio } from './radio';
|
||||
import { folderBrowser } from './folderBrowser';
|
||||
import { deviceSync } from './deviceSync';
|
||||
import { orbit } from './orbit';
|
||||
import { tray } from './tray';
|
||||
import { licenses } from './licenses';
|
||||
|
||||
export const enTranslation = {
|
||||
sidebar,
|
||||
home,
|
||||
hero,
|
||||
search,
|
||||
nowPlaying,
|
||||
contextMenu,
|
||||
sharePaste,
|
||||
albumDetail,
|
||||
entityRating,
|
||||
artistDetail,
|
||||
favorites,
|
||||
randomLanding,
|
||||
randomAlbums,
|
||||
genres,
|
||||
randomMix,
|
||||
luckyMix,
|
||||
albums,
|
||||
tracks,
|
||||
artists,
|
||||
composers,
|
||||
composerDetail,
|
||||
login,
|
||||
connection,
|
||||
common,
|
||||
settings,
|
||||
changelog,
|
||||
whatsNew,
|
||||
help,
|
||||
queue,
|
||||
miniPlayer,
|
||||
statistics,
|
||||
player,
|
||||
nowPlayingInfo,
|
||||
songInfo,
|
||||
playlists,
|
||||
smartPlaylists,
|
||||
mostPlayed,
|
||||
losslessAlbums,
|
||||
radio,
|
||||
folderBrowser,
|
||||
deviceSync,
|
||||
orbit,
|
||||
tray,
|
||||
licenses,
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export const licenses = {
|
||||
title: 'Open Source Licenses',
|
||||
intro: 'Psysonic is built on open-source software. The list below shows every dependency that ships in the app, with its version, license, and full license text.',
|
||||
highlights: 'Key dependencies',
|
||||
searchPlaceholder: 'Search by name, version or license…',
|
||||
noResults: 'No matches.',
|
||||
loading: 'Loading licenses…',
|
||||
loadError: 'Could not load license data.',
|
||||
noLicenseText: 'No license text bundled for this dependency.',
|
||||
viewSource: 'View source',
|
||||
totalLine: '{{total}} dependencies — {{cargo}} cargo, {{npm}} npm',
|
||||
generatedAt: 'Last generated {{date}}',
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
export const login = {
|
||||
subtitle: 'Your Navidrome Desktop Player',
|
||||
serverName: 'Server Name (optional)',
|
||||
serverNamePlaceholder: 'My Navidrome',
|
||||
serverUrl: 'Server URL',
|
||||
serverUrlPlaceholder: '192.168.1.100:4533 or https://music.example.com',
|
||||
username: 'Username',
|
||||
usernamePlaceholder: 'admin',
|
||||
password: 'Password',
|
||||
showPassword: 'Show password',
|
||||
hidePassword: 'Hide password',
|
||||
connect: 'Connect',
|
||||
connecting: 'Connecting…',
|
||||
connected: 'Connected!',
|
||||
error: 'Connection failed – please check your details.',
|
||||
urlRequired: 'Please enter a server URL.',
|
||||
savedServers: 'Saved Servers',
|
||||
addNew: 'Or add a new server',
|
||||
orMagicString: 'Or magic string',
|
||||
magicStringPlaceholder: 'Paste a share string (psysonic1-…)',
|
||||
magicStringInvalid: 'Invalid or unreadable magic string.',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
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.',
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export const luckyMix = {
|
||||
done: 'Lucky Mix ready: {{count}} tracks',
|
||||
failed: 'Could not build Lucky Mix. Try again.',
|
||||
unavailable: 'Lucky Mix is unavailable for this server.',
|
||||
cancelTooltip: 'Cancel Lucky Mix build',
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const miniPlayer = {
|
||||
showQueue: 'Show queue',
|
||||
hideQueue: 'Hide queue',
|
||||
pinOnTop: 'Pin on top',
|
||||
pinOff: 'Unpin',
|
||||
openMainWindow: 'Open main window',
|
||||
close: 'Close',
|
||||
emptyQueue: 'Queue is empty',
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export const mostPlayed = {
|
||||
title: 'Most Played',
|
||||
topArtists: 'Top Artists',
|
||||
topAlbums: 'Top Albums',
|
||||
plays: '{{n}} plays',
|
||||
sortMost: 'Most plays first',
|
||||
sortLeast: 'Fewest plays first',
|
||||
loadMore: 'Load more albums',
|
||||
noData: 'No play data yet. Start listening!',
|
||||
noArtists: 'All artists filtered out.',
|
||||
filterCompilations: 'Hide compilation artists (Various Artists, Soundtracks, etc.)',
|
||||
filterCompilationsShort: 'Hide compilations',
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
export const nowPlaying = {
|
||||
tooltip: 'Who is listening?',
|
||||
title: 'Who is listening?',
|
||||
loading: 'Loading…',
|
||||
nobody: 'Nobody is currently listening.',
|
||||
minutesAgo: '{{n}}m ago',
|
||||
nothingPlaying: 'Nothing playing yet. Start a track!',
|
||||
aboutArtist: 'About the Artist',
|
||||
fromAlbum: 'From this Album',
|
||||
viewAlbum: 'View Album',
|
||||
goToArtist: 'Go to Artist',
|
||||
readMore: 'Read more',
|
||||
showLess: 'Show less',
|
||||
genreInfo: 'Genre',
|
||||
trackInfo: 'Track Info',
|
||||
topSongs: 'Most played by this artist',
|
||||
topSongsCredit: 'Top tracks from {{name}}',
|
||||
trackPosition: 'Track {{pos}}',
|
||||
playsCount_one: '{{count}} play',
|
||||
playsCount_other: '{{count}} plays',
|
||||
releasedYearsAgo_one: '{{count}} year ago',
|
||||
releasedYearsAgo_other: '{{count}} years ago',
|
||||
discography: 'Discography',
|
||||
lastfmStats: 'Last.fm stats',
|
||||
thisTrack: 'This track',
|
||||
thisArtist: 'This artist',
|
||||
listeners: 'listeners',
|
||||
scrobbles: 'scrobbles',
|
||||
yourScrobbles: 'by you',
|
||||
listenersN: '{{n}} listeners',
|
||||
scrobblesN: '{{n}} scrobbles',
|
||||
playsByYouN: 'played {{n}}× by you',
|
||||
openTrackOnLastfm: 'Track on Last.fm',
|
||||
openArtistOnLastfm: 'Artist on Last.fm',
|
||||
rgTrackTooltip: 'ReplayGain (track)',
|
||||
rgAlbumTooltip: 'ReplayGain (album)',
|
||||
rgAutoTooltip: 'ReplayGain (auto)',
|
||||
showMoreTracks: 'Show {{count}} more',
|
||||
showLessTracks: 'Show less',
|
||||
hideCard: 'Hide card',
|
||||
layoutMenu: 'Layout',
|
||||
visibleCards: 'Visible cards',
|
||||
hiddenCards: 'Hidden cards',
|
||||
noHiddenCards: 'No hidden cards',
|
||||
resetLayout: 'Reset layout',
|
||||
emptyColumn: 'Drop cards here',
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
export const nowPlayingInfo = {
|
||||
tab: 'Info',
|
||||
empty: 'Play something to see info',
|
||||
artist: 'Artist',
|
||||
songInfo: 'Song info',
|
||||
onTour: 'On tour',
|
||||
noTourEvents: 'No upcoming shows',
|
||||
tourLoading: 'Loading…',
|
||||
poweredByBandsintown: 'Tour data via Bandsintown',
|
||||
bioReadMore: 'Read more',
|
||||
bioReadLess: 'Show less',
|
||||
showMoreTours_one: 'Show {{count}} more',
|
||||
showMoreTours_other: 'Show {{count}} more',
|
||||
showLessTours: 'Show less',
|
||||
enableBandsintownPrompt: 'See upcoming tour dates?',
|
||||
enableBandsintownPromptDesc: 'Optional. Loads concerts for the current artist via the public Bandsintown API.',
|
||||
enableBandsintownPrivacy: 'When enabled, the name of the currently playing artist is sent to the Bandsintown API to fetch tour dates. No account or personal data leaves your device.',
|
||||
enableBandsintownAction: 'Enable',
|
||||
role: {
|
||||
artist: 'Artist',
|
||||
albumArtist: 'Album artist',
|
||||
composer: 'Composer',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,200 @@
|
||||
export const orbit = {
|
||||
triggerLabel: 'Orbit',
|
||||
triggerTooltip: 'Start or join a shared listening session',
|
||||
launchCreate: 'Create a session',
|
||||
launchJoin: 'Join a session',
|
||||
launchHelp: 'How does this work?',
|
||||
launchHelpSoon: 'Coming soon',
|
||||
joinModalTitle: 'Join an Orbit session',
|
||||
joinModalSub: 'Paste the invite link your host sent you.',
|
||||
joinModalLinkLabel: 'Invite link',
|
||||
joinModalLinkPlaceholder: 'psysonic2-…',
|
||||
joinModalLinkHelper: 'Works with any valid Orbit link. Must point to the server you\'re currently signed into.',
|
||||
joinModalPasteTooltip: 'Paste from clipboard',
|
||||
joinModalSubmit: 'Join',
|
||||
joinModalBusy: 'Joining…',
|
||||
joinErrEmpty: 'Please paste an invite link.',
|
||||
joinErrInvalid: 'That doesn\'t look like an Orbit invite link.',
|
||||
closeAria: 'Close',
|
||||
heroTitlePrefix: 'Listen together with',
|
||||
heroTitleBrand: 'Orbit',
|
||||
heroSub: 'Start a session — other users on {{server}} will listen along and can suggest tracks.',
|
||||
fallbackServer: 'this server',
|
||||
tipLan: "You're currently connected via a home-network address. Guests outside your network can't join — switch to a public server address in settings before you start.",
|
||||
tipRemote: 'For guests outside your home network to join, your server address has to be publicly reachable. If your server is internal only, switch before you start.',
|
||||
labelName: 'Session name',
|
||||
namePlaceholder: 'Velvet Orbit',
|
||||
reshuffleTooltip: 'New suggestion',
|
||||
reshuffleAria: 'Suggest a new name',
|
||||
helperName: 'How the session shows up to your guests — keep it or type your own.',
|
||||
labelMax: 'Max guests',
|
||||
helperMax: "You don't count — this only caps incoming guests.",
|
||||
labelLink: 'Invite link',
|
||||
tooltipCopied: 'Copied',
|
||||
tooltipCopy: 'Copy',
|
||||
ariaCopyLink: 'Copy invite link',
|
||||
helperLink: 'Send this link to your guests. They can paste it anywhere in Psysonic with Ctrl+V.',
|
||||
labelClearQueue: 'Clear my queue first',
|
||||
helperClearQueue: 'Start the session with a fresh, empty queue. Off: the tracks you already have queued stay and get shared with guests.',
|
||||
btnCancel: 'Cancel',
|
||||
btnStarting: 'Starting…',
|
||||
btnStart: 'Start Orbit',
|
||||
btnCopyAndStart: 'Copy link & start',
|
||||
errNameRequired: 'Please give your session a name.',
|
||||
errStartFailed: "Couldn't start.",
|
||||
hostLabel: 'Host: {{name}}',
|
||||
participantsTooltip: 'Participants',
|
||||
settingsTooltip: 'Session settings',
|
||||
shareTooltip: 'Share invite link',
|
||||
shuffleLabel: 'Queue reshuffles in',
|
||||
catchUpLabel: 'catch up',
|
||||
catchUpTooltip: "Jump to the host's current position",
|
||||
hostAway: 'Host offline',
|
||||
hostOnline: 'Host online',
|
||||
endTooltip: 'End session',
|
||||
leaveTooltip: 'Leave session',
|
||||
helpTooltip: 'How Orbit works',
|
||||
diag: {
|
||||
openTooltip: 'Diagnostics — copyable event log',
|
||||
title: 'Orbit diagnostics',
|
||||
role: 'Role',
|
||||
hostTrack: 'Host track id',
|
||||
hostPos: 'Host position',
|
||||
guestTrack: 'My track id',
|
||||
guestPos: 'My position',
|
||||
drift: 'Drift',
|
||||
stateAge: 'State age',
|
||||
eventLog: 'Event log ({{count}})',
|
||||
copyLabel: 'Copy',
|
||||
copyTooltip: 'Copy log to clipboard',
|
||||
clearLabel: 'Clear',
|
||||
clearTooltip: 'Wipe the buffer',
|
||||
empty: 'No events yet — events appear as Orbit syncs.',
|
||||
hint: 'Open this before reproducing a problem, then click Copy and paste into the bug report.',
|
||||
copied: 'Copied {{count}} event lines',
|
||||
copyFailed: 'Could not copy to clipboard',
|
||||
cleared: 'Buffer cleared',
|
||||
},
|
||||
helpTitle: 'How Orbit works',
|
||||
helpIntro: 'Orbit turns Psysonic into a shared listening room. A host picks the music; guests listen in sync and can suggest tracks.',
|
||||
helpHostOnly: '(host)',
|
||||
helpSec1Title: 'What is Orbit?',
|
||||
helpSec1Body: "A \"listen together\" mode — the host drives playback, guests tune in. Everything runs through playlists on your own Navidrome server; no external infrastructure.",
|
||||
helpSec2Title: 'Host and guests',
|
||||
helpSec2Body: 'Host controls playback (play / pause / skip / seek) and decides when the session ends. Guests follow the host\'s playback, can suggest tracks, and leave or re-join any time. Only the host can kick or permanently ban a participant.',
|
||||
helpSec2WarnHead: 'Important: separate accounts.',
|
||||
helpSec2WarnBody: "Every participant needs their own Navidrome account. If host and guest sign in with the same user their submissions collide and the host never sees the guest's suggestions.",
|
||||
helpSec3Title: 'Starting and inviting',
|
||||
helpSec3Body: 'Click the "Orbit" button → Create a session → the start modal shows a ready-to-copy invite link and lets you optionally clear your current queue. Share that link however you like. While a session is running, the share button in the session bar at the top copies the link again at any time.',
|
||||
helpSec4Title: 'Joining',
|
||||
helpSec4Body: 'Paste the invite link anywhere in Psysonic with Ctrl+V / Cmd+V — the join prompt pops up automatically. Alternatively: "Orbit" → Join a session → paste into the field. If the link points to a server you have an account on, Psysonic switches for you. When you have more than one account on that server, a small picker asks which to use.',
|
||||
helpSec5Title: 'Suggesting tracks',
|
||||
helpSec5Body: 'In any song list: double-click a row, or right-click → "Add to Orbit session". A single click shows a hint instead of dumping the whole album into the shared queue — that\'s intentional. Explicit bulk actions like "Play All" or "Play Album" ask for confirmation first and then append (never replace).',
|
||||
helpSec6Title: 'The shared queue',
|
||||
helpSec6Body: "The queue shows the host's upcoming tracks — visible to everyone. Incoming bulk additions are always appended, so guest suggestions aren't lost. Auto-shuffle reorders the queue periodically (configurable: 1 / 5 / 10 / 15 / 30 min). If your playback drifts away from the host, the \"Catch up\" button in the session bar jumps you back to the host's live position.",
|
||||
helpSec7Title: 'Approvals',
|
||||
helpSec7Body: 'By default, guest suggestions need manual approval — they appear in an "Approvals" strip at the top of the queue panel with accept / decline buttons. Auto-approve can be turned on in the session settings so everything lands straight away.',
|
||||
helpSec8Title: 'Participants and settings',
|
||||
helpSec8Body: 'Open the settings icon in the session bar for shuffle cadence, auto-approve, and the "Shuffle now" shortcut. Click the participants count to see who\'s connected — kick (can re-join via the link) or ban (locked out for the session). Guests see the participant list too, but read-only.',
|
||||
helpSec9Title: 'Ending the session',
|
||||
helpSec9Body: "Host X → confirm dialog → session closes for everyone and the server playlists are cleaned up automatically. Guest X → the guest leaves, the session keeps running. If the host goes quiet for 5 minutes the guest auto-leaves with a notice; short reconnects within that window are invisible.",
|
||||
participantsInviteLabel: 'Invite link',
|
||||
participantsCountLabel: '{{count}} in session',
|
||||
participantsHost: 'host',
|
||||
participantsEmpty: 'No guests yet',
|
||||
participantsKickTooltip: 'Remove from session',
|
||||
participantsKickAria: 'Remove {{user}}',
|
||||
participantsRemoveTooltip: 'Remove from session',
|
||||
participantsRemoveAria: 'Remove {{user}} from this session',
|
||||
participantsBanTooltip: 'Ban permanently',
|
||||
participantsBanAria: 'Permanently ban {{user}}',
|
||||
participantsMuteTooltip: 'Mute suggestions',
|
||||
participantsUnmuteTooltip: 'Allow suggestions',
|
||||
participantsMuteAria: 'Mute suggestions from {{user}}',
|
||||
participantsUnmuteAria: 'Allow suggestions from {{user}}',
|
||||
confirmRemoveTitle: 'Remove from session?',
|
||||
confirmRemoveBody: '{{user}} will be dropped from the session, but can re-join via your invite link.',
|
||||
confirmRemoveConfirm: 'Remove',
|
||||
confirmBanTitle: 'Permanently ban?',
|
||||
confirmBanBody: '{{user}} will be removed and blocked from re-joining this session. This can\'t be undone for the lifetime of the session.',
|
||||
confirmBanConfirm: 'Ban',
|
||||
confirmCancel: 'Cancel',
|
||||
confirmJoinTitle: 'Join Orbit session?',
|
||||
confirmJoinBody: '{{host}} invited you to "{{name}}". Join the session?',
|
||||
confirmJoinConfirm: 'Join',
|
||||
confirmLeaveTitle: 'Leave session?',
|
||||
confirmLeaveBody: 'Leave "{{name}}"? You can re-join via {{host}}\'s invite link any time.',
|
||||
confirmLeaveConfirm: 'Leave',
|
||||
confirmEndTitle: 'End session for everyone?',
|
||||
confirmEndBody: '"{{name}}" will close for all participants. The session\'s playlists are cleaned up automatically.',
|
||||
confirmEndConfirm: 'End session',
|
||||
invalidLinkTitle: 'Invite link is no longer valid',
|
||||
invalidLinkBody: 'This Orbit session doesn\'t exist any more or has already ended. Ask the host for a fresh invite link.',
|
||||
settingsTitle: 'Session settings',
|
||||
settingAutoApprove: 'Auto-approve suggestions',
|
||||
settingAutoApproveHint: "Guest suggestions land in your queue instantly. Off: they stay in the session list for you to review later.",
|
||||
settingAutoShuffle: 'Automatic reshuffle',
|
||||
settingAutoShuffleHint: "Periodic Fisher–Yates shuffle of the upcoming queue. Off: order only changes when you rearrange it.",
|
||||
settingShuffleInterval: 'Reshuffle every',
|
||||
settingShuffleIntervalHint: 'How often the upcoming queue gets reshuffled while the session runs.',
|
||||
suggestBlockedMuted: 'The host muted you for this session — suggestions are off.',
|
||||
settingShuffleIntervalValue_one: '{{count}} min',
|
||||
settingShuffleIntervalValue_other: '{{count}} min',
|
||||
settingShuffleNow: 'Shuffle now',
|
||||
toastSuggested: '{{user}} suggested "{{title}}"',
|
||||
toastSuggestedMany: '{{count}} new suggestions in the queue',
|
||||
toastShuffled: 'Queue shuffled',
|
||||
toastJoined: 'Joined session',
|
||||
toastLoginFirst: 'Log in before joining a session',
|
||||
toastSwitchServer: 'Switch to {{url}} first, then paste again',
|
||||
toastNoAccountForServer: "You don't have access to {{url}}. Ask the host for an invite.",
|
||||
toastSwitchFailed: "Couldn't switch to {{url}}",
|
||||
accountPickerTitle: 'Which account?',
|
||||
accountPickerSub: 'You have more than one account for {{url}}. Pick the one to join the session as.',
|
||||
toastJoinFail: "Couldn't join session",
|
||||
joinErrNotFound: 'Session not found',
|
||||
joinErrEnded: 'Session has ended',
|
||||
joinErrFull: 'Session is full',
|
||||
joinErrKicked: "You can't rejoin this session",
|
||||
joinErrNoUser: 'No active server',
|
||||
joinErrServerError: "Couldn't join",
|
||||
ctxAddToSession: 'Add to Orbit session',
|
||||
ctxSuggestedToast: 'Suggested to the session',
|
||||
ctxSuggestFailed: "Couldn't suggest — not joined",
|
||||
ctxAddToSessionHost: 'Add to Orbit session',
|
||||
ctxAddedHostToast: 'Added to the session',
|
||||
ctxAddHostFailed: "Couldn't add to session",
|
||||
bulkConfirmTitle: 'Add all of this to the Orbit queue?',
|
||||
bulkConfirmBody: "This would drop {{count}} tracks into the shared queue in one go. That's a lot for your guests to notice. Go ahead?",
|
||||
bulkConfirmYes: 'Add them all',
|
||||
bulkConfirmNo: 'Cancel',
|
||||
guestLive: 'Live',
|
||||
guestPlaying: 'Playing now',
|
||||
guestPaused: 'Paused',
|
||||
guestLoading: 'Loading…',
|
||||
guestSuggestions: 'Suggestions',
|
||||
guestUpNext: 'Up next',
|
||||
guestUpNextEmpty: 'Nothing queued. Open a track\'s context menu and pick "Add to Orbit session" to suggest one.',
|
||||
guestPendingTitle: 'Waiting for host',
|
||||
guestPendingHint: 'Suggested — will appear in the queue when the host picks it up.',
|
||||
approvalTitle: 'Pending approvals',
|
||||
approvalFrom: 'Suggested by {{user}}',
|
||||
approvalAccept: 'Accept',
|
||||
approvalDecline: 'Decline',
|
||||
guestUpNextMore: '+ {{count}} more in the host\'s queue',
|
||||
guestSubmitter: 'by {{user}}',
|
||||
queueAddedByHost: 'Added by host',
|
||||
queueAddedByYou: 'Added by you',
|
||||
queueAddedByUser: 'Added by {{user}}',
|
||||
guestEmpty: 'No suggestions yet. Open a track\'s context menu and pick "Add to Orbit session".',
|
||||
guestFooter: "The host controls playback — you can't change the list.",
|
||||
exitKickedTitle: 'You were banned from the session',
|
||||
exitRemovedTitle: 'You were removed from the session',
|
||||
exitEndedTitle: 'The host ended the session',
|
||||
exitHostTimeoutTitle: 'Host went silent',
|
||||
exitHostTimeoutBody: "{{host}} hasn't sent an update for a while, so \"{{name}}\" was closed on your end. You can re-join any time with the invite link.",
|
||||
exitKickedBody: '{{host}} banned you from "{{name}}". You can\'t re-join.',
|
||||
exitRemovedBody: '{{host}} removed you from "{{name}}". You can re-join any time via the invite link.',
|
||||
exitEndedBody: '"{{name}}" has ended. Hope you had fun.',
|
||||
exitOk: 'OK',
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
export const player = {
|
||||
regionLabel: 'Music Player',
|
||||
openFullscreen: 'Open Fullscreen Player',
|
||||
fullscreen: 'Fullscreen Player',
|
||||
closeFullscreen: 'Close Fullscreen',
|
||||
closeTooltip: 'Close (Esc)',
|
||||
noTitle: 'No Title',
|
||||
stop: 'Stop',
|
||||
prev: 'Previous Track',
|
||||
play: 'Play',
|
||||
pause: 'Pause',
|
||||
previewActive: 'Preview playing',
|
||||
previewLabel: 'Preview',
|
||||
delayModalTitle: 'Timer',
|
||||
delayPauseSection: 'Pause after',
|
||||
delayStartSection: 'Start after',
|
||||
delayPreviewPause: 'Pauses at',
|
||||
delayPreviewStart: 'Starts at',
|
||||
delaySchedulePause: 'Schedule pause',
|
||||
delayScheduleStart: 'Schedule start',
|
||||
delayCancelPause: 'Cancel pause timer',
|
||||
delayCancelStart: 'Cancel start timer',
|
||||
delayInactivePause: 'Available only while something is playing.',
|
||||
delayInactiveStart: 'Available when paused with a track or radio loaded.',
|
||||
delayCustomMinutes: 'Custom delay (minutes)',
|
||||
delayCustomPlaceholder: 'e.g. 2.5',
|
||||
closeDelayModal: 'Close',
|
||||
delayIn: 'in',
|
||||
delayFmtSec: '{{n}}s',
|
||||
delayFmtMin: '{{n}} min',
|
||||
delayFmtHr: '{{n}} h',
|
||||
delayCancel: 'Cancel',
|
||||
delayApply: 'Apply',
|
||||
next: 'Next Track',
|
||||
repeat: 'Repeat',
|
||||
repeatOff: 'Off',
|
||||
repeatAll: 'All',
|
||||
repeatOne: 'One',
|
||||
progress: 'Song Progress',
|
||||
volume: 'Volume',
|
||||
toggleQueue: 'Toggle Queue',
|
||||
collapseQueueResize: 'Collapse queue, resize',
|
||||
moreOptions: 'More options',
|
||||
equalizer: 'Equalizer',
|
||||
miniPlayer: 'Mini Player',
|
||||
lyrics: 'Lyrics',
|
||||
fsLyricsToggle: 'Lyrics in fullscreen',
|
||||
lyricsLoading: 'Loading lyrics…',
|
||||
lyricsNotFound: 'No lyrics found for this track',
|
||||
lyricsSourceServer: 'Source: Server',
|
||||
lyricsSourceLrclib: 'Source: LRCLIB',
|
||||
lyricsSourceNetease: 'Source: Netease',
|
||||
lyricsSourceLyricsplus: 'Source: YouLyPlus',
|
||||
showDuration: 'Show duration',
|
||||
showRemainingTime: 'Show remaining time',
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
export const playlists = {
|
||||
title: 'Playlists',
|
||||
newPlaylist: 'New Playlist',
|
||||
unnamed: 'Unnamed Playlist',
|
||||
createName: 'Playlist name…',
|
||||
create: 'Create',
|
||||
cancel: 'Cancel',
|
||||
empty: 'No playlists yet.',
|
||||
emptyPlaylist: 'This playlist is empty.',
|
||||
addFirstSong: 'Add your first song',
|
||||
notFound: 'Playlist not found.',
|
||||
songs: '{{n}} songs',
|
||||
playAll: 'Play All',
|
||||
shuffle: 'Shuffle',
|
||||
addToQueue: 'Add to Queue',
|
||||
back: 'Back to Playlists',
|
||||
deletePlaylist: 'Delete',
|
||||
confirmDelete: 'Click again to confirm',
|
||||
removeSong: 'Remove from playlist',
|
||||
addSongs: 'Add Songs',
|
||||
searchPlaceholder: 'Search your library…',
|
||||
noResults: 'No results.',
|
||||
suggestions: 'Suggested Songs',
|
||||
noSuggestions: 'No suggestions available.',
|
||||
titleBadge: 'Playlist',
|
||||
refreshSuggestions: 'New suggestions',
|
||||
addSong: 'Add to playlist',
|
||||
preview: 'Preview (30s)',
|
||||
previewStop: 'Stop preview',
|
||||
playNextSuggestion: 'Play next',
|
||||
suggestionsHint: 'Double-click a row to add it to the playlist',
|
||||
addSelected: 'Add selected',
|
||||
cacheOffline: 'Cache playlist offline',
|
||||
offlineCached: 'Playlist cached',
|
||||
removeOffline: 'Remove from offline cache',
|
||||
offlineDownloading: 'Caching… ({{done}}/{{total}} albums)',
|
||||
publicLabel: 'Public',
|
||||
privateLabel: 'Private',
|
||||
editMeta: 'Edit playlist',
|
||||
editNamePlaceholder: 'Playlist name…',
|
||||
editCommentPlaceholder: 'Add a description…',
|
||||
editPublic: 'Public playlist',
|
||||
editSave: 'Save',
|
||||
editCancel: 'Cancel',
|
||||
changeCover: 'Change cover image',
|
||||
changeCoverLabel: 'Change photo',
|
||||
removeCover: 'Remove photo',
|
||||
coverUpdated: 'Cover updated',
|
||||
metaSaved: 'Playlist updated',
|
||||
downloadZip: 'Download (ZIP)',
|
||||
// Toast notifications for multi-select
|
||||
addSuccess: '{{count}} songs added to {{playlist}}',
|
||||
addPartial: '{{added}} added, {{skipped}} skipped (duplicates)',
|
||||
addAllSkipped: 'All skipped ({{count}} duplicates)',
|
||||
addedAsDuplicates: '{{count}} songs added to {{playlist}} (as duplicates)',
|
||||
duplicateConfirmTitle: 'Already in playlist',
|
||||
duplicateConfirmMessage: 'All {{count}} songs are already in "{{playlist}}". Add them again as duplicates?',
|
||||
duplicateConfirmAction: 'Add anyway',
|
||||
addError: 'Error adding songs',
|
||||
createAndAddSuccess: 'Playlist "{{playlist}}" created with {{count}} songs',
|
||||
createError: 'Error creating playlist',
|
||||
deleteSuccess: '{{count}} playlists deleted',
|
||||
deleteFailed: 'Error deleting {{name}}',
|
||||
deleteSelected: 'Delete selected',
|
||||
deleteSelectedPartial: 'Only {{n}} of {{total}} selected playlists can be deleted (the others belong to someone else).',
|
||||
mergeSuccess: '{{count}} songs merged into {{playlist}}',
|
||||
mergeNoNewSongs: 'No new songs to add',
|
||||
mergeError: 'Error merging playlists',
|
||||
mergeInto: 'Merge into',
|
||||
selectionCount: '{{count}} selected',
|
||||
select: 'Select',
|
||||
startSelect: 'Enable selection',
|
||||
cancelSelect: 'Cancel',
|
||||
loadingAlbums: 'Resolving {{count}} albums…',
|
||||
loadingArtists: 'Resolving {{count}} artists…',
|
||||
myPlaylists: 'My Playlists',
|
||||
noOtherPlaylists: 'No other playlists available',
|
||||
addToPlaylistSuccess: '{{count}} songs added to {{playlist}}',
|
||||
addToPlaylistNoNew: 'No new songs to add to {{playlist}}',
|
||||
addToPlaylistError: 'Error adding to playlist',
|
||||
removeSuccess: 'Song removed from playlist',
|
||||
removeError: 'Error removing song from playlist',
|
||||
importCSV: 'Import CSV',
|
||||
importCSVTooltip: 'Import from Spotify CSV',
|
||||
csvImportReport: 'CSV Import Report',
|
||||
csvImportTotal: 'Total',
|
||||
csvImportAdded: 'Added',
|
||||
csvImportDuplicates: 'Duplicates',
|
||||
csvImportNotFound: 'Not Found',
|
||||
csvImportNetworkErrors: 'Network Errors',
|
||||
csvImportDuplicatesTitle: 'Duplicate Tracks (Already in Playlist):',
|
||||
csvImportNotFoundTitle: 'Tracks Not Found:',
|
||||
csvImportNetworkErrorsTitle: 'Network Errors (may retry import):',
|
||||
csvImportDownloadReport: 'Download Report',
|
||||
csvImportClose: 'Close',
|
||||
csvImportNoValidTracks: 'No valid tracks found in CSV file',
|
||||
csvImportFailed: 'Failed to import CSV file',
|
||||
csvImportToast: '{{added}} added, {{notFound}} not found, {{duplicates}} duplicates',
|
||||
csvImportDownloadSuccess: 'Report downloaded successfully',
|
||||
csvImportDownloadError: 'Failed to download report',
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
export const queue = {
|
||||
title: 'Queue',
|
||||
savePlaylist: 'Save Playlist',
|
||||
updatePlaylist: 'Update Playlist',
|
||||
filterPlaylists: 'Filter playlists…',
|
||||
playlistName: 'Playlist Name',
|
||||
cancel: 'Cancel',
|
||||
save: 'Save',
|
||||
loadPlaylist: 'Load Playlist',
|
||||
loading: 'Loading…',
|
||||
noPlaylists: 'No playlists found.',
|
||||
load: 'Replace queue & play',
|
||||
appendToQueue: 'Append to queue',
|
||||
delete: 'Delete',
|
||||
deleteConfirm: 'Delete playlist "{{name}}"?',
|
||||
clear: 'Clear',
|
||||
shuffle: 'Shuffle queue',
|
||||
gapless: 'Gapless',
|
||||
crossfade: 'Crossfade',
|
||||
infiniteQueue: 'Infinite Queue',
|
||||
autoAdded: '— Added automatically —',
|
||||
radioAdded: '— Radio —',
|
||||
hide: 'Hide',
|
||||
hideNowPlaying: 'Hide now playing info',
|
||||
showNowPlaying: 'Show now playing info',
|
||||
close: 'Close',
|
||||
nextTracks: 'Next Tracks',
|
||||
shareQueue: 'Copy queue share link',
|
||||
shareQueueEmpty: 'The queue is empty — nothing to share.',
|
||||
emptyQueue: 'The queue is empty.',
|
||||
trackSingular: 'track',
|
||||
trackPlural: 'tracks',
|
||||
showRemaining: 'Show remaining time',
|
||||
showTotal: 'Show total time',
|
||||
showEta: 'Show estimated end time',
|
||||
replayGain: 'ReplayGain',
|
||||
rgTrack: 'T {{db}} dB',
|
||||
rgAlbum: 'A {{db}} dB',
|
||||
rgPeak: 'Peak {{pk}}',
|
||||
sourceOffline: 'Playing from offline library',
|
||||
sourceHot: 'Playing from cache',
|
||||
sourceStream: 'Playing from network stream',
|
||||
clearCachedLoudnessWaveform: 'Clear cached loudness and waveform, then re-analyze this track',
|
||||
recalculatingLoudnessWaveform: 'Recalculating loudness and waveform for this track…',
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
export const radio = {
|
||||
title: 'Internet Radio',
|
||||
empty: 'No radio stations configured.',
|
||||
addStation: 'Add Station',
|
||||
editStation: 'Edit',
|
||||
deleteStation: 'Delete station',
|
||||
confirmDelete: 'Click again to confirm',
|
||||
stationName: 'Station name…',
|
||||
streamUrl: 'Stream URL…',
|
||||
homepageUrl: 'Homepage URL (optional)',
|
||||
save: 'Save',
|
||||
cancel: 'Cancel',
|
||||
live: 'LIVE',
|
||||
liveStream: 'Internet Radio',
|
||||
openHomepage: 'Open homepage',
|
||||
changeCoverLabel: 'Change cover',
|
||||
removeCover: 'Remove cover',
|
||||
browseDirectory: 'Search Directory',
|
||||
directoryPlaceholder: 'Search stations…',
|
||||
noResults: 'No stations found.',
|
||||
stationAdded: 'Station added',
|
||||
filterAll: 'All',
|
||||
filterFavorites: 'Favorites',
|
||||
sortManual: 'Manual',
|
||||
sortAZ: 'A → Z',
|
||||
sortZA: 'Z → A',
|
||||
sortNewest: 'Newest',
|
||||
favorite: 'Add to favorites',
|
||||
unfavorite: 'Remove from favorites',
|
||||
noFavorites: 'No favorite stations.',
|
||||
listenerCount_one: '{{count}} listener',
|
||||
listenerCount_other: '{{count}} listeners',
|
||||
recentlyPlayed: 'Recently Played',
|
||||
upNext: 'Up Next',
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
export const randomAlbums = {
|
||||
title: 'Random Albums',
|
||||
refresh: 'Refresh',
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const randomLanding = {
|
||||
title: 'Build a Mix',
|
||||
mixByTracks: 'Mix by Tracks',
|
||||
mixByTracksDesc: 'Random selection of tracks from your entire library',
|
||||
mixByAlbums: 'Mix by Albums',
|
||||
mixByAlbumsDesc: 'Random album picks for your next discovery',
|
||||
mixByLucky: 'Lucky Mix',
|
||||
mixByLuckyDesc: 'Smart instant mix from your top artists, albums, and ratings',
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
export const randomMix = {
|
||||
title: 'Random Mix',
|
||||
remix: 'Remix',
|
||||
remixTooltip: 'Load new random songs',
|
||||
remixGenre: 'Remix {{genre}}',
|
||||
remixTooltipGenre: 'Load new {{genre}} songs',
|
||||
playAll: 'Play All',
|
||||
trackTitle: 'Title',
|
||||
trackArtist: 'Artist',
|
||||
trackAlbum: 'Album',
|
||||
trackFavorite: 'Favorite',
|
||||
trackDuration: 'Duration',
|
||||
favoriteAdd: 'Add to Favorites',
|
||||
favoriteRemove: 'Remove from Favorites',
|
||||
play: 'Play',
|
||||
trackGenre: 'Genre',
|
||||
mixSettingsHeader: 'Mix Settings',
|
||||
exclusionsHeader: 'Exclusions',
|
||||
filterPanelInexactSizeNote: 'Mix size is a target — large requests may return fewer unique tracks if the server\'s random pool runs short.',
|
||||
mixSize: 'Playlist size',
|
||||
excludeAudiobooks: 'Exclude audiobooks & radio plays',
|
||||
excludeAudiobooksDesc: 'Matches keywords against genre, title, album, and artist — e.g. Hörbuch, Audiobook, Spoken Word, …',
|
||||
genreBlocked: 'Keyword blocked',
|
||||
genreAddedToBlacklist: 'Added to filter list',
|
||||
genreAlreadyBlocked: 'Already blocked',
|
||||
artistBlocked: 'Artist blocked',
|
||||
artistAddedToBlacklist: 'Artist added to filter list',
|
||||
artistClickHint: 'Click to block this artist',
|
||||
blacklistToggle: 'Keyword Filter',
|
||||
genreMixTitle: 'Genre Mix',
|
||||
genreMixDesc: 'Top 20 genres by song count — click to load a random mix',
|
||||
genreMixAll: 'All Songs',
|
||||
genreMixLoadMore: 'Load 10 more',
|
||||
genreMixNoGenres: 'No genres found on server.',
|
||||
shuffleGenres: 'Show different genres',
|
||||
filterPanelTitle: 'Filters',
|
||||
filterPanelDesc: 'Click a genre tag or artist name in the tracklist below to block it from future mixes.',
|
||||
genreClickHint: 'Click a genre tag to add it\nas a filter keyword.\nMatches genre, title, album & artist.',
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
export const search = {
|
||||
placeholder: 'Search for artist, album or song…',
|
||||
noResults: 'No results for "{{query}}"',
|
||||
artists: 'Artists',
|
||||
albums: 'Albums',
|
||||
songs: 'Songs',
|
||||
clearLabel: 'Clear search',
|
||||
addedToQueueToast: 'Added "{{title}}" to queue',
|
||||
title: 'Search',
|
||||
resultsFor: 'Results for "{{query}}"',
|
||||
album: 'Album',
|
||||
advanced: 'Advanced Search',
|
||||
advancedSearchTerm: 'Search term',
|
||||
advancedSearchPlaceholder: 'Title, album, artist…',
|
||||
advancedGenre: 'Genre',
|
||||
advancedAllGenres: 'All genres',
|
||||
advancedYear: 'Year',
|
||||
advancedYearFrom: 'from',
|
||||
advancedYearTo: 'to',
|
||||
advancedAll: 'All',
|
||||
advancedSearch: 'Search',
|
||||
advancedEmpty: 'Enter a search term or select a filter to begin.',
|
||||
advancedNoResults: 'No results found.',
|
||||
advancedGenreNote: 'Songs are randomly selected from this genre.',
|
||||
recentSearches: 'Recent Searches',
|
||||
browse: 'Browse',
|
||||
emptyHint: 'What do you want to hear?',
|
||||
genres: 'Genres',
|
||||
};
|
||||
@@ -0,0 +1,445 @@
|
||||
export const settings = {
|
||||
title: 'Settings',
|
||||
language: 'Language',
|
||||
languageEn: 'English',
|
||||
languageDe: 'Deutsch',
|
||||
languageEs: 'Español',
|
||||
languageFr: 'Français',
|
||||
languageNl: 'Nederlands',
|
||||
languageNb: 'Norsk',
|
||||
languageRu: 'Русский',
|
||||
languageZh: '中文',
|
||||
languageRo: 'Română',
|
||||
font: 'Font',
|
||||
fontHintOpenDyslexic: 'Dyslexia-friendly · no Chinese support',
|
||||
theme: 'Theme',
|
||||
appearance: 'Appearance',
|
||||
servers: 'Servers',
|
||||
serverName: 'Server Name',
|
||||
serverUrl: 'Server URL',
|
||||
serverUrlPlaceholder: '192.168.1.100:4533 or https://music.example.com',
|
||||
serverUsername: 'Username',
|
||||
serverPassword: 'Password',
|
||||
addServer: 'Add Server',
|
||||
addServerTitle: 'Add New Server',
|
||||
useServer: 'Use',
|
||||
deleteServer: 'Delete',
|
||||
noServers: 'No servers saved.',
|
||||
serverActive: 'Active',
|
||||
confirmDeleteServer: 'Delete server "{{name}}"?',
|
||||
serverConnecting: 'Connecting…',
|
||||
serverConnected: 'Connected!',
|
||||
serverFailed: 'Connection failed.',
|
||||
testBtn: 'Test Connection',
|
||||
testingBtn: 'Testing…',
|
||||
serverCompatible: 'Built for Navidrome. Other Subsonic-compatible servers (Gonic, Airsonic, …) may work with reduced functionality, since Psysonic uses many Navidrome-specific API endpoints.',
|
||||
userMgmtTitle: 'User Management',
|
||||
userMgmtDesc: 'Manage users on this server. Requires admin privileges.',
|
||||
userMgmtNoAdmin: 'You need admin privileges to manage users on this server.',
|
||||
userMgmtLoadError: 'Failed to load users.',
|
||||
userMgmtLoadFriendly: 'Server didn\'t answer — this is usually a one-off.',
|
||||
userMgmtRetry: 'Retry',
|
||||
userMgmtEmpty: 'No users found.',
|
||||
userMgmtYouBadge: 'You',
|
||||
userMgmtAdminBadge: 'Admin',
|
||||
userMgmtAddUser: 'Add User',
|
||||
userMgmtAddUserTitle: 'Add New User',
|
||||
userMgmtEditUserTitle: 'Edit User',
|
||||
userMgmtUsername: 'Username',
|
||||
userMgmtName: 'Display Name',
|
||||
userMgmtEmail: 'Email',
|
||||
userMgmtPassword: 'Password',
|
||||
userMgmtPasswordEditHint: 'Enter a new password to update it.',
|
||||
userMgmtRoleAdmin: 'Admin',
|
||||
userMgmtLibraries: 'Libraries',
|
||||
userMgmtLibrariesAdminHint: 'Admin users automatically have access to all libraries.',
|
||||
userMgmtLibrariesEmpty: 'No libraries available on this server.',
|
||||
userMgmtLibrariesValidation: 'Select at least one library.',
|
||||
userMgmtLibrariesUpdateError: 'User saved, but library assignment failed',
|
||||
userMgmtNoLibraries: 'No libraries assigned',
|
||||
userMgmtNeverSeen: 'Never',
|
||||
userMgmtSave: 'Save',
|
||||
userMgmtCancel: 'Cancel',
|
||||
userMgmtDelete: 'Delete',
|
||||
userMgmtEdit: 'Edit',
|
||||
userMgmtConfirmDelete: 'Delete user "{{username}}"? This cannot be undone.',
|
||||
userMgmtCreateError: 'Failed to create user.',
|
||||
userMgmtUpdateError: 'Failed to update user.',
|
||||
userMgmtDeleteError: 'Failed to delete user.',
|
||||
userMgmtCreated: 'User created.',
|
||||
userMgmtUpdated: 'User updated.',
|
||||
userMgmtDeleted: 'User deleted.',
|
||||
userMgmtValidationMissing: 'Username, display name and password are required.',
|
||||
userMgmtValidationMissingIdentity: 'Username and display name are required.',
|
||||
userMgmtMagicStringGenerate: 'Generate magic string',
|
||||
userMgmtSaveAndMagicString: 'Save and get magic string',
|
||||
userMgmtMagicStringPasswordNavHint:
|
||||
'Navidrome will save this password for the user. If it differs from the current one, the server will update the login password.',
|
||||
userMgmtMagicStringPlaintextWarning:
|
||||
'Share the magic string carefully: it contains an unencrypted password (encoding is not encryption). Anyone with the full string can sign in as this user.',
|
||||
userMgmtMagicStringCopied: 'Magic string copied to clipboard.',
|
||||
userMgmtMagicStringCopyFailed: 'Could not copy to clipboard.',
|
||||
userMgmtMagicStringLoginFailed: 'Password check failed — credentials could not be verified.',
|
||||
userMgmtMagicStringModalTitle: 'Generate magic string',
|
||||
userMgmtMagicStringModalDesc: 'Enter the Subsonic password for "{{username}}". It is included in the copied magic string.',
|
||||
userMgmtMagicStringModalConfirm: 'Copy string',
|
||||
audiomuseTitle: 'AudioMuse-AI (Navidrome)',
|
||||
audiomuseDesc:
|
||||
'Turn on if this server has the <pluginLink>AudioMuse-AI Navidrome plugin</pluginLink> configured. Enables Instant Mix from tracks and uses server-side similar artists instead of Last.fm on artist pages.',
|
||||
audiomuseIssueHint:
|
||||
'Instant Mix failed recently — check the Navidrome plugin and AudioMuse API. Similar artists fall back to Last.fm when the server returns none.',
|
||||
connected: 'Connected',
|
||||
failed: 'Failed',
|
||||
eqTitle: 'Equalizer',
|
||||
eqEnabled: 'Enable Equalizer',
|
||||
eqPreset: 'Preset',
|
||||
eqPresetCustom: 'Custom',
|
||||
eqPresetBuiltin: 'Built-in Presets',
|
||||
eqPresetCustomGroup: 'My Presets',
|
||||
eqSavePreset: 'Save as Preset',
|
||||
eqPresetName: 'Preset name…',
|
||||
eqDeletePreset: 'Delete preset',
|
||||
eqResetBands: 'Reset to Flat',
|
||||
eqPreGain: 'Pre-gain',
|
||||
eqResetPreGain: 'Reset pre-gain',
|
||||
eqAutoEqTitle: 'AutoEQ Headphone Lookup',
|
||||
eqAutoEqPlaceholder: 'Search headphone / IEM model…',
|
||||
eqAutoEqSearching: 'Searching…',
|
||||
eqAutoEqNoResults: 'No results found',
|
||||
eqAutoEqError: 'Search failed',
|
||||
eqAutoEqRateLimit: 'GitHub rate limit reached — try again in a minute',
|
||||
eqAutoEqFetchError: 'Failed to fetch EQ profile',
|
||||
lfmTitle: 'Last.fm',
|
||||
lfmConnect: 'Connect with Last.fm',
|
||||
lfmConnecting: 'Waiting for authorisation…',
|
||||
lfmConfirm: 'I have authorised the app',
|
||||
lfmConnected: 'Connected as',
|
||||
lfmDisconnect: 'Disconnect',
|
||||
lfmConnectDesc: 'Connect your Last.fm account to enable scrobbling and Now Playing updates directly from Psysonic — no Navidrome configuration required.',
|
||||
lfmOpenBrowser: 'A browser window will open. Authorise Psysonic on Last.fm, then click the button below.',
|
||||
lfmScrobbles: '{{n}} scrobbles',
|
||||
lfmMemberSince: 'Member since {{year}}',
|
||||
scrobbleEnabled: 'Scrobbling enabled',
|
||||
scrobbleDesc: 'Send songs to Last.fm after 50% playtime',
|
||||
behavior: 'App Behavior',
|
||||
cacheTitle: 'Max. Storage Size',
|
||||
cacheDesc: 'Cover art and artist images. When full, the oldest entries are removed automatically. Offline albums are not auto-removed, but will be deleted when clearing the cache manually.',
|
||||
cacheUsedImages: 'Images:',
|
||||
cacheUsedOffline: 'Offline tracks:',
|
||||
cacheUsedHot: 'Size on disk:',
|
||||
hotCacheTrackCount: 'Tracks in cache:',
|
||||
cacheMaxLabel: 'Max. size',
|
||||
cacheClearBtn: 'Clear Cache',
|
||||
waveformCacheClearBtn: 'Clear waveform cache',
|
||||
cacheClearWarning: 'This will also remove all offline albums from the library.',
|
||||
cacheClearConfirm: 'Clear Everything',
|
||||
cacheClearCancel: 'Cancel',
|
||||
waveformCacheCleared: 'Waveform cache cleared ({{count}} rows).',
|
||||
waveformCacheClearFailed: 'Failed to clear waveform cache.',
|
||||
offlineDirTitle: 'Offline Library (In-App)',
|
||||
offlineDirDesc: 'Storage location for tracks you make available offline within Psysonic.',
|
||||
offlineDirDefault: 'Default (App Data)',
|
||||
offlineDirChange: 'Change Directory',
|
||||
offlineDirClear: 'Reset to Default',
|
||||
offlineDirHint: 'New downloads will use this location. Existing downloads remain at their original path.',
|
||||
hotCacheTitle: 'Hot playback cache',
|
||||
hotCacheDisclaimer: 'Preloads upcoming queue tracks and keeps previous ones. When enabled, uses disk space and network.',
|
||||
hotCacheDirDefault: 'Default (App Data)',
|
||||
hotCacheDirChange: 'Change folder',
|
||||
hotCacheDirClear: 'Reset to default',
|
||||
hotCacheDirHint: 'Changing the folder resets the in-app index; files already on disk stay where they are until you remove them.',
|
||||
hotCacheEnabled: 'Enable hot playback cache',
|
||||
hotCacheMaxMb: 'Maximum cache size',
|
||||
hotCacheDebounce: 'Queue change debounce',
|
||||
hotCacheDebounceImmediate: 'Immediate',
|
||||
hotCacheDebounceSeconds: '{{n}} s',
|
||||
hotCacheClearBtn: 'Clear hot cache',
|
||||
audioOutputDevice: 'Audio Output Device',
|
||||
audioOutputDeviceDesc: 'Select which audio device Psysonic plays through. Changes take effect immediately and restart the current track.',
|
||||
audioOutputDeviceDefault: 'System Default',
|
||||
audioOutputDeviceRefresh: 'Refresh device list',
|
||||
audioOutputDeviceOsDefaultNow: 'current system output',
|
||||
audioOutputDeviceListError: 'Could not load the audio device list.',
|
||||
audioOutputDeviceNotInCurrentList: 'not in current list',
|
||||
audioOutputDeviceMacNotice: 'On macOS, playback currently always follows the system output device for technical reasons. Change the target via System Settings → Sound or the speaker icon in the menu bar. Background: CoreAudio triggers a microphone-permission prompt when opening a non-default stream — we avoid it by always using the system default.',
|
||||
hiResTitle: 'Native Hi-Res Playback',
|
||||
hiResEnabled: 'Enable native hi-res playback',
|
||||
hiResDesc: "Forces 44.1 kHz output by default for maximum stability. Enable only if your hardware and network reliably support high sample rates (88.2 kHz+).",
|
||||
showArtistImages: 'Show Artist Images',
|
||||
showArtistImagesDesc: 'Load and display artist images in the Artists overview. Disabled by default to reduce server disk I/O and network load on large libraries.',
|
||||
showOrbitTrigger: 'Show "Orbit" in the header',
|
||||
showOrbitTriggerDesc: 'The top-bar trigger for starting or joining a shared listening session. Hide it if you don\'t use Orbit — you can turn it back on here.',
|
||||
showTrayIcon: 'Show Tray Icon',
|
||||
showTrayIconDesc: 'Display the Psysonic icon in the system notification area / menu bar.',
|
||||
minimizeToTray: 'Minimize to Tray',
|
||||
minimizeToTrayDesc: 'When closing the window, keep Psysonic running in the system tray instead of quitting.',
|
||||
preloadMiniPlayer: 'Preload mini player',
|
||||
preloadMiniPlayerDesc: 'Build the mini player window in the background at app start so it shows content instantly on first open. Uses a little extra memory.',
|
||||
discordRichPresence: 'Discord Rich Presence',
|
||||
discordRichPresenceDesc: 'Show the currently playing track on your Discord profile. Requires Discord to be running.',
|
||||
useCustomTitlebar: 'Custom title bar',
|
||||
useCustomTitlebarDesc: 'Replace the system title bar with a built-in one that matches the app theme. Disable to use the native GNOME/GTK title bar.',
|
||||
linuxWebkitSmoothScroll: 'Smooth wheel (Linux)',
|
||||
linuxWebkitSmoothScrollDesc: 'On: inertial scroll. Off: line-by-line, GTK-style.',
|
||||
discordCoverSource: 'Cover art source',
|
||||
discordCoverSourceDesc: 'Where to fetch album artwork shown on your Discord profile.',
|
||||
discordCoverNone: 'None (app icon only)',
|
||||
discordCoverServer: 'Server (via album info)',
|
||||
discordCoverApple: 'Apple Music',
|
||||
discordOptions: 'Advanced Discord options',
|
||||
discordTemplates: 'Custom text templates',
|
||||
discordTemplatesDesc: 'Customize what information is shown on your Discord profile. Variables: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Primary line (details)',
|
||||
discordTemplateState: 'Secondary line (state)',
|
||||
discordTemplateLargeText: 'Album tooltip (largeText)',
|
||||
nowPlayingEnabled: 'Show in Now Playing',
|
||||
nowPlayingEnabledDesc: 'Broadcast your currently playing track to the server\'s live listener view. Disable to stop sending playback data.',
|
||||
enableBandsintown: 'Bandsintown tour dates',
|
||||
enableBandsintownDesc: 'Show upcoming concerts for the current artist in the Info tab. Data is fetched from the public Bandsintown API.',
|
||||
lyricsServerFirst: 'Prefer server lyrics',
|
||||
lyricsServerFirstDesc: 'Check server-provided lyrics (embedded tags, sidecar files) before querying LRCLIB. Disable to use LRCLIB first.',
|
||||
enableNeteaselyrics: 'Netease Cloud Music lyrics',
|
||||
enableNeteaselyricsDesc: 'Use Netease Cloud Music as a last-resort lyrics source when server and LRCLIB both return nothing. Best coverage for Asian and international music.',
|
||||
lyricsSourcesTitle: 'Lyrics Sources',
|
||||
lyricsSourcesDesc: 'Choose which sources to query for lyrics and in what order. Drag to reorder. Disabled sources are skipped entirely.',
|
||||
lyricsSourceServer: 'Server',
|
||||
lyricsSourceLrclib: 'LRCLIB',
|
||||
lyricsSourceNetease: 'Netease Cloud Music',
|
||||
lyricsModeStandard: 'Standard',
|
||||
lyricsModeStandardDesc: 'Three sources in a freely orderable list: server tags, LRCLIB, Netease.',
|
||||
lyricsModeLyricsplus: 'YouLyPlus (Karaoke)',
|
||||
lyricsModeLyricsplusDesc: 'Word-by-word sync sourced from Apple Music, Spotify, Musixmatch & QQ (community backend). Silently falls back to the standard sources when nothing is found.',
|
||||
lyricsStaticOnly: 'Show lyrics as static text only',
|
||||
lyricsStaticOnlyDesc: 'Render synced lyrics without auto-scroll and without word highlighting.',
|
||||
downloadsTitle: 'ZIP Export & Archiving',
|
||||
downloadsFolderDesc: 'Destination folder for albums you download as a ZIP file to your computer.',
|
||||
downloadsDefault: 'Default Downloads Folder',
|
||||
pickFolder: 'Select',
|
||||
pickFolderTitle: 'Select Download Folder',
|
||||
clearFolder: 'Clear download folder',
|
||||
logout: 'Logout',
|
||||
aboutTitle: 'About Psysonic',
|
||||
aboutDesc: 'A modern desktop music player built for Navidrome. Uses the Subsonic API plus Navidrome-specific extensions. Built on Tauri v2 with a native Rust audio engine — lightweight and fast, yet packed with features: waveform seekbar, synchronized lyrics, Last.fm integration, 10-band EQ, crossfade, gapless playback, Replay Gain, genre browsing, and a large library of themes.',
|
||||
aboutLicense: 'License',
|
||||
aboutLicenseText: 'GNU GPL v3 — free to use, modify, and distribute under the same license.',
|
||||
aboutRepo: 'Source Code on GitHub',
|
||||
aboutVersion: 'Version',
|
||||
aboutBuiltWith: 'Built with Tauri · React · TypeScript · Rust/rodio',
|
||||
aboutMaintainersLabel: 'Maintainers',
|
||||
aboutReleaseNotesLabel: 'Release notes',
|
||||
aboutReleaseNotesLink: "Open this version's what's-new",
|
||||
aboutContributorsLabel: 'Contributors',
|
||||
showChangelogOnUpdate: "Show 'What's New' on update",
|
||||
showChangelogOnUpdateDesc: "Show a discreet changelog banner above Now Playing after an update. Click opens the release notes; X dismisses it.",
|
||||
randomMixTitle: 'Random Mix Blacklist',
|
||||
luckyMixMenuTitle: 'Show Lucky Mix in menu',
|
||||
luckyMixMenuDesc: 'Enables Lucky Mix in Build a Mix and as a separate menu item when split navigation is on. Visible only when AudioMuse is enabled on the active server.',
|
||||
randomMixBlacklistTitle: 'Custom Filter Keywords',
|
||||
randomMixBlacklistDesc: 'Songs are excluded when any keyword matches their genre, title, album, or artist (active when the checkbox above is on).',
|
||||
randomMixBlacklistPlaceholder: 'Add keyword…',
|
||||
randomMixBlacklistAdd: 'Add',
|
||||
randomMixBlacklistEmpty: 'No custom keywords added yet.',
|
||||
randomMixHardcodedTitle: 'Built-in keywords (active when checkbox is on)',
|
||||
tabAudio: 'Audio',
|
||||
tabStorage: 'Offline & Cache',
|
||||
tabAppearance: 'Appearance',
|
||||
tabLibrary: 'Library',
|
||||
tabServers: 'Servers',
|
||||
tabLyrics: 'Lyrics',
|
||||
tabPersonalisation: 'Personalisation',
|
||||
tabIntegrations: 'Integrations',
|
||||
inputKeybindingsTitle: 'Keyboard shortcuts',
|
||||
aboutContributorsCount_one: '{{count}} contribution',
|
||||
aboutContributorsCount_other: '{{count}} contributions',
|
||||
searchPlaceholder: 'Search settings…',
|
||||
searchNoResults: 'No settings match your search.',
|
||||
integrationsPrivacyTitle: 'Privacy notice',
|
||||
integrationsPrivacyBody: 'All integrations on this tab are <strong>opt-in</strong> and send data to external services or to your Navidrome server when enabled. Last.fm receives your listening history, Discord shows the currently playing track in your profile, Bandsintown is queried per artist to fetch tour dates, and the Now-Playing share publishes your current track to other users of your Navidrome server. If you don\'t want any of this, simply leave the corresponding section disabled.',
|
||||
homeCustomizerTitle: 'Home Page',
|
||||
queueToolbarTitle: 'Queue Toolbar',
|
||||
queueToolbarReset: 'Reset to default',
|
||||
queueToolbarSeparator: 'Separator',
|
||||
sidebarTitle: 'Sidebar',
|
||||
sidebarReset: 'Reset to default',
|
||||
artistLayoutTitle: 'Artist page sections',
|
||||
artistLayoutDesc: 'Drag to reorder, toggle to hide individual sections of the artist page. Sections without data are skipped automatically.',
|
||||
artistLayoutReset: 'Reset to default',
|
||||
artistLayoutBio: 'Artist biography',
|
||||
artistLayoutTopTracks: 'Top tracks',
|
||||
artistLayoutSimilar: 'Similar artists',
|
||||
artistLayoutAlbums: 'Albums',
|
||||
artistLayoutFeatured: 'Also featured on',
|
||||
sidebarDrag: 'Drag to reorder',
|
||||
sidebarFixed: 'Always visible',
|
||||
randomNavSplitTitle: 'Split Mix navigation',
|
||||
randomNavSplitDesc: 'Show "Random Mix", "Random Albums", and "Lucky Mix" as separate sidebar entries instead of the "Build a Mix" hub.',
|
||||
tabInput: 'Input',
|
||||
tabUsers: 'Users',
|
||||
tabSystem: 'System',
|
||||
loggingTitle: 'Logging',
|
||||
loggingModeDesc: 'Controls backend log verbosity in the terminal.',
|
||||
loggingModeOff: 'Off',
|
||||
loggingModeNormal: 'Normal',
|
||||
loggingModeDebug: 'Debug',
|
||||
loggingExport: 'Export logs',
|
||||
loggingExportSuccess: 'Logs exported ({{count}} lines).',
|
||||
loggingExportError: 'Could not export logs.',
|
||||
ratingsSectionTitle: 'Ratings',
|
||||
ratingsSkipStarTitle: 'Skip for 1 star',
|
||||
ratingsSkipStarDesc:
|
||||
'After several skips in a row, set the track to 1★. Only for tracks not yet rated.',
|
||||
ratingsSkipStarThresholdLabel: 'Skips',
|
||||
ratingsMixFilterTitle: 'Filter by rating',
|
||||
ratingsMixFilterDesc:
|
||||
'Filter low-rated items in {{mix}} and {{albums}}. Click the selected star again to turn off the threshold.',
|
||||
ratingsMixMinSong: 'Songs',
|
||||
ratingsMixMinAlbum: 'Albums',
|
||||
ratingsMixMinArtist: 'Artists',
|
||||
ratingsMixMinThresholdAria: 'Minimum stars: {{label}}',
|
||||
backupTitle: 'Backup & Restore',
|
||||
backupExport: 'Export settings',
|
||||
backupExportDesc: 'Saves all settings, server profiles, Last.fm config, theme, EQ and keybindings to a .psybkp file. Passwords are stored in plaintext — keep the file secure.',
|
||||
backupImport: 'Import settings',
|
||||
backupImportDesc: 'Restores settings from a .psybkp file. The app will reload after import.',
|
||||
backupImportConfirm: 'This will overwrite all current settings. Continue?',
|
||||
backupSuccess: 'Backup saved',
|
||||
backupImportSuccess: 'Settings restored — reloading…',
|
||||
backupImportError: 'Invalid or corrupted backup file.',
|
||||
shortcutsReset: 'Reset to defaults',
|
||||
shortcutListening: 'Press a key…',
|
||||
shortcutUnbound: '—',
|
||||
globalShortcutsTitle: 'Global Shortcuts',
|
||||
globalShortcutsNote: 'Work system-wide even when Psysonic is in the background. Requires Ctrl, Alt, or Super as a modifier.',
|
||||
shortcutClear: 'Clear',
|
||||
shortcutPlayPause: 'Play / Pause',
|
||||
shortcutNext: 'Next track',
|
||||
shortcutPrev: 'Previous track',
|
||||
shortcutVolumeUp: 'Volume up',
|
||||
shortcutVolumeDown: 'Volume down',
|
||||
shortcutSeekForward: 'Seek forward 10s',
|
||||
shortcutSeekBackward: 'Seek backward 10s',
|
||||
shortcutToggleQueue: 'Toggle queue',
|
||||
shortcutOpenFolderBrowser: 'Open {{folderBrowser}}',
|
||||
shortcutFullscreenPlayer: 'Fullscreen player',
|
||||
shortcutNativeFullscreen: 'Native fullscreen',
|
||||
shortcutOpenMiniPlayer: 'Open mini player',
|
||||
shortcutStartSearch: 'Start a search',
|
||||
shortcutStartAdvancedSearch: 'Start an advanced search',
|
||||
shortcutToggleSidebar: 'Toggle Sidebar',
|
||||
shortcutMuteSound: 'Mute sound',
|
||||
shortcutToggleEqualizer: 'Open / Toggle Equalizer',
|
||||
shortcutToggleRepeat: 'Toggle Repeat',
|
||||
shortcutOpenNowPlaying: 'Open "Now Playing"',
|
||||
shortcutShowLyrics: 'Show Lyrics',
|
||||
shortcutFavoriteCurrentTrack: 'Add current track to favorites',
|
||||
shortcutOpenHelp: 'Help',
|
||||
playbackTitle: 'Playback',
|
||||
replayGain: 'Replay Gain',
|
||||
replayGainDesc: 'Normalize track volume using ReplayGain metadata',
|
||||
replayGainMode: 'Mode',
|
||||
replayGainAuto: 'Auto',
|
||||
replayGainAutoDesc: 'Picks album gain when neighbouring queue tracks are from the same album, otherwise track gain.',
|
||||
replayGainTrack: 'Track',
|
||||
replayGainAlbum: 'Album',
|
||||
replayGainPreGain: 'Pre-Gain (tagged files)',
|
||||
replayGainPreGainDesc: 'Universal boost added on top of every ReplayGain calculation. Use to compensate if your library feels too quiet overall.',
|
||||
replayGainFallback: 'Fallback (untagged / radio)',
|
||||
replayGainFallbackDesc: 'Applied to tracks (and radio streams) that have no ReplayGain tags at all, so untagged content does not pop louder than the rest.',
|
||||
normalization: 'Normalization',
|
||||
normalizationDesc: 'Even out perceived loudness across tracks, albums and radio.',
|
||||
normalizationOff: 'Off',
|
||||
normalizationReplayGain: 'ReplayGain',
|
||||
normalizationLufs: 'LUFS',
|
||||
loudnessTargetLufs: 'Target LUFS',
|
||||
loudnessTargetLufsDesc: 'Reference loudness all tracks are matched to. Lower numbers = louder output. Streaming services typically sit around -14 LUFS.',
|
||||
loudnessPreAnalysisAttenuation: 'Pre-analysis attenuation',
|
||||
loudnessPreAnalysisAttenuationDesc:
|
||||
'Extra quieting until loudness for this track is saved. Streaming then uses rough guesses, not a full measurement. 0 dB = off; lower = quieter. The number on the right is the effective dB for your current target.',
|
||||
loudnessPreAnalysisAttenuationRef: 'Effective {{eff}} dB with target {{tgt}} LUFS.',
|
||||
loudnessPreAnalysisAttenuationReset: 'Reset to default',
|
||||
loudnessFirstPlayNote:
|
||||
'First play of a brand-new track may briefly drift in volume while it is being measured. The next play uses the cached measurement and is rock-solid. Upcoming queue tracks are usually pre-analysed during the previous song, so this rarely happens in practice.',
|
||||
crossfade: 'Crossfade',
|
||||
crossfadeDesc: 'Fade between tracks',
|
||||
crossfadeSecs: '{{n}} s',
|
||||
notWithGapless: 'Not available while Gapless is active',
|
||||
notWithCrossfade: 'Not available while Crossfade is active',
|
||||
gapless: 'Gapless Playback',
|
||||
gaplessDesc: 'Pre-buffer next track to eliminate gaps between songs',
|
||||
preservePlayNextOrder: 'Preserve "Play Next" order',
|
||||
preservePlayNextOrderDesc: 'Newly added Play Next items queue up behind earlier ones instead of jumping in front.',
|
||||
trackPreviewsTitle: 'Track Previews',
|
||||
trackPreviewsToggle: 'Enable track previews',
|
||||
trackPreviewsDesc: 'Show inline Play and Preview buttons in tracklists for a quick mid-song sample.',
|
||||
trackPreviewStart: 'Start position',
|
||||
trackPreviewStartDesc: 'How far into the track the preview starts (% of track length).',
|
||||
trackPreviewDuration: 'Duration',
|
||||
trackPreviewDurationDesc: 'How long each preview plays before it stops.',
|
||||
trackPreviewDurationSecs: '{{n}} s',
|
||||
trackPreviewLocationsTitle: 'Where previews appear',
|
||||
trackPreviewLocationsDesc: 'Pick which lists show inline preview buttons.',
|
||||
trackPreviewLocation_suggestions: 'In playlist suggestions',
|
||||
trackPreviewLocation_albums: 'In album tracklists',
|
||||
trackPreviewLocation_playlists: 'In playlists',
|
||||
trackPreviewLocation_favorites: 'In favorites',
|
||||
trackPreviewLocation_artist: 'In artist top tracks',
|
||||
trackPreviewLocation_randomMix: 'In Random Mix',
|
||||
preloadMode: 'Preload Next Track',
|
||||
preloadModeDesc: 'When to start buffering the next track in the queue',
|
||||
nextTrackBufferingTitle: 'Buffering',
|
||||
preloadHotCacheMutualExclusive: 'Preload and Hot Cache serve the same purpose — only one can be active at a time. Enabling one will automatically disable the other.',
|
||||
preloadOff: 'Off',
|
||||
preloadBalanced: 'Balanced (30 s before end)',
|
||||
preloadEarly: 'Early (after 5 s of playback)',
|
||||
preloadCustom: 'Custom',
|
||||
preloadCustomSeconds: 'Seconds before end: {{n}}',
|
||||
infiniteQueue: 'Infinite Queue',
|
||||
infiniteQueueDesc: 'Automatically append random tracks when the queue runs out',
|
||||
experimental: 'Experimental',
|
||||
fsPlayerSection: 'Fullscreen Player',
|
||||
fsLyricsStyle: 'Lyrics style',
|
||||
fsLyricsStyleRail: 'Rail',
|
||||
fsLyricsStyleRailDesc: 'Classic 5-line sliding rail.',
|
||||
fsLyricsStyleApple: 'Scrolling',
|
||||
fsLyricsStyleAppleDesc: 'Full-screen scrollable list.',
|
||||
sidebarLyricsStyle: 'Lyrics scroll style',
|
||||
sidebarLyricsStyleClassic: 'Classic',
|
||||
sidebarLyricsStyleClassicDesc: 'Scroll active line to center.',
|
||||
sidebarLyricsStyleApple: 'Apple Music-like',
|
||||
sidebarLyricsStyleAppleDesc: 'Active line anchors near the top with smooth spring transitions.',
|
||||
fsShowArtistPortrait: 'Show artist photo',
|
||||
fsShowArtistPortraitDesc: 'Display the artist photo (or album art) on the right side of the fullscreen player.',
|
||||
fsPortraitDim: 'Photo dimming',
|
||||
seekbarStyle: 'Seekbar Style',
|
||||
seekbarStyleDesc: 'Choose the look of the player seek bar',
|
||||
seekbarTruewave: 'Truewave',
|
||||
seekbarPseudowave: 'Pseudowave',
|
||||
seekbarLinedot: 'Line & Dot',
|
||||
seekbarBar: 'Bar',
|
||||
seekbarThick: 'Thick Bar',
|
||||
seekbarSegmented: 'Segmented',
|
||||
seekbarNeon: 'Neon Glow',
|
||||
seekbarPulsewave: 'Pulse Wave',
|
||||
seekbarParticletrail: 'Particle Trail',
|
||||
seekbarLiquidfill: 'Liquid Fill',
|
||||
seekbarRetrotape: 'Retro Tape',
|
||||
themeSchedulerTitle: 'Auto-Switch Theme',
|
||||
themeSchedulerEnable: 'Enable Theme Scheduler',
|
||||
themeSchedulerEnableSub: 'Automatically switch between two themes based on the time of day',
|
||||
themeSchedulerDayTheme: 'Day Theme',
|
||||
themeSchedulerDayStart: 'Day Starts At',
|
||||
themeSchedulerNightTheme: 'Night Theme',
|
||||
themeSchedulerNightStart: 'Night Starts At',
|
||||
themeSchedulerActiveHint: 'Theme Scheduler is active - theme changes are managed automatically.',
|
||||
visualOptionsTitle: 'Visual Options',
|
||||
coverArtBackground: 'Cover Art Background',
|
||||
coverArtBackgroundSub: 'Show blurred cover art as background in album/playlist headers',
|
||||
playlistCoverPhoto: 'Playlist Cover Photo',
|
||||
playlistCoverPhotoSub: 'Show cover photo grid in playlist detail view',
|
||||
showBitrate: 'Show Bitrate',
|
||||
showBitrateSub: 'Display audio bitrate in track listings',
|
||||
floatingPlayerBar: 'Floating Player Bar',
|
||||
floatingPlayerBarSub: 'Keep the player bar floating above content',
|
||||
uiScaleTitle: 'Interface Scale',
|
||||
uiScaleLabel: 'Zoom',
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
export const sharePaste = {
|
||||
notLoggedIn: 'Sign in and add the server before pasting a share link.',
|
||||
noMatchingServer: 'No saved server matches this link. Add a server with this address: {{url}}',
|
||||
trackUnavailable: 'This track was not found on the server.',
|
||||
albumUnavailable: 'This album was not found on the server.',
|
||||
artistUnavailable: 'This artist was not found on the server.',
|
||||
composerUnavailable: 'This composer was not found on the server.',
|
||||
openedTrack: 'Playing shared track.',
|
||||
openedAlbum: 'Opening shared album.',
|
||||
openedArtist: 'Opening shared artist.',
|
||||
openedComposer: 'Opening shared composer.',
|
||||
openedQueue_one: 'Playing {{count}} track from the share link.',
|
||||
openedQueue_other: 'Playing {{count}} tracks from the share link.',
|
||||
openedQueuePartial:
|
||||
'Playing {{played}} of {{total}} tracks from the link ({{skipped}} not found on this server).',
|
||||
queueAllUnavailable: 'None of the tracks from this link were found on the server.',
|
||||
genericError: 'Could not open the share link.',
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
export const sidebar = {
|
||||
library: 'Library',
|
||||
mainstage: 'Mainstage',
|
||||
newReleases: 'New Releases',
|
||||
allAlbums: 'All Albums',
|
||||
randomAlbums: 'Random Albums',
|
||||
randomPicker: 'Build a Mix',
|
||||
artists: 'Artists',
|
||||
composers: 'Composers',
|
||||
randomMix: 'Random Mix',
|
||||
favorites: 'Favorites',
|
||||
nowPlaying: 'Now Playing',
|
||||
system: 'System',
|
||||
statistics: 'Statistics',
|
||||
settings: 'Settings',
|
||||
help: 'Help',
|
||||
expand: 'Expand Sidebar',
|
||||
collapse: 'Collapse Sidebar',
|
||||
|
||||
downloadingTracks: 'Caching {{n}} tracks…',
|
||||
syncingTracks: 'Syncing {{done}}/{{total}}…',
|
||||
cancelDownload: 'Cancel download',
|
||||
offlineLibrary: 'Offline Library',
|
||||
genres: 'Genres',
|
||||
tracks: 'Tracks',
|
||||
playlists: 'Playlists',
|
||||
smartPlaylists: 'Smart Playlists',
|
||||
mostPlayed: 'Most Played',
|
||||
losslessAlbums: 'Lossless',
|
||||
radio: 'Internet Radio',
|
||||
folderBrowser: 'Folder Browser',
|
||||
deviceSync: 'Device Sync',
|
||||
libraryScope: 'Library scope',
|
||||
allLibraries: 'All libraries',
|
||||
expandPlaylists: 'Expand playlists',
|
||||
collapsePlaylists: 'Collapse playlists',
|
||||
more: 'More',
|
||||
feelingLucky: 'Lucky Mix',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export const smartPlaylists = {
|
||||
sectionBasic: '1. Basic',
|
||||
sectionGenres: '2. Genres',
|
||||
sectionYearsAndFilters: '3. Years and filters',
|
||||
genreMode: 'Genre mode',
|
||||
genreModeInclude: 'Include genres',
|
||||
genreModeExclude: 'Exclude genres',
|
||||
genreSearchPlaceholder: 'Filter genres...',
|
||||
availableGenres: 'Available',
|
||||
selectedGenres: 'Selected',
|
||||
yearMode: 'Year mode',
|
||||
yearModeInclude: 'Include range',
|
||||
yearModeExclude: 'Exclude range',
|
||||
name: 'Name (without prefix)',
|
||||
limit: 'Limit',
|
||||
limitHint: 'How many tracks to include in playlist (1-{{max}}, usually 50).',
|
||||
artistContains: 'Artist contains…',
|
||||
albumContains: 'Album contains…',
|
||||
titleContains: 'Title contains…',
|
||||
minRating: 'Minimum rating',
|
||||
minRatingAria: 'Minimum rating for smart playlist',
|
||||
minRatingHint: '0 disables minimum threshold; 1-5 keeps tracks with rating above selected value.',
|
||||
fromYear: 'From year',
|
||||
toYear: 'To year',
|
||||
excludeUnrated: 'Exclude unrated tracks',
|
||||
compilationOnly: 'Only compilations',
|
||||
create: 'New Smart Playlist',
|
||||
save: 'Save Smart Playlist',
|
||||
created: 'Created {{name}}',
|
||||
updated: 'Updated {{name}}',
|
||||
createFailed: 'Could not create smart playlist.',
|
||||
updateFailed: 'Could not update smart playlist.',
|
||||
navidromeOnly: 'Smart playlists can only be created on Navidrome servers.',
|
||||
loadFailed: 'Could not load smart playlists from Navidrome.',
|
||||
sortRandom: 'Sort: random',
|
||||
sortTitleAsc: 'Sort: title A-Z',
|
||||
sortTitleDesc: 'Sort: title Z-A',
|
||||
sortYearDesc: 'Sort: year desc',
|
||||
sortYearAsc: 'Sort: year asc',
|
||||
sortPlayCountDesc: 'Sort: play count desc',
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
export const songInfo = {
|
||||
title: 'Song Info',
|
||||
songTitle: 'Title',
|
||||
artist: 'Artist',
|
||||
album: 'Album',
|
||||
albumArtist: 'Album Artist',
|
||||
year: 'Year',
|
||||
genre: 'Genre',
|
||||
duration: 'Duration',
|
||||
track: 'Track',
|
||||
format: 'Format',
|
||||
bitrate: 'Bitrate',
|
||||
sampleRate: 'Sample Rate',
|
||||
bitDepth: 'Bit Depth',
|
||||
channels: 'Channels',
|
||||
fileSize: 'File Size',
|
||||
path: 'Path',
|
||||
replayGainTrack: 'RG Track Gain',
|
||||
replayGainAlbum: 'RG Album Gain',
|
||||
replayGainPeak: 'RG Track Peak',
|
||||
mono: 'Mono',
|
||||
stereo: 'Stereo',
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
export const statistics = {
|
||||
title: 'Statistics',
|
||||
recentlyPlayed: 'Recently Played',
|
||||
mostPlayed: 'Most Played Albums',
|
||||
highestRated: 'Highest Rated Albums',
|
||||
genreDistribution: 'Genre Distribution (Top 20)',
|
||||
loadMore: 'Load more',
|
||||
statArtists: 'Artists',
|
||||
statArtistsTooltip: 'Album artists only — artists appearing only as a track-level artist (featured, guest, etc.) without their own album are not included.',
|
||||
statAlbums: 'Albums',
|
||||
statSongs: 'Songs',
|
||||
statGenres: 'Genres',
|
||||
statPlaytime: 'Total Playtime',
|
||||
genreInsights: 'Genre Insights',
|
||||
formatDistribution: 'Format Distribution',
|
||||
formatSample: 'Sample of {{n}} tracks',
|
||||
computing: 'Computing…',
|
||||
genreSongs: '{{count}} Songs',
|
||||
genreAlbums: '{{count}} Albums',
|
||||
recentlyAdded: 'Recently Added',
|
||||
decadeDistribution: 'Albums by Decade',
|
||||
decadeAlbums_one: '{{count}} Album',
|
||||
decadeAlbums_other: '{{count}} Albums',
|
||||
decadeUnknown: 'Unknown',
|
||||
lfmTitle: 'Last.fm Stats',
|
||||
lfmTopArtists: 'Top Artists',
|
||||
lfmTopAlbums: 'Top Albums',
|
||||
lfmTopTracks: 'Top Tracks',
|
||||
lfmPlays: '{{count}} plays',
|
||||
lfmPeriodOverall: 'All Time',
|
||||
lfmPeriod7day: '7 Days',
|
||||
lfmPeriod1month: '1 Month',
|
||||
lfmPeriod3month: '3 Months',
|
||||
lfmPeriod6month: '6 Months',
|
||||
lfmPeriod12month: '12 Months',
|
||||
lfmNotConnected: 'Connect Last.fm in Settings to see your stats.',
|
||||
lfmRecentTracks: 'Recent Scrobbles',
|
||||
lfmNowPlaying: 'Now Playing',
|
||||
lfmJustNow: 'just now',
|
||||
lfmMinutesAgo: '{{n}}m ago',
|
||||
lfmHoursAgo: '{{n}}h ago',
|
||||
lfmDaysAgo: '{{n}}d ago',
|
||||
topRatedSongs: 'Top Rated Songs',
|
||||
topRatedArtists: 'Top Rated Artists',
|
||||
noRatedSongs: 'No rated songs yet. Rate songs in album or playlist view.',
|
||||
noRatedArtists: 'No rated artists yet.',
|
||||
exportShare: 'Share',
|
||||
exportTitle: 'Share Top Albums',
|
||||
exportSubtitle: 'Generate a shareable image of your most-played albums.',
|
||||
exportFormat: 'Format',
|
||||
exportFormatStory: 'Story',
|
||||
exportFormatSquare: 'Square',
|
||||
exportFormatTwitter: 'Twitter Card',
|
||||
exportGrid: 'Grid',
|
||||
exportGridLabel: '{{n}}×{{n}}',
|
||||
exportPreview: 'Preview',
|
||||
exportGenerate: 'Generate',
|
||||
exportSave: 'Save image…',
|
||||
exportCancel: 'Cancel',
|
||||
exportFooterLabel: 'Top Albums',
|
||||
exportNotEnough: 'Need at least {{count}} albums in your library for a {{n}}×{{n}} grid.',
|
||||
exportSaving: 'Saving…',
|
||||
exportSaved: 'Saved.',
|
||||
exportSaveFailed: 'Could not save the image.',
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
export const tracks = {
|
||||
title: 'Tracks',
|
||||
subtitle: 'Browse. Search. Discover.',
|
||||
heroEyebrow: 'Track of the moment',
|
||||
heroReroll: 'Pick another',
|
||||
playSong: 'Play',
|
||||
enqueueSong: 'Add to queue',
|
||||
railRandom: 'Random Pick',
|
||||
railHighlyRated: 'Highly Rated',
|
||||
browseTitle: 'Browse all tracks',
|
||||
browseUnsupported: "This server doesn't list the whole library at once. Use the search above to find specific tracks.",
|
||||
searchPlaceholder: 'Find a track by title, artist or album…',
|
||||
count_one: '{{count}} track',
|
||||
count_other: '{{count}} tracks',
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const tray = {
|
||||
playPause: 'Play / Pause',
|
||||
nextTrack: 'Next Track',
|
||||
previousTrack: 'Previous Track',
|
||||
showHide: 'Show / Hide',
|
||||
exitPsysonic: 'Exit Psysonic',
|
||||
nothingPlaying: 'Nothing playing',
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const whatsNew = {
|
||||
title: "What's New",
|
||||
empty: 'No changelog entry for this version yet.',
|
||||
bannerTitle: 'Changelog',
|
||||
bannerCollapsed: "What's new in v{{version}}",
|
||||
dismiss: 'Dismiss',
|
||||
close: 'Close',
|
||||
};
|
||||
-1828
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
export const albumDetail = {
|
||||
back: 'Volver',
|
||||
orbitDoubleClickHint: 'Doble clic para añadir esta canción a la cola Orbit',
|
||||
playAll: 'Reproducir Todo',
|
||||
shareAlbum: 'Compartir álbum',
|
||||
enqueue: 'Agregar a la Cola',
|
||||
enqueueTooltip: 'Agregar álbum completo a la cola',
|
||||
artistBio: 'Biografía del Artista',
|
||||
download: 'Descargar (ZIP)',
|
||||
downloading: 'Cargando…',
|
||||
cacheOffline: 'Disponible offline',
|
||||
offlineCached: 'Disponible offline',
|
||||
offlineDownloading: 'Descargando… ({{n}}/{{total}})',
|
||||
removeOffline: 'Quitar de offline',
|
||||
offlineStorageFull: 'Almacenamiento offline lleno (límite: {{mb}} MB). Libera espacio eliminando un álbum de tu Biblioteca Offline, o aumenta el límite en Configuración.',
|
||||
offlineStorageGoToLibrary: 'Biblioteca Offline',
|
||||
offlineStorageGoToSettings: 'Configuración',
|
||||
favoriteAdd: 'Agregar a Favoritos',
|
||||
favoriteRemove: 'Quitar de Favoritos',
|
||||
favorite: 'Favorito',
|
||||
noBio: 'No hay biografía disponible.',
|
||||
moreByArtist: 'Más de {{artist}}',
|
||||
tracksCount: '{{n}} Pistas',
|
||||
goToArtist: 'Ir a {{artist}}',
|
||||
moreLabelAlbums: 'Más álbumes en {{label}}',
|
||||
trackTitle: 'Título',
|
||||
trackAlbum: 'Álbum',
|
||||
trackArtist: 'Artista',
|
||||
trackGenre: 'Género',
|
||||
trackFormat: 'Formato',
|
||||
trackFavorite: 'Favorito',
|
||||
trackRating: 'Calificación',
|
||||
trackDuration: 'Duración',
|
||||
trackTotal: 'Total',
|
||||
columns: 'Columnas',
|
||||
resetColumns: 'Restablecer',
|
||||
notFound: 'Álbum no encontrado.',
|
||||
bioModal: 'Biografía del Artista',
|
||||
bioClose: 'Cerrar',
|
||||
ratingLabel: 'Calificación',
|
||||
enlargeCover: 'Ampliar',
|
||||
filterSongs: 'Filtrar canciones…',
|
||||
sortNatural: 'Natural',
|
||||
sortByTitle: 'A–Z (Título)',
|
||||
sortByArtist: 'A–Z (Artista)',
|
||||
sortByAlbum: 'A–Z (Álbum)',
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
export const albums = {
|
||||
title: 'Todos los Álbumes',
|
||||
sortByName: 'A–Z (Álbum)',
|
||||
sortByArtist: 'A–Z (Artista)',
|
||||
sortNewest: 'Más recientes primero',
|
||||
sortRandom: 'Aleatorio',
|
||||
yearFrom: 'Desde',
|
||||
yearTo: 'Hasta',
|
||||
yearFilterClear: 'Limpiar filtro de año',
|
||||
yearFilterLabel: 'Año',
|
||||
compilationLabel: 'Recopilatorios',
|
||||
compilationOnly: 'Solo recopilatorios',
|
||||
compilationHide: 'Ocultar recopilatorios',
|
||||
compilationTooltipAll: 'Todos los álbumes · clic: solo recopilatorios',
|
||||
compilationTooltipOnly: 'Solo recopilatorios · clic: ocultar recopilatorios',
|
||||
compilationTooltipHide: 'Recopilatorios ocultos · clic: mostrar todo',
|
||||
select: 'Selección múltiple',
|
||||
startSelect: 'Activar selección múltiple',
|
||||
cancelSelect: 'Cancelar',
|
||||
selectionCount: '{{count}} seleccionados',
|
||||
downloadZips: 'Descargar ZIPs',
|
||||
addOffline: 'Agregar Offline',
|
||||
enqueueSelected_one: 'A la cola ({{count}})',
|
||||
enqueueSelected_other: 'A la cola ({{count}})',
|
||||
enqueueQueued_one: '{{count}} álbum añadido a la cola',
|
||||
enqueueQueued_other: '{{count}} álbumes añadidos a la cola',
|
||||
downloadingZip: 'Descargando {{current}}/{{total}}: {{name}}',
|
||||
downloadZipDone: '{{count}} ZIP(s) descargado(s)',
|
||||
downloadZipFailed: 'Error al descargar {{name}}',
|
||||
offlineQueuing: 'Encolando {{count}} álbum(es) para offline…',
|
||||
offlineFailed: 'Error al agregar {{name}} offline',
|
||||
addToPlaylist: 'Agregar a Lista de Reproducción',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
export const artistDetail = {
|
||||
back: 'Volver',
|
||||
albums: 'Álbumes',
|
||||
album: 'Álbum',
|
||||
playAll: 'Reproducir Todo',
|
||||
shareArtist: 'Compartir artista',
|
||||
shuffle: 'Aleatorio',
|
||||
radio: 'Radio',
|
||||
loading: 'Cargando…',
|
||||
noRadio: 'No se encontraron pistas similares para este artista.',
|
||||
notFound: 'Artista no encontrado.',
|
||||
albumsBy: 'Álbumes de {{name}}',
|
||||
topTracks: 'Mejores Pistas',
|
||||
noAlbums: 'No se encontraron álbumes.',
|
||||
trackTitle: 'Título',
|
||||
trackAlbum: 'Álbum',
|
||||
trackDuration: 'Duración',
|
||||
favoriteAdd: 'Agregar a Favoritos',
|
||||
favoriteRemove: 'Quitar de Favoritos',
|
||||
favorite: 'Favorito',
|
||||
albumCount_one: '{{count}} Álbum',
|
||||
albumCount_other: '{{count}} Álbumes',
|
||||
openedInBrowser: 'Abierto en navegador',
|
||||
featuredOn: 'También Aparece En',
|
||||
similarArtists: 'Artistas Similares',
|
||||
cacheOffline: 'Guardar discografía offline',
|
||||
offlineCached: 'Discografía guardada',
|
||||
offlineDownloading: 'Descargando… ({{done}}/{{total}} álbumes)',
|
||||
uploadImage: 'Subir imagen del artista',
|
||||
uploadImageError: 'Error al subir imagen',
|
||||
releaseTypes: {
|
||||
album: 'Álbum',
|
||||
ep: 'EP',
|
||||
single: 'Single',
|
||||
compilation: 'Recopilación',
|
||||
live: 'En vivo',
|
||||
soundtrack: 'Banda sonora',
|
||||
remix: 'Remix',
|
||||
other: 'Otro',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
export const artists = {
|
||||
title: 'Artistas',
|
||||
search: 'Buscar…',
|
||||
all: 'Todos',
|
||||
gridView: 'Vista de cuadrícula',
|
||||
listView: 'Vista de lista',
|
||||
imagesOn: 'Imágenes de artistas activadas — puede aumentar la carga de red y sistema',
|
||||
imagesOff: 'Imágenes de artistas desactivadas — mostrando solo iniciales',
|
||||
loadMore: 'Cargar más',
|
||||
notFound: 'No se encontraron artistas.',
|
||||
albumCount_one: '{{count}} Álbum',
|
||||
albumCount_other: '{{count}} Álbumes',
|
||||
selectionCount: '{{count}} seleccionados',
|
||||
select: 'Selección múltiple',
|
||||
startSelect: 'Activar selección múltiple',
|
||||
cancelSelect: 'Cancelar',
|
||||
addToPlaylist: 'Agregar a Lista',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export const changelog = {
|
||||
modalTitle: 'Novedades',
|
||||
dontShowAgain: 'No mostrar de nuevo',
|
||||
close: 'Entendido',
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
export const common = {
|
||||
albums: 'Álbumes',
|
||||
album: 'Álbum',
|
||||
loading: 'Cargando…',
|
||||
loadingMore: 'Cargando…',
|
||||
loadingPlaylists: 'Cargando Listas…',
|
||||
noAlbums: 'No se encontraron álbumes.',
|
||||
downloading: 'Descargando…',
|
||||
downloadZip: 'Descargar (ZIP)',
|
||||
back: 'Volver',
|
||||
cancel: 'Cancelar',
|
||||
save: 'Guardar',
|
||||
delete: 'Eliminar',
|
||||
use: 'Usar',
|
||||
add: 'Agregar',
|
||||
new: 'Nuevo',
|
||||
active: 'Activo',
|
||||
download: 'Descargar',
|
||||
chooseDownloadFolder: 'Elegir carpeta de descarga',
|
||||
noFolderSelected: 'Ninguna carpeta seleccionada',
|
||||
rememberDownloadFolder: 'Recordar esta carpeta',
|
||||
filterGenre: 'Filtro de Género',
|
||||
filterSearchGenres: 'Buscar géneros…',
|
||||
filterNoGenres: 'Ningún género coincide',
|
||||
filterClear: 'Limpiar',
|
||||
favorites: 'Favoritos',
|
||||
favoritesTooltipOff: 'Mostrar solo favoritos',
|
||||
favoritesTooltipOn: 'Mostrar todo',
|
||||
play: 'Reproducir',
|
||||
bulkSelected: '{{count}} seleccionados',
|
||||
clearSelection: 'Limpiar selección',
|
||||
bulkAddToPlaylist: 'Agregar a Lista',
|
||||
bulkRemoveFromPlaylist: 'Quitar de Lista',
|
||||
bulkClear: 'Limpiar selección',
|
||||
updaterAvailable: 'Actualización disponible',
|
||||
updaterVersion: 'v{{version}} está disponible',
|
||||
updaterWebsite: 'Sitio web',
|
||||
updaterModalTitle: 'Nueva Versión Disponible',
|
||||
updaterChangelog: 'Novedades',
|
||||
updaterDownloadBtn: 'Descargar Ahora',
|
||||
updaterSkipBtn: 'Omitir esta Versión',
|
||||
updaterRemindBtn: 'Recordarme Después',
|
||||
updaterDone: 'Descarga completada',
|
||||
updaterShowFolder: 'Mostrar en Carpeta',
|
||||
updaterInstallHint: 'Cierra Psysonic y ejecuta el instalador manualmente.',
|
||||
updaterAurHint: 'Instala la actualización vía AUR:',
|
||||
updaterErrorMsg: 'Error de descarga',
|
||||
updaterRetryBtn: 'Reintentar',
|
||||
durationHoursMinutes: '{{hours}}h {{minutes}}m',
|
||||
durationMinutesOnly: '{{minutes}}m',
|
||||
updaterOpenGitHub: 'Abrir en GitHub',
|
||||
filters: 'Filtros',
|
||||
more: 'más',
|
||||
yearRange: 'Rango de años',
|
||||
clearAll: 'Limpiar todo',
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export const composerDetail = {
|
||||
back: 'Atrás',
|
||||
notFound: 'Compositor no encontrado.',
|
||||
about: 'Sobre este compositor',
|
||||
works: 'Obras',
|
||||
noWorks: 'No se encontraron obras.',
|
||||
workCount_one: '{{count}} obra',
|
||||
workCount_other: '{{count}} obras',
|
||||
shareComposer: 'Compartir compositor',
|
||||
unknownComposer: 'Compositor',
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user