diff --git a/client/components/modals/ListeningSessionModal.vue b/client/components/modals/ListeningSessionModal.vue index ecf00f787..0a6b556e6 100644 --- a/client/components/modals/ListeningSessionModal.vue +++ b/client/components/modals/ListeningSessionModal.vue @@ -81,7 +81,7 @@
{{ $strings.LabelUser }}
-{{ _session.userId }}
+{{ username }}
{{ $strings.LabelMediaPlayer }}
{{ playMethodName }}
@@ -132,6 +132,9 @@ export default { _session() { return this.session || {} }, + username() { + return this._session.user?.username || this._session.userId || '' + }, deviceInfo() { return this._session.deviceInfo || {} }, diff --git a/client/package-lock.json b/client/package-lock.json index 406ef9dbe..d321ce58e 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-client", - "version": "2.26.0", + "version": "2.26.1", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/client/package.json b/client/package.json index 5ebaab543..1aa9b384a 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-client", - "version": "2.26.0", + "version": "2.26.1", "buildNumber": 1, "description": "Self-hosted audiobook and podcast client", "main": "index.js", diff --git a/client/pages/config/sessions.vue b/client/pages/config/sessions.vue index 135922d39..c8a881c17 100644 --- a/client/pages/config/sessions.vue +++ b/client/pages/config/sessions.vue @@ -68,7 +68,7 @@{{ $elapsedPretty(session.timeListening) }}
+{{ $elapsedPrettyLocalized(session.timeListening) }}
{{ $secondsToTimestamp(session.currentTime) }}
diff --git a/client/pages/config/users/_id/index.vue b/client/pages/config/users/_id/index.vue index b48147d3d..34a0fc86c 100644 --- a/client/pages/config/users/_id/index.vue +++ b/client/pages/config/users/_id/index.vue @@ -13,8 +13,10 @@{{ $elapsedPretty(session.timeListening) }}
+{{ $elapsedPrettyLocalized(session.timeListening) }}
{{ $secondsToTimestamp(session.currentTime) }}
diff --git a/client/pages/login.vue b/client/pages/login.vue index 01adadcd5..b6235845a 100644 --- a/client/pages/login.vue +++ b/client/pages/login.vue @@ -191,7 +191,10 @@ export default { this.$store.commit('libraries/setCurrentLibrary', userDefaultLibraryId) this.$store.commit('user/setUser', user) - this.$store.commit('user/setAccessToken', user.accessToken) + // Access token only returned from login, not authorize + if (user.accessToken) { + this.$store.commit('user/setAccessToken', user.accessToken) + } this.$store.dispatch('user/loadUserSettings') }, @@ -225,6 +228,8 @@ export default { this.processing = true + this.$store.commit('user/setAccessToken', token) + return this.$axios .$post('/api/authorize', null, { headers: { @@ -240,6 +245,7 @@ export default { this.showNewAuthSystemAdminMessage = res.user.type === 'admin' || res.user.type === 'root' return false } + this.setUser(res) return true }) diff --git a/client/plugins/utils.js b/client/plugins/utils.js index 8341a9e2d..a03deb41f 100644 --- a/client/plugins/utils.js +++ b/client/plugins/utils.js @@ -37,6 +37,48 @@ Vue.prototype.$elapsedPretty = (seconds, useFullNames = false, useMilliseconds = return `${hours} ${useFullNames ? `hour${hours === 1 ? '' : 's'}` : 'hr'} ${minutes} ${useFullNames ? `minute${minutes === 1 ? '' : 's'}` : 'min'}` } +Vue.prototype.$elapsedPrettyLocalized = (seconds, useFullNames = false, useMilliseconds = false) => { + if (isNaN(seconds) || seconds === null) return '' + + try { + const df = new Intl.DurationFormat(Vue.prototype.$languageCodes.current, { + style: useFullNames ? 'long' : 'short' + }) + + const duration = {} + + if (seconds < 60) { + if (useMilliseconds && seconds < 1) { + duration.milliseconds = Math.floor(seconds * 1000) + } else { + duration.seconds = Math.floor(seconds) + } + } else if (seconds < 3600) { + // 1 hour + duration.minutes = Math.floor(seconds / 60) + } else if (seconds < 86400) { + // 1 day + duration.hours = Math.floor(seconds / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + if (minutes > 0) { + duration.minutes = minutes + } + } else { + duration.days = Math.floor(seconds / 86400) + const hours = Math.floor((seconds % 86400) / 3600) + if (hours > 0) { + duration.hours = hours + } + } + + return df.format(duration) + } catch (error) { + // Handle not supported + console.warn('Intl.DurationFormat not supported, not localizing duration') + return Vue.prototype.$elapsedPretty(seconds, useFullNames, useMilliseconds) + } +} + Vue.prototype.$secondsToTimestamp = (seconds, includeMs = false, alwaysIncludeHours = false) => { if (!seconds) { return alwaysIncludeHours ? '00:00:00' : '0:00' diff --git a/client/strings/de.json b/client/strings/de.json index 0e62a2a05..c455a1203 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -1,5 +1,6 @@ { "ButtonAdd": "Hinzufügen", + "ButtonAddApiKey": "API-Schlüssel hinzufügen", "ButtonAddChapters": "Kapitel hinzufügen", "ButtonAddDevice": "Gerät hinzufügen", "ButtonAddLibrary": "Bibliothek hinzufügen", @@ -20,6 +21,7 @@ "ButtonChooseAFolder": "Wähle einen Ordner", "ButtonChooseFiles": "Wähle eine Datei", "ButtonClearFilter": "Filter löschen", + "ButtonClose": "Schließen", "ButtonCloseFeed": "Feed schließen", "ButtonCloseSession": "Offene Sitzung schließen", "ButtonCollections": "Sammlungen", @@ -119,6 +121,7 @@ "HeaderAccount": "Konto", "HeaderAddCustomMetadataProvider": "Benutzerdefinierten Metadatenanbieter hinzufügen", "HeaderAdvanced": "Erweitert", + "HeaderApiKeys": "API-Schlüssel", "HeaderAppriseNotificationSettings": "Apprise Benachrichtigungseinstellungen", "HeaderAudioTracks": "Audiodateien", "HeaderAudiobookTools": "Hörbuch-Dateiverwaltungswerkzeuge", @@ -162,6 +165,7 @@ "HeaderMetadataOrderOfPrecedence": "Metadaten Rangfolge", "HeaderMetadataToEmbed": "Einzubettende Metadaten", "HeaderNewAccount": "Neues Konto", + "HeaderNewApiKey": "Neuen API-Schlüssel erstellen", "HeaderNewLibrary": "Neue Bibliothek", "HeaderNotificationCreate": "Benachrichtigung erstellen", "HeaderNotificationUpdate": "Benachrichtigung bearbeiten", @@ -206,6 +210,7 @@ "HeaderTableOfContents": "Inhaltsverzeichnis", "HeaderTools": "Werkzeuge", "HeaderUpdateAccount": "Konto aktualisieren", + "HeaderUpdateApiKey": "API-Schlüssel aktualisieren", "HeaderUpdateAuthor": "Autor aktualisieren", "HeaderUpdateDetails": "Details aktualisieren", "HeaderUpdateLibrary": "Bibliothek aktualisieren", @@ -235,6 +240,10 @@ "LabelAllUsersExcludingGuests": "Alle Benutzer außer Gästen", "LabelAllUsersIncludingGuests": "Alle Benutzer und Gäste", "LabelAlreadyInYourLibrary": "Bereits in der Bibliothek", + "LabelApiKeyCreated": "API-Schlüssel \"{0}\" erfolgreich erstellt.", + "LabelApiKeyCreatedDescription": "Speichere den API-Schlüssel an einem sicheren Ort, du wirst ihn später nicht mehr abrufen können.", + "LabelApiKeyUser": "Im Kontext eines Nutzers agieren", + "LabelApiKeyUserDescription": "Dieser API-Schlüssel hat die gleichen Berechtigungen wie der Benutzer, in dessen Namen er erstellt wurde .In den Protokollen wird es aussehen, als ob der Benutzer die Anfrage durchführte.", "LabelApiToken": "API Schlüssel", "LabelAppend": "Anhängen", "LabelAudioBitrate": "Audiobitrate (z. B. 128 kbit/s)", @@ -346,7 +355,11 @@ "LabelExample": "Beispiel", "LabelExpandSeries": "Serie ausklappen", "LabelExpandSubSeries": "Unterserie ausklappen", - "LabelExplicit": "Explizit (Altersbeschränkung)", + "LabelExpired": "Abgelaufen", + "LabelExpiresAt": "Läuft ab am", + "LabelExpiresInSeconds": "Ablauf in (seconds) Sekunden", + "LabelExpiresNever": "Niemals", + "LabelExplicit": "Explizit", "LabelExplicitChecked": "Explicit (Altersbeschränkung) (angehakt)", "LabelExplicitUnchecked": "Not Explicit (Altersbeschränkung) (nicht angehakt)", "LabelExportOPML": "OPML exportieren", @@ -455,6 +468,7 @@ "LabelNewestEpisodes": "Neueste Episoden", "LabelNextBackupDate": "Nächstes Sicherungsdatum", "LabelNextScheduledRun": "Nächster planmäßiger Durchlauf", + "LabelNoApiKeys": "Keine API-Schlüssel vorhanden", "LabelNoCustomMetadataProviders": "Keine benutzerdefinierten Metadata Anbieter", "LabelNoEpisodesSelected": "Keine Episoden ausgewählt", "LabelNotFinished": "Nicht beendet", @@ -544,6 +558,7 @@ "LabelSelectAll": "Alles auswählen", "LabelSelectAllEpisodes": "Alle Episoden auswählen", "LabelSelectEpisodesShowing": "{0} ausgewählte Episoden werden angezeigt", + "LabelSelectUser": "Ausgewählter Benutzer", "LabelSelectUsers": "Benutzer auswählen", "LabelSendEbookToDevice": "E-Buch senden an …", "LabelSequence": "Reihenfolge", @@ -709,6 +724,7 @@ "MessageAppriseDescription": "Um diese Funktion nutzen zu können, musst du eine Instanz von Apprise API laufen haben oder eine API verwenden welche dieselbe Anfragen bearbeiten kann.http://192.168.1.1:8337 läuft, würdest du http://192.168.1.1:8337/notify eingeben.",
"MessageAsinCheck": "Stellen Sie sicher, dass Sie die ASIN aus der richtigen Audible Region verwenden, nicht Amazon.",
"MessageAuthenticationOIDCChangesRestart": "Nach dem Speichern muss der Server neugestartet werden um die OIDC Änderungen zu übernehmen.",
+ "MessageAuthenticationSecurityMessage": "Die Anmeldung wurde abgesichert. Benutzersitzungen werden getrennt, alle Benutzer müssen sich erneut anmelden.",
"MessageBackupsDescription": "In einer Sicherung werden Benutzer, Benutzerfortschritte, Details zu den Bibliotheksobjekten, Servereinstellungen und Bilder welche in /metadata/items & /metadata/authors gespeichert sind gespeichert. Sicherungen enthalten keine Dateien welche in den einzelnen Bibliotheksordnern (Medien-Ordnern) gespeichert sind.",
"MessageBackupsLocationEditNote": "Hinweis: Durch das Aktualisieren des Backup-Speicherorts werden vorhandene Sicherungen nicht verschoben oder geändert",
"MessageBackupsLocationNoEditNote": "Hinweis: Der Sicherungsspeicherort wird über eine Umgebungsvariable festgelegt und kann hier nicht geändert werden.",
@@ -730,6 +746,7 @@
"MessageChaptersNotFound": "Kapitel gefunden nicht",
"MessageCheckingCron": "Überprüfe Cron...",
"MessageConfirmCloseFeed": "Feed wird geschlossen! Bist du dir sicher?",
+ "MessageConfirmDeleteApiKey": "Möchtest du den API-Schlüssel \"{0}\" wirklich entfernen ?",
"MessageConfirmDeleteBackup": "Sicherung für {0} wird gelöscht! Bist du dir sicher?",
"MessageConfirmDeleteDevice": "Möchtest du das Lesegerät „{0}“ wirklich löschen?",
"MessageConfirmDeleteFile": "Datei wird vom System gelöscht! Bist du dir sicher?",
@@ -1001,7 +1018,9 @@
"ToastEpisodeDownloadQueueClearSuccess": "Warteschlange für Episoden-Downloads gelöscht",
"ToastEpisodeUpdateSuccess": "{0} Episoden aktualisiert",
"ToastErrorCannotShare": "Das kann nicht nativ auf diesem Gerät freigegeben werden",
- "ToastFailedToLoadData": "Daten laden fehlgeschlagen",
+ "ToastFailedToCreate": "Fehler beim Erzeugen",
+ "ToastFailedToDelete": "Fehler beim Löschen",
+ "ToastFailedToLoadData": "Fehler beim laden der Daten",
"ToastFailedToMatch": "Fehler beim Abgleich",
"ToastFailedToShare": "Fehler beim Teilen",
"ToastFailedToUpdate": "Aktualisierung ist fehlgeschlagen",
@@ -1032,6 +1051,7 @@
"ToastMustHaveAtLeastOnePath": "Es muss mindestens ein Pfad angegeben werden",
"ToastNameEmailRequired": "Name und E-Mail sind erforderlich",
"ToastNameRequired": "Name ist erforderlich",
+ "ToastNewApiKeyUserError": "Bitte wähle einen Benutzer aus (Pflichtfeld)",
"ToastNewEpisodesFound": "{0} neue Episoden gefunden",
"ToastNewUserCreatedFailed": "Fehler beim erstellen des Accounts: \"{ 0}\"",
"ToastNewUserCreatedSuccess": "Neuer Account erstellt",
diff --git a/client/strings/en-us.json b/client/strings/en-us.json
index 56c29ec1f..d927e3fd0 100644
--- a/client/strings/en-us.json
+++ b/client/strings/en-us.json
@@ -723,6 +723,7 @@
"MessageAddToPlayerQueue": "Add to player queue",
"MessageAppriseDescription": "To use this feature you will need to have an instance of Apprise API running or an api that will handle those same requests. http://192.168.1.1:8337 then you would put http://192.168.1.1:8337/notify.",
"MessageAsinCheck": "Ensure you are using the ASIN from the correct Audible region, not Amazon.",
+ "MessageAuthenticationLegacyTokenWarning": "Legacy API tokens will be removed in the future. Use API Keys instead.",
"MessageAuthenticationOIDCChangesRestart": "Restart your server after saving to apply OIDC changes.",
"MessageAuthenticationSecurityMessage": "Authentication has been improved for security. All users are required to re-login.",
"MessageBackupsDescription": "Backups include users, user progress, library item details, server settings, and images stored in /metadata/items & /metadata/authors. Backups do not include any files stored in your library folders.",
diff --git a/client/strings/hr.json b/client/strings/hr.json
index 267d8a67e..40d9cf5b0 100644
--- a/client/strings/hr.json
+++ b/client/strings/hr.json
@@ -1,5 +1,6 @@
{
"ButtonAdd": "Dodaj",
+ "ButtonAddApiKey": "Dodaj API ključ",
"ButtonAddChapters": "Dodaj poglavlja",
"ButtonAddDevice": "Dodaj uređaj",
"ButtonAddLibrary": "Dodaj knjižnicu",
@@ -20,6 +21,7 @@
"ButtonChooseAFolder": "Odaberi mapu",
"ButtonChooseFiles": "Odaberi datoteke",
"ButtonClearFilter": "Poništi filter",
+ "ButtonClose": "Zatvori",
"ButtonCloseFeed": "Zatvori izvor",
"ButtonCloseSession": "Zatvori otvorenu sesiju",
"ButtonCollections": "Zbirke",
@@ -119,6 +121,7 @@
"HeaderAccount": "Korisnički račun",
"HeaderAddCustomMetadataProvider": "Dodaj prilagođenog pružatelja meta-podataka",
"HeaderAdvanced": "Napredno",
+ "HeaderApiKeys": "API ključevi",
"HeaderAppriseNotificationSettings": "Postavke obavijesti Apprise",
"HeaderAudioTracks": "Zvučni zapisi",
"HeaderAudiobookTools": "Alati za upravljanje datotekama zvučnih knjiga",
@@ -162,6 +165,7 @@
"HeaderMetadataOrderOfPrecedence": "Redoslijed prihvaćanja meta-podataka",
"HeaderMetadataToEmbed": "Meta-podatci za ugradnju",
"HeaderNewAccount": "Novi korisnički račun",
+ "HeaderNewApiKey": "Novi API ključ",
"HeaderNewLibrary": "Nova knjižnica",
"HeaderNotificationCreate": "Izradi obavijest",
"HeaderNotificationUpdate": "Ažuriraj obavijest",
@@ -206,6 +210,7 @@
"HeaderTableOfContents": "Sadržaj",
"HeaderTools": "Alati",
"HeaderUpdateAccount": "Ažuriraj korisnički račun",
+ "HeaderUpdateApiKey": "Ažuriraj API ključ",
"HeaderUpdateAuthor": "Ažuriraj autora",
"HeaderUpdateDetails": "Ažuriraj pojedinosti",
"HeaderUpdateLibrary": "Ažuriraj knjižnicu",
@@ -235,6 +240,10 @@
"LabelAllUsersExcludingGuests": "Svi korisnici osim gostiju",
"LabelAllUsersIncludingGuests": "Svi korisnici uključujući i goste",
"LabelAlreadyInYourLibrary": "Već u vašoj knjižnici",
+ "LabelApiKeyCreated": "API ključ \"{0}\" uspješno izrađen.",
+ "LabelApiKeyCreatedDescription": "Ne zaboravite odmah kopirati API ključ jer ga više nećete moći vidjeti.",
+ "LabelApiKeyUser": "Izvršavaj u ime korisnika",
+ "LabelApiKeyUserDescription": "Ovaj API ključ imat će iste dozvole kao i korisnik u čije ime djeluje. U zapisnicima će biti zabilježeno da je korisnik slao zahtjeve.",
"LabelApiToken": "API Token",
"LabelAppend": "Pridodaj",
"LabelAudioBitrate": "Kvaliteta zvučnog zapisa (npr. 128k)",
@@ -346,7 +355,11 @@
"LabelExample": "Primjer",
"LabelExpandSeries": "Serijal prikaži prošireno",
"LabelExpandSubSeries": "Podserijal prikaži prošireno",
- "LabelExplicit": "Eksplicitni sadržaj",
+ "LabelExpired": "Istekao",
+ "LabelExpiresAt": "Istječe",
+ "LabelExpiresInSeconds": "Istječe za (sekundi)",
+ "LabelExpiresNever": "Nikada",
+ "LabelExplicit": "Eksplicitno",
"LabelExplicitChecked": "Eksplicitni sadržaj (označeno)",
"LabelExplicitUnchecked": "Nije eksplicitni sadržaj (odznačeno)",
"LabelExportOPML": "Izvoz OPML-a",
@@ -455,6 +468,7 @@
"LabelNewestEpisodes": "Najnoviji nastavci",
"LabelNextBackupDate": "Sljedeća izrada sigurnosne kopije",
"LabelNextScheduledRun": "Sljedeće zakazano izvođenje",
+ "LabelNoApiKeys": "Nema API ključeva",
"LabelNoCustomMetadataProviders": "Nema prilagođenih pružatelja meta-podataka",
"LabelNoEpisodesSelected": "Nema odabranih nastavaka",
"LabelNotFinished": "Nije dovršeno",
@@ -544,6 +558,7 @@
"LabelSelectAll": "Označi sve",
"LabelSelectAllEpisodes": "Označi sve nastavke",
"LabelSelectEpisodesShowing": "Prikazujem {0} odabranih nastavaka",
+ "LabelSelectUser": "Odaberite korisnika",
"LabelSelectUsers": "Označi korisnike",
"LabelSendEbookToDevice": "Pošalji e-knjigu …",
"LabelSequence": "Slijed",
@@ -709,6 +724,7 @@
"MessageAppriseDescription": "Da biste se koristili ovom značajkom, treba vam instanca Apprise API-ja ili API koji može rukovati istom vrstom zahtjeva.http://192.168.1.1:8337 trebate upisati http://192.168.1.1:8337/notify.",
"MessageAsinCheck": "Upišite ASIN iz odgovarajuće Audibleove regije, ne s Amazonov.",
"MessageAuthenticationOIDCChangesRestart": "Ponovno pokrenite poslužitelj da biste primijenili OIDC promjene.",
+ "MessageAuthenticationSecurityMessage": "Provjera autentičnosti poboljšana je radi sigurnosti. Svi se korisnici moraju ponovno prijaviti.",
"MessageBackupsDescription": "Sigurnosne kopije sadrže korisnike, korisnikov napredak medija, pojedinosti knjižničke građe, postavke poslužitelja i slike koje se spremaju u /metadata/items & /metadata/authors. Sigurnosne kopije ne sadrže niti jednu datoteku iz mapa knjižnice.",
"MessageBackupsLocationEditNote": "Napomena: Uređivanje lokacije za sigurnosne kopije ne premješta ili mijenja postojeće sigurnosne kopije",
"MessageBackupsLocationNoEditNote": "Napomena: Lokacija za sigurnosne kopije zadana je kroz varijablu okoline i ovdje se ne može izmijeniti.",
@@ -730,6 +746,7 @@
"MessageChaptersNotFound": "Poglavlja nisu pronađena",
"MessageCheckingCron": "Provjeravam cron...",
"MessageConfirmCloseFeed": "Sigurno želite zatvoriti ovaj izvor?",
+ "MessageConfirmDeleteApiKey": "Sigurno želite izbrisati API ključ \"{0}\"?",
"MessageConfirmDeleteBackup": "Sigurno želite izbrisati sigurnosnu kopiju za {0}?",
"MessageConfirmDeleteDevice": "Sigurno želite izbrisati e-čitač \"{0}\"?",
"MessageConfirmDeleteFile": "Ovo će izbrisati datoteke s datotečnog sustava. Jeste li sigurni?",
@@ -757,6 +774,7 @@
"MessageConfirmRemoveAuthor": "Sigurno želite ukloniti autora \"{0}\"?",
"MessageConfirmRemoveCollection": "Sigurno želite obrisati kolekciju \"{0}\"?",
"MessageConfirmRemoveEpisode": "Sigurno želite ukloniti nastavak \"{0}\"?",
+ "MessageConfirmRemoveEpisodeNote": "Napomena: Ova funkcija neće izbrisati zvučnu datoteku ukoliko ne uključite opciju \"Izbriši datoteku zauvijek\"",
"MessageConfirmRemoveEpisodes": "Sigurno želite ukloniti {0} nastavaka?",
"MessageConfirmRemoveListeningSessions": "Sigurno želite ukloniti {0} sesija slušanja?",
"MessageConfirmRemoveMetadataFiles": "Sigurno želite ukloniti sve datoteke metadata.{0} u mapama vaših knjižničkih stavki?",
@@ -1000,6 +1018,8 @@
"ToastEpisodeDownloadQueueClearSuccess": "Redoslijed preuzimanja nastavaka očišćen",
"ToastEpisodeUpdateSuccess": "{0} nastavak/a ažurirano",
"ToastErrorCannotShare": "Dijeljenje na ovaj uređaj nije moguće",
+ "ToastFailedToCreate": "Izrada nije uspjela",
+ "ToastFailedToDelete": "Brisanje nije uspjelo",
"ToastFailedToLoadData": "Učitavanje podataka nije uspjelo",
"ToastFailedToMatch": "Nije prepoznato",
"ToastFailedToShare": "Dijeljenje nije uspjelo",
@@ -1031,6 +1051,7 @@
"ToastMustHaveAtLeastOnePath": "Mora postojati barem jedna putanja",
"ToastNameEmailRequired": "Ime i adresa e-pošte su obavezni",
"ToastNameRequired": "Ime je obavezno",
+ "ToastNewApiKeyUserError": "Morate odabrati korisnika",
"ToastNewEpisodesFound": "pronađeno {0} novih nastavaka",
"ToastNewUserCreatedFailed": "Račun \"{0}\" nije uspješno izrađen",
"ToastNewUserCreatedSuccess": "Novi račun izrađen",
diff --git a/client/strings/pl.json b/client/strings/pl.json
index 7248ae966..451112bbd 100644
--- a/client/strings/pl.json
+++ b/client/strings/pl.json
@@ -1,5 +1,6 @@
{
"ButtonAdd": "Dodaj",
+ "ButtonAddApiKey": "Dodaj klucz API",
"ButtonAddChapters": "Dodaj rozdziały",
"ButtonAddDevice": "Dodaj urządzenie",
"ButtonAddLibrary": "Dodaj bibliotekę",
@@ -20,6 +21,7 @@
"ButtonChooseAFolder": "Wybierz folder",
"ButtonChooseFiles": "Wybierz pliki",
"ButtonClearFilter": "Wyczyść filtr",
+ "ButtonClose": "Zamknij",
"ButtonCloseFeed": "Zamknij kanał",
"ButtonCloseSession": "Zamknij otwartą sesję",
"ButtonCollections": "Kolekcje",
@@ -119,6 +121,7 @@
"HeaderAccount": "Konto",
"HeaderAddCustomMetadataProvider": "Dodaj niestandardowego dostawcę metadanych",
"HeaderAdvanced": "Zaawansowane",
+ "HeaderApiKeys": "Klucze API",
"HeaderAppriseNotificationSettings": "Ustawienia powiadomień Apprise",
"HeaderAudioTracks": "Ścieżki audio",
"HeaderAudiobookTools": "Narzędzia do zarządzania audiobookami",
@@ -162,6 +165,7 @@
"HeaderMetadataOrderOfPrecedence": "Kolejność metadanych",
"HeaderMetadataToEmbed": "Metadane do osadzenia",
"HeaderNewAccount": "Nowe konto",
+ "HeaderNewApiKey": "Nowy klucz API",
"HeaderNewLibrary": "Nowa biblioteka",
"HeaderNotificationCreate": "Utwórz powiadomienie",
"HeaderNotificationUpdate": "Zaktualizuj powiadomienie",
@@ -206,6 +210,7 @@
"HeaderTableOfContents": "Spis treści",
"HeaderTools": "Narzędzia",
"HeaderUpdateAccount": "Zaktualizuj konto",
+ "HeaderUpdateApiKey": "Aktualizuj klucz API",
"HeaderUpdateAuthor": "Zaktualizuj autorów",
"HeaderUpdateDetails": "Zaktualizuj szczegóły",
"HeaderUpdateLibrary": "Zaktualizuj bibliotekę",
@@ -235,6 +240,7 @@
"LabelAllUsersExcludingGuests": "Wszyscy użytkownicy z wyłączeniem gości",
"LabelAllUsersIncludingGuests": "Wszyscy użytkownicy, łącznie z gośćmi",
"LabelAlreadyInYourLibrary": "Już istnieje w twojej bibliotece",
+ "LabelApiKeyCreated": "Klucz API \"{0}\" został pomyślnie utworzony.",
"LabelApiToken": "API Token",
"LabelAppend": "Dołącz",
"LabelAudioBitrate": "Audio Bitrate (np. 128k)",
@@ -324,6 +330,10 @@
"LabelEmbeddedCover": "Wbudowana okładka",
"LabelEnable": "Włącz",
"LabelEncodingBackupLocation": "Kopia zapasowa twoich oryginalnych plików audio będzie się znajdować w:",
+ "LabelEncodingChaptersNotEmbedded": "W audiobookach wielościeżkowych rozdziały nie są osadzone.",
+ "LabelEncodingClearItemCache": "Pamiętaj o okresowym czyszczeniu pamięci podręcznej elementów.",
+ "LabelEncodingFinishedM4B": "Ukończony plik M4B zostanie umieszczony w folderze audiobooka pod adresem:",
+ "LabelEncodingInfoEmbedded": "Metadane zostaną osadzone w ścieżkach audio w folderze z audiobookiem.",
"LabelEnd": "Zakończ",
"LabelEndOfChapter": "Koniec rozdziału",
"LabelEpisode": "Odcinek",
diff --git a/client/strings/ru.json b/client/strings/ru.json
index 54ed4abee..3971365c3 100644
--- a/client/strings/ru.json
+++ b/client/strings/ru.json
@@ -1,5 +1,6 @@
{
"ButtonAdd": "Добавить",
+ "ButtonAddApiKey": "Добавить API ключ",
"ButtonAddChapters": "Добавить главы",
"ButtonAddDevice": "Добавить устройство",
"ButtonAddLibrary": "Добавить библиотеку",
@@ -20,6 +21,7 @@
"ButtonChooseAFolder": "Выбор папки",
"ButtonChooseFiles": "Выбор файлов",
"ButtonClearFilter": "Очистить фильтр",
+ "ButtonClose": "Закрыть",
"ButtonCloseFeed": "Закрыть канал",
"ButtonCloseSession": "Закрыть открытый сеанс",
"ButtonCollections": "Коллекции",
@@ -119,6 +121,7 @@
"HeaderAccount": "Учетная запись",
"HeaderAddCustomMetadataProvider": "Добавление пользовательского поставщика метаданных",
"HeaderAdvanced": "Дополнительно",
+ "HeaderApiKeys": "API ключи",
"HeaderAppriseNotificationSettings": "Настройки оповещений",
"HeaderAudioTracks": "Аудио треки",
"HeaderAudiobookTools": "Инструменты файлов аудиокниг",
@@ -162,6 +165,7 @@
"HeaderMetadataOrderOfPrecedence": "Порядок приоритета метаданных",
"HeaderMetadataToEmbed": "Метаинформация для встраивания",
"HeaderNewAccount": "Новая учетная запись",
+ "HeaderNewApiKey": "Новый API ключ",
"HeaderNewLibrary": "Новая библиотека",
"HeaderNotificationCreate": "Создать уведомление",
"HeaderNotificationUpdate": "Уведомление об обновлении",
@@ -206,6 +210,7 @@
"HeaderTableOfContents": "Содержание",
"HeaderTools": "Инструменты",
"HeaderUpdateAccount": "Обновить учетную запись",
+ "HeaderUpdateApiKey": "Обновить API ключ",
"HeaderUpdateAuthor": "Обновить автора",
"HeaderUpdateDetails": "Обновить детали",
"HeaderUpdateLibrary": "Обновить библиотеку",
@@ -235,6 +240,10 @@
"LabelAllUsersExcludingGuests": "Все пользователи, кроме гостей",
"LabelAllUsersIncludingGuests": "Все пользователи, включая гостей",
"LabelAlreadyInYourLibrary": "Уже в Вашей библиотеке",
+ "LabelApiKeyCreated": "API ключ \"{0}\" успешно создан.",
+ "LabelApiKeyCreatedDescription": "Обязательно скопируйте API-ключ сейчас, так как вы больше не сможете его увидеть.",
+ "LabelApiKeyUser": "Управление от пользователя",
+ "LabelApiKeyUserDescription": "Этот API-ключ будет иметь те же права доступа, что и пользователь, от имени которого он действует. В логах это будет отображаться так же, как если бы пользователь отправлял запрос.",
"LabelApiToken": "Токен API",
"LabelAppend": "Добавить",
"LabelAudioBitrate": "Битрейт (напр. 128k)",
@@ -346,6 +355,10 @@
"LabelExample": "Пример",
"LabelExpandSeries": "Развернуть серию",
"LabelExpandSubSeries": "Развернуть подсерию",
+ "LabelExpired": "Истекший",
+ "LabelExpiresAt": "Истекает в",
+ "LabelExpiresInSeconds": "Истекает через (seconds)",
+ "LabelExpiresNever": "Никогда",
"LabelExplicit": "18+",
"LabelExplicitChecked": "18+ (отмечено)",
"LabelExplicitUnchecked": "+18 (не отмечено)",
@@ -455,6 +468,7 @@
"LabelNewestEpisodes": "Новые эпизоды",
"LabelNextBackupDate": "Следующая дата бэкапирования",
"LabelNextScheduledRun": "Следущий запланированный запуск",
+ "LabelNoApiKeys": "API ключи отсутствуют",
"LabelNoCustomMetadataProviders": "Нет пользовательских поставщиков метаданных",
"LabelNoEpisodesSelected": "Эпизоды не выбраны",
"LabelNotFinished": "Не завершено",
@@ -544,6 +558,7 @@
"LabelSelectAll": "Выбрать все",
"LabelSelectAllEpisodes": "Выбрать все эпизоды",
"LabelSelectEpisodesShowing": "Выберите {0} эпизодов для показа",
+ "LabelSelectUser": "Выбрать пользователя",
"LabelSelectUsers": "Выбор пользователей",
"LabelSendEbookToDevice": "Отправить e-книгу в...",
"LabelSequence": "Последовательность",
@@ -709,6 +724,7 @@
"MessageAppriseDescription": "Для использования этой функции необходимо иметь запущенный экземпляр Apprise API или api которое обрабатывает те же самые запросы. http://192.168.1.1:8337 тогда нужно указать http://192.168.1.1:8337/notify.",
"MessageAsinCheck": "Убедитесь, что вы используете ASIN из правильной региональной зоны Audible, а не из Amazon.",
"MessageAuthenticationOIDCChangesRestart": "Перезапустите ваш сервер после сохранения для применения изменений в OIDC.",
+ "MessageAuthenticationSecurityMessage": "В целях безопасности была улучшена аутентификация. Всем пользователям необходимо повторно войти в систему.",
"MessageBackupsDescription": "Бэкап включает пользователей, прогресс пользователей, данные элементов библиотеки, настройки сервера и изображения хранящиеся в /metadata/items и /metadata/authors. Бэкапы НЕ сохраняют файлы из папок библиотек.",
"MessageBackupsLocationEditNote": "Примечание: Обновление местоположения резервной копии не приведет к перемещению или изменению существующих резервных копий",
"MessageBackupsLocationNoEditNote": "Примечание: Местоположение резервного копирования задается с помощью переменной среды и не может быть изменено здесь.",
@@ -730,6 +746,7 @@
"MessageChaptersNotFound": "Главы не найденны",
"MessageCheckingCron": "Проверка cron...",
"MessageConfirmCloseFeed": "Вы уверены, что хотите закрыть этот канал?",
+ "MessageConfirmDeleteApiKey": "Вы уверены, что хотите удалить API ключ \"{0}\"?",
"MessageConfirmDeleteBackup": "Вы уверены, что хотите удалить бэкап для {0}?",
"MessageConfirmDeleteDevice": "Вы уверены, что хотите удалить устройство для чтения электронных книг \"{0}\"?",
"MessageConfirmDeleteFile": "Это удалит файл из Вашей файловой системы. Вы уверены?",
@@ -757,6 +774,7 @@
"MessageConfirmRemoveAuthor": "Вы уверены, что хотите удалить автора \"{0}\"?",
"MessageConfirmRemoveCollection": "Вы уверены, что хотите удалить коллекцию \"{0}\"?",
"MessageConfirmRemoveEpisode": "Вы уверены, что хотите удалить эпизод \"{0}\"?",
+ "MessageConfirmRemoveEpisodeNote": "Примечание: Это не приведет к удалению аудиофайла, если не включить опцию \"Жесткое удаление файла\"",
"MessageConfirmRemoveEpisodes": "Вы уверены, что хотите удалить {0} эпизодов?",
"MessageConfirmRemoveListeningSessions": "Вы уверены, что хотите удалить {0} сеансов прослушивания?",
"MessageConfirmRemoveMetadataFiles": "Вы уверены, что хотите удалить все файлы metadata. {0} файлов из папок элементов вашей библиотеки?",
@@ -1000,6 +1018,8 @@
"ToastEpisodeDownloadQueueClearSuccess": "Очередь загрузки эпизода очищена",
"ToastEpisodeUpdateSuccess": "{0 эпизодов обновлено",
"ToastErrorCannotShare": "Невозможно предоставить общий доступ на этом устройстве",
+ "ToastFailedToCreate": "Не удалось создать",
+ "ToastFailedToDelete": "Не удалось удалить",
"ToastFailedToLoadData": "Не удалось загрузить данные",
"ToastFailedToMatch": "Не удалось найти совпадения",
"ToastFailedToShare": "Не удалось поделиться",
@@ -1031,6 +1051,7 @@
"ToastMustHaveAtLeastOnePath": "Должен быть хотя бы один путь",
"ToastNameEmailRequired": "Имя и адрес электронной почты обязательны",
"ToastNameRequired": "Имя обязательно для заполнения",
+ "ToastNewApiKeyUserError": "Необходимо выбрать пользователя",
"ToastNewEpisodesFound": "{0} новых эпизодов найдено",
"ToastNewUserCreatedFailed": "Не удалось создать учетную запись: \"{0}\"",
"ToastNewUserCreatedSuccess": "Новая учетная запись создана",
diff --git a/client/strings/sv.json b/client/strings/sv.json
index 4fdc400ff..17254a50e 100644
--- a/client/strings/sv.json
+++ b/client/strings/sv.json
@@ -1,5 +1,6 @@
{
"ButtonAdd": "Lägg till",
+ "ButtonAddApiKey": "Addera API-nyckel",
"ButtonAddChapters": "Lägg till kapitel",
"ButtonAddDevice": "Lägg till enhet",
"ButtonAddLibrary": "Lägg till bibliotek",
@@ -20,6 +21,7 @@
"ButtonChooseAFolder": "Välj en mapp",
"ButtonChooseFiles": "Välj filer",
"ButtonClearFilter": "Rensa filter",
+ "ButtonClose": "Stäng",
"ButtonCloseFeed": "Stäng flöde",
"ButtonCloseSession": "Stäng öppen session",
"ButtonCollections": "Samlingar",
@@ -119,6 +121,7 @@
"HeaderAccount": "Konto",
"HeaderAddCustomMetadataProvider": "Addera egen källa för metadata",
"HeaderAdvanced": "Avancerad",
+ "HeaderApiKeys": "API-nyckel",
"HeaderAppriseNotificationSettings": "Inställningar av meddelanden med Apprise",
"HeaderAudioTracks": "Ljudfiler",
"HeaderAudiobookTools": "Hantering av ljudboksfiler",
@@ -162,6 +165,7 @@
"HeaderMetadataOrderOfPrecedence": "Prioriteringsordning vid inläsning av metadata",
"HeaderMetadataToEmbed": "Metadata som kommer att adderas",
"HeaderNewAccount": "Nytt konto",
+ "HeaderNewApiKey": "Ny API-nyckel",
"HeaderNewLibrary": "Nytt bibliotek",
"HeaderNotificationCreate": "Addera ett meddelande",
"HeaderNotificationUpdate": "Uppdateringsnotis",
@@ -205,6 +209,7 @@
"HeaderTableOfContents": "Innehållsförteckning",
"HeaderTools": "Verktyg",
"HeaderUpdateAccount": "Uppdatera konto",
+ "HeaderUpdateApiKey": "Uppdatera API-nyckel",
"HeaderUpdateAuthor": "Uppdatera författare",
"HeaderUpdateDetails": "Uppdatera detaljer om boken",
"HeaderUpdateLibrary": "Uppdatera bibliotek",
@@ -234,6 +239,9 @@
"LabelAllUsersExcludingGuests": "Alla användare utom gäster",
"LabelAllUsersIncludingGuests": "Alla användare inklusive gäster",
"LabelAlreadyInYourLibrary": "Finns redan i samlingen",
+ "LabelApiKeyCreated": "API-nyckel \"{0}\" har adderats.",
+ "LabelApiKeyCreatedDescription": "Se till att kopiera API-nyckeln omedelbart eftersom du inte kommer att kunna se den igen.",
+ "LabelApiKeyUserDescription": "Denna API-nyckel kommer att ha samma behörigheter som användaren den agerar på uppdrag av. Detta kommer att visas på samma sätt i loggarna som om användaren gjorde begäran.",
"LabelApiToken": "API-token",
"LabelAppend": "Lägg till",
"LabelAudioBitrate": "Bitrate (t.ex. 128k)",
@@ -345,7 +353,11 @@
"LabelExample": "Exempel",
"LabelExpandSeries": "Expandera serier",
"LabelExpandSubSeries": "Expandera Underserier",
- "LabelExplicit": "Explicit version",
+ "LabelExpired": "Upphört",
+ "LabelExpiresAt": "Gäller till och med",
+ "LabelExpiresInSeconds": "Upphör om (sekunder)",
+ "LabelExpiresNever": "Aldrig",
+ "LabelExplicit": "Bestämd",
"LabelExplicitChecked": "Explicit version (markerad)",
"LabelExplicitUnchecked": "Ej Explicit version (ej markerad)",
"LabelExportOPML": "Exportera OPML-information",
@@ -454,6 +466,7 @@
"LabelNewestEpisodes": "Senaste avsnitten",
"LabelNextBackupDate": "Nästa tillfälle för säkerhetskopiering",
"LabelNextScheduledRun": "Nästa schemalagda körning",
+ "LabelNoApiKeys": "Ingen API-nyckel",
"LabelNoCustomMetadataProviders": "Ingen egen källa för metadata",
"LabelNoEpisodesSelected": "Inga avsnitt har valts",
"LabelNotFinished": "Ej avslutad",
@@ -470,11 +483,15 @@
"LabelNotificationsMaxQueueSizeHelp": "Evenemang är begränsade till att utlösa ett per sekund. Evenemang kommer att ignoreras om kön är full. Detta förhindrar aviseringsspam.",
"LabelNumberOfBooks": "Antal böcker",
"LabelNumberOfEpisodes": "# av Avsnitt",
+ "LabelOpenIDAdvancedPermsClaimDescription": "Namn på OpenID-anspråket som innehåller avancerade behörigheter för användaråtgärder i applikationen, vilka gäller för icke-administratörsroller (om konfigurerat). Om anspråket saknas i svaret kommer åtkomst till ABS att nekas. Om ett enskilt alternativ saknas kommer det att behandlas som falskt. Se till att identitetsleverantörens anspråk matchar den förväntade strukturen:",
+ "LabelOpenIDClaims": "Lämna följande alternativ tomma för att inaktivera avancerad grupp- och behörighetstilldelning, och tilldela då automatiskt gruppen 'Användare'.",
+ "LabelOpenIDGroupClaimDescription": "Namn på OpenID-anspråket som innehåller en lista över användarens grupper. Vanligtvis kallat groups. Om det är konfigurerat kommer programmet automatiskt att tilldela roller baserat på användarens gruppmedlemskap, förutsatt att dessa grupper namnges utan att skiftlägeskänsligt tolkas som 'admin', 'user' eller 'guest' i anspråket. Anspråket ska innehålla en lista, och om en användare tillhör flera grupper kommer programmet att tilldela den roll som motsvarar den högsta åtkomstnivån. Om ingen grupp matchar kommer åtkomst att nekas.",
"LabelOpenRSSFeed": "Öppna RSS-flöde",
"LabelOverwrite": "Skriv över",
"LabelPaginationPageXOfY": "Sida {0} av {1}",
"LabelPassword": "Lösenord",
"LabelPath": "Sökväg",
+ "LabelPermanent": "Permanent",
"LabelPermissionsAccessAllLibraries": "Kan komma åt alla bibliotek",
"LabelPermissionsAccessAllTags": "Kan komma åt alla taggar",
"LabelPermissionsAccessExplicitContent": "Kan komma åt explicit version",
@@ -486,6 +503,7 @@
"LabelPersonalYearReview": "En sammanställning av ditt år, sidan {0}",
"LabelPhotoPathURL": "Bildsökväg/URL",
"LabelPlayMethod": "Spelläge",
+ "LabelPlaybackRateIncrementDecrement": "Uppspelningshastighetsökning/minskning",
"LabelPlayerChapterNumberMarker": "{0} av {1}",
"LabelPlaylists": "Spellistor",
"LabelPodcast": "Podcast",
@@ -524,6 +542,7 @@
"LabelReleaseDate": "Utgivningsdatum",
"LabelRemoveAllMetadataAbs": "Radera alla 'metadata.abs' filer",
"LabelRemoveAllMetadataJson": "Radera alla 'metadata.json' filer",
+ "LabelRemoveAudibleBranding": "Ta bort Audible intro och outro från kapitel",
"LabelRemoveCover": "Ta bort omslag",
"LabelRemoveMetadataFile": "Radera metadata-filer i alla mappar i biblioteket",
"LabelRemoveMetadataFileHelp": "Radera alla 'metadata.json' och 'metadata.abs' filer i dina {0} mappar.",
@@ -536,6 +555,7 @@
"LabelSelectAll": "Välj alla",
"LabelSelectAllEpisodes": "Välj alla avsnitt",
"LabelSelectEpisodesShowing": "Välj {0} avsnitt som visas",
+ "LabelSelectUser": "Välj användare",
"LabelSelectUsers": "Välj användare",
"LabelSendEbookToDevice": "Skicka e-bok till...",
"LabelSequence": "Ordningsnummer",
@@ -694,6 +714,7 @@
"LabelYourProgress": "Framsteg",
"MessageAddToPlayerQueue": "Lägg till i spellistan",
"MessageAppriseDescription": "För att använda den här funktionen behöver du ha en instans av Apprise API igång eller en API som hanterar dessa begäranden. http://192.168.1.1:8337, bör du ange http://192.168.1.1:8337/notify.",
+ "MessageAuthenticationSecurityMessage": "Identifieringen av användare har förbättrats av säkerhetsskäl. Alla användare måste därför logga in på nytt.",
"MessageBackupsDescription": "Säkerhetskopior inkluderar användare, användarnas framsteg, biblioteksobjekt,/metadata/items & /metadata/authors.http://192.168.1.1:8337, то необхідно вказати адресу http://192.168.1.1:8337/notify.",
"MessageAsinCheck": "Переконайтесь, що ви використовуєте ASIN з правильної регіональної Audible зони, а не з Amazon.",
"MessageAuthenticationOIDCChangesRestart": "Перезавантажте сервер після збереження, щоб застосувати зміни OIDC.",
+ "MessageAuthenticationSecurityMessage": "Автентифікацію покращено для безпеки. Усім користувачам потрібно повторно увійти в систему.",
"MessageBackupsDescription": "Резервні копії містять користувачів, прогрес, подробиці елементів бібліотеки, налаштування сервера та зображення з /metadata/items та /metadata/authors. Резервні копії не містять жодних файлів з тек бібліотеки.",
"MessageBackupsLocationEditNote": "Примітка: оновлення розташування резервної копії не переносить та не змінює існуючих копій",
"MessageBackupsLocationNoEditNote": "Примітка: розташування резервної копії встановлюється за допомогою змінної середовища та не може бути змінене тут.",
@@ -730,6 +746,7 @@
"MessageChaptersNotFound": "Розділи не знайдені",
"MessageCheckingCron": "Перевірка планувальника...",
"MessageConfirmCloseFeed": "Ви дійсно бажаєте закрити цей канал?",
+ "MessageConfirmDeleteApiKey": "Ви впевнені, що хочете видалити ключ API? \"{0}\"?",
"MessageConfirmDeleteBackup": "Ви дійсно бажаєте видалити резервну копію за {0}?",
"MessageConfirmDeleteDevice": "Ви впевнені, що хочете видалити пристрій для читання \"{0}\"?",
"MessageConfirmDeleteFile": "Файл буде видалено з вашої файлової системи. Ви впевнені?",
@@ -819,7 +836,7 @@
"MessageNoItems": "Елементи відсутні",
"MessageNoItemsFound": "Елементів не знайдено",
"MessageNoListeningSessions": "Сеанси прослуховування відсутні",
- "MessageNoLogs": "Немає журнали",
+ "MessageNoLogs": "Немає журналів",
"MessageNoMediaProgress": "Прогрес відсутній",
"MessageNoNotifications": "Сповіщення відсутні",
"MessageNoPodcastFeed": "Некоректний подкаст: немає каналу",
@@ -1001,6 +1018,8 @@
"ToastEpisodeDownloadQueueClearSuccess": "Чергу на скачування епізодів очищено",
"ToastEpisodeUpdateSuccess": "{0} епізодів оновлено",
"ToastErrorCannotShare": "Не можна типово поширити на цей пристрій",
+ "ToastFailedToCreate": "Не вдалося створити",
+ "ToastFailedToDelete": "Не вдалося видалити",
"ToastFailedToLoadData": "Не вдалося завантажити дані",
"ToastFailedToMatch": "Не вдалося знайти відповідність",
"ToastFailedToShare": "Не вдалося поділитися",
@@ -1032,6 +1051,7 @@
"ToastMustHaveAtLeastOnePath": "Повинен бути хоча б один шлях",
"ToastNameEmailRequired": "Ім'я та електронна пошта обов'язкові",
"ToastNameRequired": "Ім'я обов'язкове",
+ "ToastNewApiKeyUserError": "Потрібно вибрати користувача",
"ToastNewEpisodesFound": "{0} нових епізодів знайдено",
"ToastNewUserCreatedFailed": "Не вдалося створити акаунт: \"{0}\"",
"ToastNewUserCreatedSuccess": "Новий акаунт створено",
@@ -1066,7 +1086,7 @@
"ToastProviderRemoveSuccess": "Постачальник видалений",
"ToastRSSFeedCloseFailed": "Не вдалося закрити RSS-канал",
"ToastRSSFeedCloseSuccess": "RSS-канал закрито",
- "ToastRemoveFailed": "Не вдалося видалити",
+ "ToastRemoveFailed": "Не вдалося вилучити",
"ToastRemoveItemFromCollectionFailed": "Не вдалося видалити елемент із добірки",
"ToastRemoveItemFromCollectionSuccess": "Елемент видалено з добірки",
"ToastRemoveItemsWithIssuesFailed": "Не вдалося видалити елементи бібліотеки з проблемами",
diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json
index 36ec12708..84ae64a9f 100644
--- a/client/strings/zh-cn.json
+++ b/client/strings/zh-cn.json
@@ -1,5 +1,6 @@
{
"ButtonAdd": "添加",
+ "ButtonAddApiKey": "添加 API 密钥",
"ButtonAddChapters": "添加章节",
"ButtonAddDevice": "添加设备",
"ButtonAddLibrary": "添加库",
@@ -20,6 +21,7 @@
"ButtonChooseAFolder": "选择文件夹",
"ButtonChooseFiles": "选择文件",
"ButtonClearFilter": "清除过滤器",
+ "ButtonClose": "关闭",
"ButtonCloseFeed": "关闭源",
"ButtonCloseSession": "关闭活动会话",
"ButtonCollections": "收藏",
@@ -119,6 +121,7 @@
"HeaderAccount": "帐户",
"HeaderAddCustomMetadataProvider": "添加自定义元数据提供商",
"HeaderAdvanced": "高级",
+ "HeaderApiKeys": "API 密钥",
"HeaderAppriseNotificationSettings": "测试通知设置",
"HeaderAudioTracks": "音轨",
"HeaderAudiobookTools": "有声读物文件管理工具",
@@ -162,12 +165,13 @@
"HeaderMetadataOrderOfPrecedence": "元数据优先级",
"HeaderMetadataToEmbed": "嵌入元数据",
"HeaderNewAccount": "新建帐户",
+ "HeaderNewApiKey": "新建 API 密钥",
"HeaderNewLibrary": "新建媒体库",
"HeaderNotificationCreate": "创建通知",
"HeaderNotificationUpdate": "更新通知",
"HeaderNotifications": "通知",
"HeaderOpenIDConnectAuthentication": "OpenID 连接身份验证",
- "HeaderOpenListeningSessions": "打开收听会话",
+ "HeaderOpenListeningSessions": "活动中会话",
"HeaderOpenRSSFeed": "打开 RSS 源",
"HeaderOtherFiles": "其他文件",
"HeaderPasswordAuthentication": "密码认证",
@@ -206,6 +210,7 @@
"HeaderTableOfContents": "目录",
"HeaderTools": "工具",
"HeaderUpdateAccount": "更新帐户",
+ "HeaderUpdateApiKey": "更新 API 密钥",
"HeaderUpdateAuthor": "更新作者",
"HeaderUpdateDetails": "更新详情",
"HeaderUpdateLibrary": "更新媒体库",
@@ -235,6 +240,10 @@
"LabelAllUsersExcludingGuests": "除访客外的所有用户",
"LabelAllUsersIncludingGuests": "包括访客的所有用户",
"LabelAlreadyInYourLibrary": "已存在你的库中",
+ "LabelApiKeyCreated": "API 密钥 \"{0}\" 创建成功。",
+ "LabelApiKeyCreatedDescription": "请确保现在就复制 API 密钥,之后将无法再次查看。",
+ "LabelApiKeyUser": "代用户操作",
+ "LabelApiKeyUserDescription": "此 API 密钥将具有与其代理的用户相同的权限。在日志中,其请求将被视为由该用户直接发出。",
"LabelApiToken": "API 令牌",
"LabelAppend": "附加",
"LabelAudioBitrate": "音频比特率 (例如: 128k)",
@@ -346,6 +355,10 @@
"LabelExample": "示例",
"LabelExpandSeries": "展开系列",
"LabelExpandSubSeries": "展开子系列",
+ "LabelExpired": "已过期",
+ "LabelExpiresAt": "过期时间",
+ "LabelExpiresInSeconds": "有效期(秒)",
+ "LabelExpiresNever": "从不",
"LabelExplicit": "含成人内容",
"LabelExplicitChecked": "成人内容(已核实)",
"LabelExplicitUnchecked": "无成人内容 (未核实)",
@@ -455,6 +468,7 @@
"LabelNewestEpisodes": "最新剧集",
"LabelNextBackupDate": "下次备份日期",
"LabelNextScheduledRun": "下次任务运行",
+ "LabelNoApiKeys": "无 API 密钥",
"LabelNoCustomMetadataProviders": "没有自定义元数据提供商",
"LabelNoEpisodesSelected": "未选择任何剧集",
"LabelNotFinished": "未听完",
@@ -544,6 +558,7 @@
"LabelSelectAll": "全选",
"LabelSelectAllEpisodes": "选择所有剧集",
"LabelSelectEpisodesShowing": "选择正在播放的 {0} 剧集",
+ "LabelSelectUser": "选择用户",
"LabelSelectUsers": "选择用户",
"LabelSendEbookToDevice": "发送电子书到...",
"LabelSequence": "序列",
@@ -610,12 +625,12 @@
"LabelStart": "开始",
"LabelStartTime": "开始时间",
"LabelStarted": "开始于",
- "LabelStartedAt": "从这开始",
+ "LabelStartedAt": "收听始于",
"LabelStatsAudioTracks": "音轨",
"LabelStatsAuthors": "作者",
"LabelStatsBestDay": "单日最高",
"LabelStatsDailyAverage": "每日平均值",
- "LabelStatsDays": "连续收听",
+ "LabelStatsDays": "连续",
"LabelStatsDaysListened": "收听天数",
"LabelStatsHours": "小时",
"LabelStatsInARow": "天",
@@ -709,6 +724,7 @@
"MessageAppriseDescription": "要使用此功能,你需要运行一个 Apprise API 实例或一个可以处理这些相同请求的 API. http://192.168.1.1:8337, 那么你可以输入 http://192.168.1.1:8337/notify.",
"MessageAsinCheck": "确保你使用的 ASIN 来自正确的 Audible 地区, 而不是亚马逊.",
"MessageAuthenticationOIDCChangesRestart": "保存后重新启动服务器以应用 OIDC 更改.",
+ "MessageAuthenticationSecurityMessage": "身份验证安全性已增强,所有用户都需要重新登录。",
"MessageBackupsDescription": "备份包括用户, 用户进度, 媒体库项目详细信息, 服务器设置和图像, 存储在 /metadata/items & /metadata/authors. 备份不包括存储在你的媒体库文件夹中的任何文件.",
"MessageBackupsLocationEditNote": "注意: 更新备份位置不会移动或修改现有备份",
"MessageBackupsLocationNoEditNote": "注意: 备份位置是通过环境变量设置的, 不能在此处更改.",
@@ -730,6 +746,7 @@
"MessageChaptersNotFound": "未找到章节",
"MessageCheckingCron": "检查计划任务...",
"MessageConfirmCloseFeed": "你确定要关闭此订阅源吗?",
+ "MessageConfirmDeleteApiKey": "你确定要删除 API 密钥 \"{0}\" 吗?",
"MessageConfirmDeleteBackup": "你确定要删除备份 {0}?",
"MessageConfirmDeleteDevice": "你确定要删除电子阅读器设备 \"{0}\" 吗?",
"MessageConfirmDeleteFile": "这将从文件系统中删除该文件. 你确定吗?",
@@ -788,7 +805,7 @@
"MessageInvalidAsin": "无效的 ASIN",
"MessageItemsSelected": "已选定 {0} 个项目",
"MessageItemsUpdated": "已更新 {0} 个项目",
- "MessageJoinUsOn": "加入我们",
+ "MessageJoinUsOn": "加入我们的",
"MessageLoading": "正在加载...",
"MessageLoadingFolders": "加载文件夹...",
"MessageLogsDescription": "日志以 JSON 文件形式存储在 /metadata/logs 目录中. 崩溃日志存储在 /metadata/logs/crash_logs.txt 目录中.",
@@ -849,12 +866,12 @@
"MessageRemoveEpisodes": "移除 {0} 剧集",
"MessageRemoveFromPlayerQueue": "从播放队列中移除",
"MessageRemoveUserWarning": "是否确实要永久删除用户 \"{0}\"?",
- "MessageReportBugsAndContribute": "报告错误、请求功能和贡献在",
+ "MessageReportBugsAndContribute": "反馈问题、建议功能或参与贡献,请访问",
"MessageResetChaptersConfirm": "你确定要重置章节并撤消你所做的更改吗?",
"MessageRestoreBackupConfirm": "你确定要恢复创建的这个备份",
"MessageRestoreBackupWarning": "恢复备份将覆盖位于 /config 的整个数据库并覆盖 /metadata/items & /metadata/authors 中的图像.