From e6cc61b2dda079722950edd73b8715a99ae84461 Mon Sep 17 00:00:00 2001 From: fabian Date: Wed, 26 Jun 2024 21:14:15 +0200 Subject: [PATCH 01/18] Simplifying language loading to avoid double toasts on language change at webpage startup. Also using resolvedLanguage to make it more robust against locales and "wrong" inputs. --- html/management.html | 78 ++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/html/management.html b/html/management.html index 9cf936de..f1b90bd5 100644 --- a/html/management.html +++ b/html/management.html @@ -1042,8 +1042,6 @@ var ActiveTab = 'nav-rfid-tab'; var ActiveSubTab = 'rfid-music-tab'; var host = $(location).attr('hostname'); - var language = navigator.language || navigator.userLanguage; - var localize; /* show active / selected tab */ $('#nav-tab.nav-tabs a').on('shown.bs.tab', function(e) { ActiveTab = $(e.target).attr('id'); @@ -1120,43 +1118,45 @@ warning: msg => toaster.toast(msg, 'text-bg-warning'), error: msg => toaster.toast(msg, 'text-bg-danger') } - - i18next.use(i18nextHttpBackend).init({ - backend: { - loadPath: "http://" + host + "/locales/{{lng}}.json" - }, - load: 'languageOnly', - debug: true, - fallbackLng: 'en', - returnObjects: true, - }, (err, t) => { - localize = locI18next.init(i18next); - localize('body'); - toaster.clear(); - // change the language if we found it in the local storage - const lang = localStorage.getItem("language"); - if(lang === null) { - i18next.changeLanguage(language.split("-")[0]); - } else { - i18next.changeLanguage(lang); - } - }); - i18next.on('languageChanged', (lng) => { - document.querySelector('#langSel').value = lng; - if(localize) { - localize('body'); - } - document.querySelector('#menu').classList.remove("show") // Hide the menu again - }); - document.querySelector('#langSel').addEventListener('change', (e) => { - const lang = e.target.value; - console.log(lang); - if(lang !== i18next.language) { - toaster.clear(); - localStorage.setItem("language", lang); - i18next.changeLanguage(lang); - } - }); + + function initI18N() { + // function to call for translating elements + let localize; + // check for language in local storage. if none is present, choose navigator language or userLanguage. + const startupLanguage = localStorage.getItem("language") || navigator.language || navigator.userLanguage; + i18next.use(i18nextHttpBackend) + .init({ + backend: { + loadPath: "http://" + host + "/locales/{{lng}}.json" + }, + load: 'languageOnly', + // debug: true, + lng: startupLanguage, + fallbackLng: 'en', + returnObjects: true, + }, (err, t) => { + localize = locI18next.init(i18next); + localize('body'); + }); + i18next.on('languageChanged', () => { + $('#langSel').val(i18next.resolvedLanguage); // set for the resolved language, which will be without locale + $('#menu').removeClass("show") // Hide the menu again + console.info('language changes to', i18next.resolvedLanguage); + if(localize) { + localize('body'); + } + }); + $('#langSel').on('change', (e) => { + const lng = e.target.value; + if(lng !== i18next.language) { + toaster.clear(); + localStorage.setItem("language", lng); + i18next.changeLanguage(lng); + } + }); + } + initI18N(); + document.getElementById('trackProgressDiv').addEventListener('click', function(e) { var bounds = this.getBoundingClientRect(); var max = bounds.width; From f8fd51e7c6aa3bcb827132ce596dab0a0123461d Mon Sep 17 00:00:00 2001 From: fabian Date: Wed, 26 Jun 2024 21:55:58 +0200 Subject: [PATCH 02/18] Prepare localization for popovers as they need a reinitialization --- html/management.html | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/html/management.html b/html/management.html index f1b90bd5..62239992 100644 --- a/html/management.html +++ b/html/management.html @@ -1124,6 +1124,19 @@ let localize; // check for language in local storage. if none is present, choose navigator language or userLanguage. const startupLanguage = localStorage.getItem("language") || navigator.language || navigator.userLanguage; + + // function to wrap the localize call into a reusable code block + function localization() { + if (localize) { + localize('body'); + // (re)initialize all popover buttons to get correct translations in the popovers + document.querySelectorAll('[data-bs-toggle="popover"]') + .forEach(popoverButton => { + new bootstrap.Popover(popoverButton, {html: true, trigger: 'focus'}) + }); + } + } + i18next.use(i18nextHttpBackend) .init({ backend: { @@ -1136,15 +1149,13 @@ returnObjects: true, }, (err, t) => { localize = locI18next.init(i18next); - localize('body'); + localization(); }); i18next.on('languageChanged', () => { $('#langSel').val(i18next.resolvedLanguage); // set for the resolved language, which will be without locale - $('#menu').removeClass("show") // Hide the menu again + $('#menu').removeClass("show"); // Hide the menu again console.info('language changes to', i18next.resolvedLanguage); - if(localize) { - localize('body'); - } + localization(); }); $('#langSel').on('change', (e) => { const lng = e.target.value; From cf10829b9dd79125c4178b7669c525fe6a0fca5a Mon Sep 17 00:00:00 2001 From: fabian Date: Mon, 8 Jul 2024 12:33:24 +0200 Subject: [PATCH 03/18] Swallow the first untranslated toast.success --- html/management.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/html/management.html b/html/management.html index 62239992..81132f3d 100644 --- a/html/management.html +++ b/html/management.html @@ -1814,7 +1814,10 @@ } if("status" in socketMsg) { if(socketMsg.status == "ok") { - toaster.success(i18next.t("toast.success")); + // avoiding the untranslated toast on bootup + if (i18next.exists('toast.success')) { + toaster.success(i18next.t("toast.success")); + } } if(socketMsg.status == "dropout") { toaster.warning(i18next.t("toast.dropout")); From 7ef22be647367ed631e5c33b2fca923f686f583a Mon Sep 17 00:00:00 2001 From: fabian Date: Mon, 8 Jul 2024 12:42:35 +0200 Subject: [PATCH 04/18] Adding splash screen while translation is loading --- html/locales/de.json | 701 ++++++++++++++++++++++--------------------- html/locales/en.json | 701 ++++++++++++++++++++++--------------------- html/locales/fr.json | 1 + html/management.html | 13 + 4 files changed, 716 insertions(+), 700 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 2eca5197..ccbb1cc5 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -1,350 +1,351 @@ -{ - "submit":"Absenden", - "restart":"Neustart", - "reset":"Reset", - "execute":"Ausführen", - "title":"ESPuino", - "shutdown":"Ausschalten", - "log":"Log", - "info":"Info", - "delete":"Löschen", - "cancel":"Abbrechen", - "refresh":"Aktualisieren", - "ok": "OK", - "infos": "Infos", - "darkmode": "Dunkelmodus", - "restartinfo":"ESPuino wird jetzt neu gestartet...
Die Seite lädt sich nach dem Neustart automatisch neu.", - "shutdowninfo":"ESPuino wird jetzt ausgeschaltet...
Die Seite lädt sich nach dem Wiedereinschalten automatisch neu.", - "toast":{ - "rfidDetect":"RFID Tag mit {{rfidId}} erkannt.", - "success":"Aktion erfolgreich ausgeführt.", - "conlost":"Die Verbindung zum ESPuino ist unterbrochen! Bitte Seite neu laden.", - "dropout":"Langsamer Stream, Aussetzer möglich." - }, - "nav":{ - "control":"Steuerung", - "rfid":"RFID", - "wifi":"WLAN", - "mqtt":"MQTT", - "ftp":"FTP", - "bluetooth":"Bluetooth", - "general":"Allgemein", - "tools":"Tools", - "help":"Hilfe" - }, - "wifi":{ - "title":"WLAN-Einstellungen", - "networks":"Netzwerke", - "savedNetworks":"Gespeicherte Netzwerke", - "ssid":{ - "title":"WLAN-Name (SSID)", - "placeholder":"SSID", - "validation":"Bitte SSID des WLANs eintragen" - }, - "password":{ - "title":"Passwort", - "placeholder":"Passwort", - "validation":"Bitte Passwort vom WLANs eintragen" - }, - "hostname":{ - "title":"ESPuino-Name (Hostname)", - "placeholder":"espuino", - "validation":"Trage einen validen Hostnamen ein" - }, - "static":{ - "addr":"Statische IP-Adresse", - "enabled":"Statische IP-Konfiguration", - "gateway":"Gateway für statische IP-Konfiguration", - "subnet":"Subnetzmaske für statische IP-Konfiguration", - "dns1":" DNS 1 für statische IP-Konfiguration", - "dns2":"DNS 2 für statische IP-Konfiguration" - }, - "scan":{ - "enabled":"Start mit bestem WLAN" - }, - "delete":{ - "title":"Netzwerk entfernen", - "prompt":"Gespeichertes Netzwerk \"{{ssid}}\" wirklich entfernen?" - }, - "restartPrompt":"Fertig?" - }, - "control":{ - "title":"Steuerung", - "first":"Erster", - "prev":"Vorheriger", - "playpause":"Play / Pause", - "forward":"Nächster", - "last":"Letzter", - "volume":"Lautstärke", - "voldown":"Leiser", - "volup":"Lauter", - "current":"Aktueller Titel", - "command":"Modifikation ausführen" - }, - "files":{ - "title":"Dateien", - "loading":"Wird geladen...", - "context":{ - "newFolder":"Neuer Ordner", - "play":"Abspielen", - "refresh":"Aktualisieren", - "delete":"Löschen", - "rename":"Umbenennen", - "download":"Download" - }, - "files":{ - "title":"Dateien", - "desc":"Eine oder mehrere Datei(en) hochladen" - }, - "directory":{ - "title":"Ordner", - "desc":"Einen Ordner samt Inhalt (und allen Unterordnern) hochladen" - }, - "search":{ - "placeholder":"Dateien suchen.." - }, - "upload":{ - "title":"Upload", - "desc":"Upload starten", - "selectFolder":"Wähle den Zielordner für den Upload!", - "selectFile":"Wähle eine Datei zum Hochladen!", - "success":"Upload erfolgreich ({{elapsed}}, {{speed}} KB/s)", - "error":"Upload fehlgeschlagen", - "timeCalc":"Verbleibende Zeit wird berechnet..", - "minutes_one":"Minute", - "minutes_other":"Minuten", - "seconds":"Sekunden", - "fewSec":"wenige", - "progress":"{{percent}}% ({{speed}} KB/s), {{remaining.value}} {{remaining.unit}} verbleibend.." - }, - "rfid":{ - "title":"RFID-Zuweisungen", - "idNumber":"RFID-Chip-Nummer (12-stellig)", - "music":"Musik", - "modification":"Modifikation", - "savedassignments":"Gespeicherte RFID-Zuweisungen", - "fileurl":{ - "title":"Datei, Verzeichnis oder URL (^ und # als Zeichen nicht erlaubt)", - "placeholder":"z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3" - }, - "playmode":{ - "title":"Abspielmodus", - "placeholder":"Modus auswählen", - "mode":{ - "1":"Einzelner Titel", - "2":"Einzelner Titel (Endlosschleife)", - "12":"Einzelner Titel eines Verzeichnis (zufällig). Danach schlafen.", - "3":"Hörbuch", - "4":"Hörbuch (Endlosschleife)", - "5":"Alle Titel eines Verzeichnis (sortiert)", - "6":"Alle Titel eines Verzeichnis (zufällig)", - "7":"Alle Titel eines Verzeichnis (sortiert, Endlosschleife)", - "9":"Alle Titel eines Verzeichnis (zufällig, Endlosschleife)", - "13":"Alle Titel aus einem zufälligen Unterverzeichnis (sortiert)", - "14":"Alle Titel aus einem zufälligen Unterverzeichnis (zufällig)", - "8":"Webradio", - "11":"Liste (Dateien von SD und/oder Webstreams) aus lokaler .m3u-Datei" - }, - "error":"Kein gültiger Abspielmodus" - }, - "mod":{ - "title":"Modifikation", - "placeholder":"Modifikation auswählen", - "cmd":{ - "100":"Tastensperre", - "179":"Schlafe sofort", - "101":"Schlafen nach 15 Minuten", - "102":"Schlafen nach 30 Minuten", - "103":"Schlafen nach 1 Stunde", - "104":"Schlafen nach 2 Stunden", - "105":"Schlafen nach Ende des Titels", - "106":"Schlafen nach Ende der Playlist", - "107":"Schlafen nach fünf Titeln", - "110":"Wiederhole Playlist (endlos)", - "111":"Wiederhole Titel (endlos)", - "120":"Dimme LEDs (Nachtmodus)", - "130":"Aktiviere/deaktiviere WLAN", - "140":"Bluetooth-Lautsprecher aktivieren/deaktivieren", - "141":"Bluetooth-Kopfhörer aktivieren/deaktivieren", - "142":"Wechsle Modus (Normal => BT-Lautsprecher => BT-Kopfhörer)", - "150":"Aktiviere FTP", - "151":"IP-Adresse ansagen", - "152":"Uhrzeit ansagen", - "0":"Lösche Zuordnung", - "170":"Play/Pause", - "171":"Vorheriger Titel", - "172":"Nächster Titel", - "173":"Erster Titel", - "174":"Letzter Titel", - "180":"Springe vorwärts (n Sekunden)", - "181":"Springe rückwärts (n Sekunden)" - } - } - } - }, - "mqtt":{ - "title":"MQTT-Einstellungen", - "enable":"MQTT aktivieren", - "clientId":{ - "title":"MQTT-ClientId", - "placeholder":"z.B. ESPuino", - "validation":"" - }, - "server":{ - "title":"MQTT-Server", - "placeholder":"f.e. 192.168.2.89", - "validation":"" - }, - "user":{ - "title":"MQTT-Benutzername (optional)", - "placeholder":"Benutzername", - "validation":"" - }, - "pwd":{ - "title":"MQTT-Passwort (optional)", - "placeholder":"Passwort", - "validation":"" - }, - "port":{ - "title":"MQTT-Port", - "placeholder":"z.B. 1883", - "validation":"" - } - }, - "ftp":{ - "title":"FTP-Einstellungen", - "user":{ - "title":"FTP-Benutzername", - "placeholder":"Benutzername" - }, - "pwd":{ - "title":"FTP-Passwort", - "placeholder":"Passwort" - }, - "start":{ - "title":"FTP-Server starten", - "desc":"Aktiviert den FTP-Server bis zum Neustart des Geräts.", - "button":"FTP-Server starten" - } - }, - "bt":{ - "sink":{ - "title":"ESPuino als Bluetooth-Lautsprecher", - "desc":"ESPuino wird als Bluetooth-Lautsprecher gestartet. Nach dem Wechsel in diesen Modus wird die Web-Schnittstelle nicht mehr zur Verfügung stehen, bis das System im normalen Modus neu gestartet wird.", - "button":"Als Bluetooth-Lautsprecher starten" - }, - "source":{ - "configtitle":"Bluetooth-Kopfhörer Einstellungen", - "title":"Mit Bluetooth-Kopfhörer verbinden", - "desc":"Das Gerät verbindet sich mit dem angegebenen Bluetooth-Kopfhörer. Nach dem Wechsel in diesen Modus wird die Web-Schnittstelle nicht mehr zur Verfügung stehen, bis das System im normalen Modus neu gestartet wird.", - "button":"Im Kopfhörer-Modus starten" - }, - "device":{ - "title":"Bluetooth-Gerät (Kopfhörer)", - "placeholder":"z.B. My POGS Wireless Headphone" - }, - "pincode":{ - "title":"Pairing PIN-Code", - "placeholder":"z.B. 0000" - } - }, - "general":{ - "language":"Sprache", - "volume":{ - "title":"Lautstärke", - "restart":"Nach dem Einschalten", - "speakerMax":"Maximal (Lautsprecher)", - "headphoneMax":"Maximal (Kopfhörer)" - }, - "equalizer":{ - "title":"Equalizer", - "gainLowPass":"Tiefen (in dB)", - "gainBandPass":"Mitten (in dB)", - "gainHighPass":"Höhen (in dB)", - "info":"Die Frequenzen sind laut Bibliothek (ESP32-audioI2S) 500 Hz LowShelf, 3000 Hz PeakEQ und 6000 Hz HighShelf." - }, - "neopixel":{ - "title":"Neopixel (Helligkeit)", - "restart":"Nach dem Einschalten", - "nightmode":"Im Nachtmodus" - }, - "sleep":{ - "title":"Deep Sleep", - "inactivity":"Inaktivität nach (in Minuten)" - }, - "battery":{ - "title":"Batterie", - "desc":"Status über Neopixel anzeigen", - "lowWarning":"Unter dieser Spannung (in Volt) wird eine Warnung angezeigt", - "lowCritical":"Eine LED leuchtet bei dieser Spannung (in Volt)", - "criticalShutoff":"Unter dieser Spannung (in Volt) schaltet der ESPuino ab", - "high":"Alle LEDs leuchten bei dieser Spannung (in Volt)", - "measureInterval":"Zeitabstand der Messung (in Minuten)" - }, - "playlist":{ - "title":"Wiedergabeliste", - "sortMode":"Sortierungsmodus für Wiedergabeliste und Dateibrowser", - "strcmp":"Standardsortierung", - "strnatcmp":"Natürlich: Groß- und Kleinschreibung beachten", - "strnatcasecmp":"Natürlich: Groß- und Kleinschreibung ignorieren" - } - }, - "tools":{ - "nvserase":{ - "title":"NVS RFID-Zuweisungen löschen", - "desc":"Über den Importer werden lediglich neue Einträge importiert, jedoch keine bestehenden Einträge aktiv gelöscht. Im Falle einer doppelten Zuweisung wird ein Eintrag allenfalls überschrieben. Mit dieser Funktion können alle bestehenden NVS-RFID-Zuweisungen gelöscht werden, so dass der ESPuino im Anschluss keinerlei Karten mehr kennt. Wird im Anschluss der Importer gestartet, befinden sich im Speicher des ESPuino anschließend exakt nur solche Zuweisungen, die Teil der Backup-Datei sind. Weitere Infos gibt es hier.", - "button":"Zuweisungen löschen", - "prompt":"Alle RFID-Zuweisungen wirklich löschen?" - }, - "nvsdelete":{ - "title":"NVS RFID-Zuweisung entfernen", - "prompt":"Gespeicherte Zuweisung \"{{rfid}}\" wirklich entfernen?" - }, - "nvsimport":{ - "title":"NVS RFID-Importer", - "desc":"Hier kann eine Backup-Datei hochgeladen werden, um NVS-RFID-Zuweisungen zu importieren." - }, - "fwupdate":{ - "title":"Firmware-Update", - "desc":"Hier kann ein Firmware-Update durchgeführt werden." - } - }, - "help":{ - "forum":{ - "title":"Forum", - "desc":"Du hast Probleme mit ESPuino oder bist an einem Erfahrungsaustausch interessiert?
Dann schaue doch mal im ESPuino-Forum vorbei! Insbesondere gibt es dort auch einen Bereich, in dem reichlich Dokumentation hinterlegt ist. Wir freuen uns auf deinen Besuch!" - }, - "swagger":{ - "title":"Swagger", - "desc":"Dokumentation der REST API: Swagger." - } - }, - "datetime":{ - "day":"Tag", - "days":"Tage", - "hour":"Stunde", - "hours":"Stunden", - "minute":"Minute", - "minutes":"Minuten", - "second":"Sekunde", - "seconds":"Sekunden" - }, - "systeminfo":{ - "title":"Information", - "softwareversion":"ESPuino {{softwareversion}}", - "gitversion":"ESPuino {{gitversion}}", - "arduinoversion":"Arduino Version: {{arduinoversion}} (ESP-IDF {{idfversion}})", - "hardware":"Hardware: {{hwmodel}}, Revision {{hwrevision}}, CPU: {{hwfreq}} MHZ", - "freeheap":"Freier Heap: {{freeheap}} Bytes", - "largestfreeblock":"Größter freier Heap-Block: {{largestfreeblock}} Bytes", - "freepsram":"Freier PS-RAM: {{freepsram}} Bytes", - "currentip":"Aktuelle IP-Adresse: {{currentip}}", - "macAddress":"MAC-Adresse: {{macAddress}}", - "rssi":"WLAN Signalstärke: {{rssi}} dBm", - "audiotimetotal":"Audio-Gesamtspielzeit seit {{firststart}}: {{audiotimetotal}}", - "audiotimesincestart":"Spielzeit seit letztem Start: {{audiotimesincestart}}", - "currvoltage":"Aktuelle Batteriespannung: {{currvoltage}} V", - "chargelevel":"Aktuelle Batterieladung: {{chargelevel}} %", - "hallsensor":"HallEffectSensor NullFieldValue: {{hsnullfieldvalue}}, actual: {{hsactual}}, diff:{{hsdiff}}, LastWaitFor_State:{{hslastwaitforstate}} (waited:{{hswaited}} ms)" - } -} +{ + "submit":"Absenden", + "restart":"Neustart", + "reset":"Reset", + "execute":"Ausführen", + "title":"ESPuino", + "shutdown":"Ausschalten", + "log":"Log", + "info":"Info", + "delete":"Löschen", + "cancel":"Abbrechen", + "refresh":"Aktualisieren", + "ok": "OK", + "infos": "Infos", + "darkmode": "Dunkelmodus", + "restartinfo":"ESPuino wird jetzt neu gestartet...
Die Seite lädt sich nach dem Neustart automatisch neu.", + "shutdowninfo":"ESPuino wird jetzt ausgeschaltet...
Die Seite lädt sich nach dem Wiedereinschalten automatisch neu.", + "toast":{ + "rfidDetect":"RFID Tag mit {{rfidId}} erkannt.", + "success":"Aktion erfolgreich ausgeführt.", + "conlost":"Die Verbindung zum ESPuino ist unterbrochen! Bitte Seite neu laden.", + "dropout":"Langsamer Stream, Aussetzer möglich." + }, + "nav":{ + "control":"Steuerung", + "rfid":"RFID", + "wifi":"WLAN", + "mqtt":"MQTT", + "ftp":"FTP", + "bluetooth":"Bluetooth", + "general":"Allgemein", + "tools":"Tools", + "help":"Hilfe" + }, + "wifi":{ + "title":"WLAN-Einstellungen", + "networks":"Netzwerke", + "savedNetworks":"Gespeicherte Netzwerke", + "ssid":{ + "title":"WLAN-Name (SSID)", + "placeholder":"SSID", + "validation":"Bitte SSID des WLANs eintragen" + }, + "password":{ + "title":"Passwort", + "placeholder":"Passwort", + "validation":"Bitte Passwort vom WLANs eintragen" + }, + "hostname":{ + "title":"ESPuino-Name (Hostname)", + "placeholder":"espuino", + "validation":"Trage einen validen Hostnamen ein" + }, + "static":{ + "addr":"Statische IP-Adresse", + "enabled":"Statische IP-Konfiguration", + "gateway":"Gateway für statische IP-Konfiguration", + "subnet":"Subnetzmaske für statische IP-Konfiguration", + "dns1":" DNS 1 für statische IP-Konfiguration", + "dns2":"DNS 2 für statische IP-Konfiguration" + }, + "scan":{ + "enabled":"Start mit bestem WLAN" + }, + "delete":{ + "title":"Netzwerk entfernen", + "prompt":"Gespeichertes Netzwerk \"{{ssid}}\" wirklich entfernen?" + }, + "restartPrompt":"Fertig?" + }, + "control":{ + "title":"Steuerung", + "first":"Erster", + "prev":"Vorheriger", + "playpause":"Play / Pause", + "forward":"Nächster", + "last":"Letzter", + "volume":"Lautstärke", + "voldown":"Leiser", + "volup":"Lauter", + "current":"Aktueller Titel", + "command":"Modifikation ausführen" + }, + "files":{ + "title":"Dateien", + "loading":"Wird geladen...", + "context":{ + "newFolder":"Neuer Ordner", + "play":"Abspielen", + "refresh":"Aktualisieren", + "delete":"Löschen", + "rename":"Umbenennen", + "download":"Download" + }, + "files":{ + "title":"Dateien", + "desc":"Eine oder mehrere Datei(en) hochladen" + }, + "directory":{ + "title":"Ordner", + "desc":"Einen Ordner samt Inhalt (und allen Unterordnern) hochladen" + }, + "search":{ + "placeholder":"Dateien suchen.." + }, + "upload":{ + "title":"Upload", + "desc":"Upload starten", + "selectFolder":"Wähle den Zielordner für den Upload!", + "selectFile":"Wähle eine Datei zum Hochladen!", + "success":"Upload erfolgreich ({{elapsed}}, {{speed}} KB/s)", + "error":"Upload fehlgeschlagen", + "timeCalc":"Verbleibende Zeit wird berechnet..", + "minutes_one":"Minute", + "minutes_other":"Minuten", + "seconds":"Sekunden", + "fewSec":"wenige", + "progress":"{{percent}}% ({{speed}} KB/s), {{remaining.value}} {{remaining.unit}} verbleibend.." + }, + "rfid":{ + "title":"RFID-Zuweisungen", + "idNumber":"RFID-Chip-Nummer (12-stellig)", + "music":"Musik", + "modification":"Modifikation", + "savedassignments":"Gespeicherte RFID-Zuweisungen", + "fileurl":{ + "title":"Datei, Verzeichnis oder URL (^ und # als Zeichen nicht erlaubt)", + "placeholder":"z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3" + }, + "playmode":{ + "title":"Abspielmodus", + "placeholder":"Modus auswählen", + "mode":{ + "1":"Einzelner Titel", + "2":"Einzelner Titel (Endlosschleife)", + "12":"Einzelner Titel eines Verzeichnis (zufällig). Danach schlafen.", + "3":"Hörbuch", + "4":"Hörbuch (Endlosschleife)", + "5":"Alle Titel eines Verzeichnis (sortiert)", + "6":"Alle Titel eines Verzeichnis (zufällig)", + "7":"Alle Titel eines Verzeichnis (sortiert, Endlosschleife)", + "9":"Alle Titel eines Verzeichnis (zufällig, Endlosschleife)", + "13":"Alle Titel aus einem zufälligen Unterverzeichnis (sortiert)", + "14":"Alle Titel aus einem zufälligen Unterverzeichnis (zufällig)", + "8":"Webradio", + "11":"Liste (Dateien von SD und/oder Webstreams) aus lokaler .m3u-Datei" + }, + "error":"Kein gültiger Abspielmodus" + }, + "mod":{ + "title":"Modifikation", + "placeholder":"Modifikation auswählen", + "cmd":{ + "100":"Tastensperre", + "179":"Schlafe sofort", + "101":"Schlafen nach 15 Minuten", + "102":"Schlafen nach 30 Minuten", + "103":"Schlafen nach 1 Stunde", + "104":"Schlafen nach 2 Stunden", + "105":"Schlafen nach Ende des Titels", + "106":"Schlafen nach Ende der Playlist", + "107":"Schlafen nach fünf Titeln", + "110":"Wiederhole Playlist (endlos)", + "111":"Wiederhole Titel (endlos)", + "120":"Dimme LEDs (Nachtmodus)", + "130":"Aktiviere/deaktiviere WLAN", + "140":"Bluetooth-Lautsprecher aktivieren/deaktivieren", + "141":"Bluetooth-Kopfhörer aktivieren/deaktivieren", + "142":"Wechsle Modus (Normal => BT-Lautsprecher => BT-Kopfhörer)", + "150":"Aktiviere FTP", + "151":"IP-Adresse ansagen", + "152":"Uhrzeit ansagen", + "0":"Lösche Zuordnung", + "170":"Play/Pause", + "171":"Vorheriger Titel", + "172":"Nächster Titel", + "173":"Erster Titel", + "174":"Letzter Titel", + "180":"Springe vorwärts (n Sekunden)", + "181":"Springe rückwärts (n Sekunden)" + } + } + } + }, + "mqtt":{ + "title":"MQTT-Einstellungen", + "enable":"MQTT aktivieren", + "clientId":{ + "title":"MQTT-ClientId", + "placeholder":"z.B. ESPuino", + "validation":"" + }, + "server":{ + "title":"MQTT-Server", + "placeholder":"f.e. 192.168.2.89", + "validation":"" + }, + "user":{ + "title":"MQTT-Benutzername (optional)", + "placeholder":"Benutzername", + "validation":"" + }, + "pwd":{ + "title":"MQTT-Passwort (optional)", + "placeholder":"Passwort", + "validation":"" + }, + "port":{ + "title":"MQTT-Port", + "placeholder":"z.B. 1883", + "validation":"" + } + }, + "ftp":{ + "title":"FTP-Einstellungen", + "user":{ + "title":"FTP-Benutzername", + "placeholder":"Benutzername" + }, + "pwd":{ + "title":"FTP-Passwort", + "placeholder":"Passwort" + }, + "start":{ + "title":"FTP-Server starten", + "desc":"Aktiviert den FTP-Server bis zum Neustart des Geräts.", + "button":"FTP-Server starten" + } + }, + "bt":{ + "sink":{ + "title":"ESPuino als Bluetooth-Lautsprecher", + "desc":"ESPuino wird als Bluetooth-Lautsprecher gestartet. Nach dem Wechsel in diesen Modus wird die Web-Schnittstelle nicht mehr zur Verfügung stehen, bis das System im normalen Modus neu gestartet wird.", + "button":"Als Bluetooth-Lautsprecher starten" + }, + "source":{ + "configtitle":"Bluetooth-Kopfhörer Einstellungen", + "title":"Mit Bluetooth-Kopfhörer verbinden", + "desc":"Das Gerät verbindet sich mit dem angegebenen Bluetooth-Kopfhörer. Nach dem Wechsel in diesen Modus wird die Web-Schnittstelle nicht mehr zur Verfügung stehen, bis das System im normalen Modus neu gestartet wird.", + "button":"Im Kopfhörer-Modus starten" + }, + "device":{ + "title":"Bluetooth-Gerät (Kopfhörer)", + "placeholder":"z.B. My POGS Wireless Headphone" + }, + "pincode":{ + "title":"Pairing PIN-Code", + "placeholder":"z.B. 0000" + } + }, + "general":{ + "language":"Sprache", + "loadingLanguage": "Sprache wird geladen ...", + "volume":{ + "title":"Lautstärke", + "restart":"Nach dem Einschalten", + "speakerMax":"Maximal (Lautsprecher)", + "headphoneMax":"Maximal (Kopfhörer)" + }, + "equalizer":{ + "title":"Equalizer", + "gainLowPass":"Tiefen (in dB)", + "gainBandPass":"Mitten (in dB)", + "gainHighPass":"Höhen (in dB)", + "info":"Die Frequenzen sind laut Bibliothek (ESP32-audioI2S) 500 Hz LowShelf, 3000 Hz PeakEQ und 6000 Hz HighShelf." + }, + "neopixel":{ + "title":"Neopixel (Helligkeit)", + "restart":"Nach dem Einschalten", + "nightmode":"Im Nachtmodus" + }, + "sleep":{ + "title":"Deep Sleep", + "inactivity":"Inaktivität nach (in Minuten)" + }, + "battery":{ + "title":"Batterie", + "desc":"Status über Neopixel anzeigen", + "lowWarning":"Unter dieser Spannung (in Volt) wird eine Warnung angezeigt", + "lowCritical":"Eine LED leuchtet bei dieser Spannung (in Volt)", + "criticalShutoff":"Unter dieser Spannung (in Volt) schaltet der ESPuino ab", + "high":"Alle LEDs leuchten bei dieser Spannung (in Volt)", + "measureInterval":"Zeitabstand der Messung (in Minuten)" + }, + "playlist":{ + "title":"Wiedergabeliste", + "sortMode":"Sortierungsmodus für Wiedergabeliste und Dateibrowser", + "strcmp":"Standardsortierung", + "strnatcmp":"Natürlich: Groß- und Kleinschreibung beachten", + "strnatcasecmp":"Natürlich: Groß- und Kleinschreibung ignorieren" + } + }, + "tools":{ + "nvserase":{ + "title":"NVS RFID-Zuweisungen löschen", + "desc":"Über den Importer werden lediglich neue Einträge importiert, jedoch keine bestehenden Einträge aktiv gelöscht. Im Falle einer doppelten Zuweisung wird ein Eintrag allenfalls überschrieben. Mit dieser Funktion können alle bestehenden NVS-RFID-Zuweisungen gelöscht werden, so dass der ESPuino im Anschluss keinerlei Karten mehr kennt. Wird im Anschluss der Importer gestartet, befinden sich im Speicher des ESPuino anschließend exakt nur solche Zuweisungen, die Teil der Backup-Datei sind. Weitere Infos gibt es hier.", + "button":"Zuweisungen löschen", + "prompt":"Alle RFID-Zuweisungen wirklich löschen?" + }, + "nvsdelete":{ + "title":"NVS RFID-Zuweisung entfernen", + "prompt":"Gespeicherte Zuweisung \"{{rfid}}\" wirklich entfernen?" + }, + "nvsimport":{ + "title":"NVS RFID-Importer", + "desc":"Hier kann eine Backup-Datei hochgeladen werden, um NVS-RFID-Zuweisungen zu importieren." + }, + "fwupdate":{ + "title":"Firmware-Update", + "desc":"Hier kann ein Firmware-Update durchgeführt werden." + } + }, + "help":{ + "forum":{ + "title":"Forum", + "desc":"Du hast Probleme mit ESPuino oder bist an einem Erfahrungsaustausch interessiert?
Dann schaue doch mal im ESPuino-Forum vorbei! Insbesondere gibt es dort auch einen Bereich, in dem reichlich Dokumentation hinterlegt ist. Wir freuen uns auf deinen Besuch!" + }, + "swagger":{ + "title":"Swagger", + "desc":"Dokumentation der REST API: Swagger." + } + }, + "datetime":{ + "day":"Tag", + "days":"Tage", + "hour":"Stunde", + "hours":"Stunden", + "minute":"Minute", + "minutes":"Minuten", + "second":"Sekunde", + "seconds":"Sekunden" + }, + "systeminfo":{ + "title":"Information", + "softwareversion":"ESPuino {{softwareversion}}", + "gitversion":"ESPuino {{gitversion}}", + "arduinoversion":"Arduino Version: {{arduinoversion}} (ESP-IDF {{idfversion}})", + "hardware":"Hardware: {{hwmodel}}, Revision {{hwrevision}}, CPU: {{hwfreq}} MHZ", + "freeheap":"Freier Heap: {{freeheap}} Bytes", + "largestfreeblock":"Größter freier Heap-Block: {{largestfreeblock}} Bytes", + "freepsram":"Freier PS-RAM: {{freepsram}} Bytes", + "currentip":"Aktuelle IP-Adresse: {{currentip}}", + "macAddress":"MAC-Adresse: {{macAddress}}", + "rssi":"WLAN Signalstärke: {{rssi}} dBm", + "audiotimetotal":"Audio-Gesamtspielzeit seit {{firststart}}: {{audiotimetotal}}", + "audiotimesincestart":"Spielzeit seit letztem Start: {{audiotimesincestart}}", + "currvoltage":"Aktuelle Batteriespannung: {{currvoltage}} V", + "chargelevel":"Aktuelle Batterieladung: {{chargelevel}} %", + "hallsensor":"HallEffectSensor NullFieldValue: {{hsnullfieldvalue}}, actual: {{hsactual}}, diff:{{hsdiff}}, LastWaitFor_State:{{hslastwaitforstate}} (waited:{{hswaited}} ms)" + } +} diff --git a/html/locales/en.json b/html/locales/en.json index a593d4b0..176e9362 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -1,350 +1,351 @@ -{ - "submit":"Submit", - "restart":"Restart", - "reset":"Reset", - "execute":"Execute", - "title":"ESPuino", - "shutdown":"Shutdown", - "log":"Log", - "info":"Info", - "delete":"Delete", - "cancel":"Cancel", - "refresh":"Refresh", - "ok": "OK", - "infos": "Infos", - "darkmode": "Dark Mode", - "restartinfo":"ESPuino is being restarted...
Page reloads automatically after restart finished.", - "shutdowninfo":"ESPuino is now switched off...
Page reloads automatically when the ESPuino is switched on again..", - "toast":{ - "rfidDetect":"RFID-tag {{rfidId}} detected.", - "success":"Action performed successfully.", - "conlost":"Connection to ESPuino broken! Please reload website.", - "dropout":"slow stream, dropouts are possible." - }, - "nav":{ - "control":"Control", - "rfid":"RFID", - "wifi":"WiFi", - "mqtt":"MQTT", - "ftp":"FTP", - "bluetooth":"Bluetooth", - "general":"General", - "tools":"Tools", - "help":"Help" - }, - "wifi":{ - "title":"WiFi-configuration", - "networks":"Networks", - "savedNetworks":"Saved Networks", - "ssid":{ - "title":"WiFi-name (SSID)", - "placeholder":"SSID", - "validation":"Enter WiFi's SSID" - }, - "password":{ - "title":"Password", - "placeholder":"Password", - "validation":"Enter the WiFi's password" - }, - "hostname":{ - "title":"ESPuino's name (hostname)", - "placeholder":"espuino", - "validation":"Enter a valid hostname" - }, - "static":{ - "addr":"Static IP-Address", - "enabled":"Static IP-Configuration", - "gateway":"Gateway for static IP-Configuration", - "subnet":"Subnet-mask for static IP-Configuration", - "dns1":" DNS 1 for static IP-Configuration", - "dns2":"DNS 2 for static IP-Configuration" - }, - "scan":{ - "enabled":"Start with strongest WiFi" - }, - "delete":{ - "title":"Delete WiFi", - "prompt":"Delete saved WiFi \"{{ssid}}\" ?" - }, - "restartPrompt":"Ready to go?" - }, - "control":{ - "title":"Control", - "first":"First", - "prev":"Previous", - "playpause":"Play / Pause", - "forward":"Next", - "last":"Last", - "volume":"Volume", - "voldown":"Volume Down", - "volup":"Volume Up", - "current":"Current track", - "command":"Execute Modification" - }, - "files":{ - "title":"Files", - "loading":"Please wait...", - "context":{ - "newFolder":"New Folder", - "play":"Play", - "refresh":"Refresh", - "delete":"Delete", - "rename":"Rename", - "download":"Download" - }, - "files":{ - "title":"Files", - "desc":"Upload one ore more files" - }, - "directory":{ - "title":"Directory", - "desc":"Upload directory with all files and subdirectories" - }, - "search":{ - "placeholder":"Search files.." - }, - "upload":{ - "title":"Upload", - "desc":"Start Upload", - "selectFolder":"Please select the upload location!", - "selectFile":"Please select files to upload!", - "success":"Upload successful ({{elapsed}}, {{speed}} KB/s)", - "error":"Upload error", - "timeCalc":"Remaining time is being calculated..", - "minutes_one":"minute", - "minutes_other":"minutes", - "seconds":"seconds", - "fewSec":"few", - "progress":"{{percent}}% ({{speed}} KB/s), {{remaining.value}} {{remaining.unit}} remaining.." - }, - "rfid":{ - "title":"RFID-Assignments", - "idNumber":"RFID-number (12 digits)", - "music":"Music", - "modification":"Modification", - "savedassignments":"Saved RFID-assignments", - "fileurl":{ - "title":"File, directory or URL (^ and # aren't allowed as chars)", - "placeholder":"f.e. /mp3/Audiobook/Yakari/Yakari_and_Friends.mp3" - }, - "playmode":{ - "title":"Playmode", - "placeholder":"Select mode", - "mode":{ - "1":"Single track", - "2":"Single track (loop)", - "12":"Single track of a directory (random). Followed by sleep.", - "3":"Audiobook", - "4":"Audiobook (loop)", - "5":"All tracks of a directory (sorted)", - "6":"All tracks of a directory (random)", - "7":"All tracks of a directory (sorted, loop)", - "9":"All tracks of a directory (random, loop)", - "13":"All tracks of a random subdirectory (sorted)", - "14":"All tracks of a random subdirectory (random)", - "8":"Webradio", - "11":"List (files from SD and/or webstreams) from local .m3u-File" - }, - "error":"Invalid playmode" - }, - "mod":{ - "title":"Mod", - "placeholder":"Select modification", - "cmd":{ - "100":"Keylock", - "179":"Sleep immediately", - "101":"Sleep after 15 minutes", - "102":"Sleep after 30 minutes", - "103":"Sleep after 1 hour", - "104":"Sleep after 2 hours", - "105":"Sleep after end of track", - "106":"Sleep after end of playlist", - "107":"Sleep after end of five tracks", - "110":"Loop playlist", - "111":"Loop track", - "120":"Dimm LEDs (nightmode)", - "130":"Toggle WiFi", - "140":"Toggle Bluetooth Speaker", - "141":"Toggle Bluetooth Headphones", - "142":"Toggle Mode (Normal => BT-Speaker => Bluetooth Headphone)", - "150":"Enable FTP", - "151":"Announce IP-Address", - "152":"Announce current time", - "0":"Remove assignment", - "170":"Toggle Play/Pause", - "171":"Previous track", - "172":"Next track", - "173":"First track", - "174":"Last track", - "180":"Seek forwards (n seconds)", - "181":"Seek backwards (n seconds)" - } - } - } - }, - "mqtt":{ - "title":"MQTT-settings", - "enable":"Enable MQTT", - "clientId":{ - "title":"MQTT-ClientId", - "placeholder":"f.e. ESPuino", - "validation":"" - }, - "server":{ - "title":"MQTT-server", - "placeholder":"f.e. 192.168.2.89", - "validation":"" - }, - "user":{ - "title":"MQTT-username (optional)", - "placeholder":"username", - "validation":"" - }, - "pwd":{ - "title":"MQTT-password (optional)", - "placeholder":"password", - "validation":"" - }, - "port":{ - "title":"MQTT-port", - "placeholder":"f.e. 1883", - "validation":"" - } - }, - "ftp":{ - "title":"FTP-settings", - "user":{ - "title":"FTP-Username", - "placeholder":"username" - }, - "pwd":{ - "title":"FTP-password", - "placeholder":"password" - }, - "start":{ - "title":"Start FTP-server", - "desc":"Enables FTP-server until device is restarted.", - "button":"Start FTP-server" - } - }, - "bt":{ - "sink":{ - "title":"ESPuino as Bluetooth speaker", - "desc":"ESPuino is started as a Bluetooth speaker. After switching to this mode, the web interface will no longer be available until the system is restarted in normal mode.", - "button":"Start as Bluetooth speaker" - }, - "source":{ - "configtitle":"Bluetooth headphone settings", - "title":"Connect with Bluetooth headphone", - "desc":"The device connects to the specified Bluetooth headset. After switching to this mode, the web interface will no longer be available until the system is restarted in normal mode.", - "button":"Start in headphone mode" - }, - "device":{ - "title":"Bluetooth device (headphone)", - "placeholder":"e.g. My POGS Wireless Headphone" - }, - "pincode":{ - "title":"Pairing PIN-Code", - "placeholder":"e.g. 0000" - } - }, - "general":{ - "language":"Language", - "volume":{ - "title":"Volume", - "restart":"After restart", - "speakerMax":"Max. volume (speaker)", - "headphoneMax":"Max. volume (headphones)" - }, - "equalizer":{ - "title":"Equalizer", - "gainLowPass":"Lows (in dB)", - "gainBandPass":"Mids (in dB)", - "gainHighPass":"Highs (in dB)", - "info":"According to the library (ESP32-audioI2S), the frequencies are 500 Hz LowShelf, 3000 Hz PeakEQ and 6000 Hz HighShelf." - }, - "neopixel":{ - "title":"Neopixel (brightness)", - "restart":"After restart", - "nightmode":"For nightmode" - }, - "sleep":{ - "title":"Deep Sleep", - "inactivity":"After n minutes inactivity" - }, - "battery":{ - "title":"Battery", - "desc":"Show voltage-status via Neopixel", - "lowWarning":"Show warning below this threshold (in volt)", - "lowCritical":"Lowest voltage (in volt), that is indicated by one LED", - "criticalShutoff":"Below this voltage (in volt), ESPuino turns off", - "high":"Voltage (in volt), that is indicated by all LEDs", - "measureInterval":"Interval between measurements (in minutes)" - }, - "playlist":{ - "title":"Playlist", - "sortMode":"Sorting mode for playlist and file browser", - "strcmp":"Standard sorting", - "strnatcmp":"Natural: case-sensitive", - "strnatcasecmp":"Natural: case-insensitive" - } - }, - "tools":{ - "nvserase":{ - "title":"Erase NVS RFID-assignments", - "desc":"Via importer new entries will only be inserted but old ones won't be erased. Only in case an old assignment to the same entry already exists, it will be overwritten. With this function all existing rfid-assignments will be erased. Further infos in German language.", - "button":"Delete assignments", - "prompt":"Erase all saved NVS RFID-assignments?" - }, - "nvsdelete":{ - "title":"Remove NVS RFID-assignment", - "prompt":"Remove assignment \"{{rfid}}\" ?" - }, - "nvsimport":{ - "title":"NVS RFID-Importer", - "desc":"Backupfile can be uploaded right here in order to import NVS-RFID-assignments." - }, - "fwupdate":{ - "title":"Firmware-Update", - "desc":"Firmware can be updated right here." - } - }, - "help":{ - "forum":{ - "title":"Forum", - "desc":"Having problems or aim to discuss about ESPuino?
Join us at ESPuino-Forum! Especially there's a lot of (german) documentation online!" - }, - "swagger":{ - "title":"Swagger", - "desc":"Documentation of the REST API: Swagger." - } - }, - "datetime":{ - "day":"day", - "days":"days", - "hour":"hour", - "hours":"hours", - "minute":"minute", - "minutes":"minutes", - "second":"second", - "seconds":"seconds" - }, - "systeminfo":{ - "title":"Information", - "softwareversion":"ESPuino {{softwareversion}}", - "gitversion":"ESPuino {{gitversion}}", - "arduinoversion":"Arduino Version: {{arduinoversion}} (ESP-IDF {{idfversion}})", - "hardware":"Hardware: {{hwmodel}}, Revision {{hwrevision}}, CPU: {{hwfreq}} MHZ", - "freeheap":"Free heap: {{freeheap}} Bytes", - "largestfreeblock":"Largest free heap-block: {{largestfreeblock}} Bytes", - "freepsram":"Free PS-RAM: {{freepsram}} Bytes", - "currentip":"Current IP-Address: {{currentip}}", - "macAddress":"MAC-Address: {{macAddress}}", - "rssi":"WiFi signal strength: {{rssi}} dBm", - "audiotimetotal":"Total audio playtime since {{firststart}}: {{audiotimetotal}}", - "audiotimesincestart":"Playtime since last start: {{audiotimesincestart}}", - "currvoltage":"Current battery voltage: {{currvoltage}} V", - "chargelevel":"Current charge level: {{chargelevel}} %", - "hallsensor":"HallEffectSensor NullFieldValue: {{hsnullfieldvalue}}, actual: {{hsactual}}, diff:{{hsdiff}}, LastWaitFor_State:{{hslastwaitforstate}} (waited:{{hswaited}} ms)" - } -} +{ + "submit":"Submit", + "restart":"Restart", + "reset":"Reset", + "execute":"Execute", + "title":"ESPuino", + "shutdown":"Shutdown", + "log":"Log", + "info":"Info", + "delete":"Delete", + "cancel":"Cancel", + "refresh":"Refresh", + "ok": "OK", + "infos": "Infos", + "darkmode": "Dark Mode", + "restartinfo":"ESPuino is being restarted...
Page reloads automatically after restart finished.", + "shutdowninfo":"ESPuino is now switched off...
Page reloads automatically when the ESPuino is switched on again..", + "toast":{ + "rfidDetect":"RFID-tag {{rfidId}} detected.", + "success":"Action performed successfully.", + "conlost":"Connection to ESPuino broken! Please reload website.", + "dropout":"slow stream, dropouts are possible." + }, + "nav":{ + "control":"Control", + "rfid":"RFID", + "wifi":"WiFi", + "mqtt":"MQTT", + "ftp":"FTP", + "bluetooth":"Bluetooth", + "general":"General", + "tools":"Tools", + "help":"Help" + }, + "wifi":{ + "title":"WiFi-configuration", + "networks":"Networks", + "savedNetworks":"Saved Networks", + "ssid":{ + "title":"WiFi-name (SSID)", + "placeholder":"SSID", + "validation":"Enter WiFi's SSID" + }, + "password":{ + "title":"Password", + "placeholder":"Password", + "validation":"Enter the WiFi's password" + }, + "hostname":{ + "title":"ESPuino's name (hostname)", + "placeholder":"espuino", + "validation":"Enter a valid hostname" + }, + "static":{ + "addr":"Static IP-Address", + "enabled":"Static IP-Configuration", + "gateway":"Gateway for static IP-Configuration", + "subnet":"Subnet-mask for static IP-Configuration", + "dns1":" DNS 1 for static IP-Configuration", + "dns2":"DNS 2 for static IP-Configuration" + }, + "scan":{ + "enabled":"Start with strongest WiFi" + }, + "delete":{ + "title":"Delete WiFi", + "prompt":"Delete saved WiFi \"{{ssid}}\" ?" + }, + "restartPrompt":"Ready to go?" + }, + "control":{ + "title":"Control", + "first":"First", + "prev":"Previous", + "playpause":"Play / Pause", + "forward":"Next", + "last":"Last", + "volume":"Volume", + "voldown":"Volume Down", + "volup":"Volume Up", + "current":"Current track", + "command":"Execute Modification" + }, + "files":{ + "title":"Files", + "loading":"Please wait...", + "context":{ + "newFolder":"New Folder", + "play":"Play", + "refresh":"Refresh", + "delete":"Delete", + "rename":"Rename", + "download":"Download" + }, + "files":{ + "title":"Files", + "desc":"Upload one ore more files" + }, + "directory":{ + "title":"Directory", + "desc":"Upload directory with all files and subdirectories" + }, + "search":{ + "placeholder":"Search files.." + }, + "upload":{ + "title":"Upload", + "desc":"Start Upload", + "selectFolder":"Please select the upload location!", + "selectFile":"Please select files to upload!", + "success":"Upload successful ({{elapsed}}, {{speed}} KB/s)", + "error":"Upload error", + "timeCalc":"Remaining time is being calculated..", + "minutes_one":"minute", + "minutes_other":"minutes", + "seconds":"seconds", + "fewSec":"few", + "progress":"{{percent}}% ({{speed}} KB/s), {{remaining.value}} {{remaining.unit}} remaining.." + }, + "rfid":{ + "title":"RFID-Assignments", + "idNumber":"RFID-number (12 digits)", + "music":"Music", + "modification":"Modification", + "savedassignments":"Saved RFID-assignments", + "fileurl":{ + "title":"File, directory or URL (^ and # aren't allowed as chars)", + "placeholder":"f.e. /mp3/Audiobook/Yakari/Yakari_and_Friends.mp3" + }, + "playmode":{ + "title":"Playmode", + "placeholder":"Select mode", + "mode":{ + "1":"Single track", + "2":"Single track (loop)", + "12":"Single track of a directory (random). Followed by sleep.", + "3":"Audiobook", + "4":"Audiobook (loop)", + "5":"All tracks of a directory (sorted)", + "6":"All tracks of a directory (random)", + "7":"All tracks of a directory (sorted, loop)", + "9":"All tracks of a directory (random, loop)", + "13":"All tracks of a random subdirectory (sorted)", + "14":"All tracks of a random subdirectory (random)", + "8":"Webradio", + "11":"List (files from SD and/or webstreams) from local .m3u-File" + }, + "error":"Invalid playmode" + }, + "mod":{ + "title":"Mod", + "placeholder":"Select modification", + "cmd":{ + "100":"Keylock", + "179":"Sleep immediately", + "101":"Sleep after 15 minutes", + "102":"Sleep after 30 minutes", + "103":"Sleep after 1 hour", + "104":"Sleep after 2 hours", + "105":"Sleep after end of track", + "106":"Sleep after end of playlist", + "107":"Sleep after end of five tracks", + "110":"Loop playlist", + "111":"Loop track", + "120":"Dimm LEDs (nightmode)", + "130":"Toggle WiFi", + "140":"Toggle Bluetooth Speaker", + "141":"Toggle Bluetooth Headphones", + "142":"Toggle Mode (Normal => BT-Speaker => Bluetooth Headphone)", + "150":"Enable FTP", + "151":"Announce IP-Address", + "152":"Announce current time", + "0":"Remove assignment", + "170":"Toggle Play/Pause", + "171":"Previous track", + "172":"Next track", + "173":"First track", + "174":"Last track", + "180":"Seek forwards (n seconds)", + "181":"Seek backwards (n seconds)" + } + } + } + }, + "mqtt":{ + "title":"MQTT-settings", + "enable":"Enable MQTT", + "clientId":{ + "title":"MQTT-ClientId", + "placeholder":"f.e. ESPuino", + "validation":"" + }, + "server":{ + "title":"MQTT-server", + "placeholder":"f.e. 192.168.2.89", + "validation":"" + }, + "user":{ + "title":"MQTT-username (optional)", + "placeholder":"username", + "validation":"" + }, + "pwd":{ + "title":"MQTT-password (optional)", + "placeholder":"password", + "validation":"" + }, + "port":{ + "title":"MQTT-port", + "placeholder":"f.e. 1883", + "validation":"" + } + }, + "ftp":{ + "title":"FTP-settings", + "user":{ + "title":"FTP-Username", + "placeholder":"username" + }, + "pwd":{ + "title":"FTP-password", + "placeholder":"password" + }, + "start":{ + "title":"Start FTP-server", + "desc":"Enables FTP-server until device is restarted.", + "button":"Start FTP-server" + } + }, + "bt":{ + "sink":{ + "title":"ESPuino as Bluetooth speaker", + "desc":"ESPuino is started as a Bluetooth speaker. After switching to this mode, the web interface will no longer be available until the system is restarted in normal mode.", + "button":"Start as Bluetooth speaker" + }, + "source":{ + "configtitle":"Bluetooth headphone settings", + "title":"Connect with Bluetooth headphone", + "desc":"The device connects to the specified Bluetooth headset. After switching to this mode, the web interface will no longer be available until the system is restarted in normal mode.", + "button":"Start in headphone mode" + }, + "device":{ + "title":"Bluetooth device (headphone)", + "placeholder":"e.g. My POGS Wireless Headphone" + }, + "pincode":{ + "title":"Pairing PIN-Code", + "placeholder":"e.g. 0000" + } + }, + "general":{ + "language":"Language", + "loadingLanguage": "Loading language ...", + "volume":{ + "title":"Volume", + "restart":"After restart", + "speakerMax":"Max. volume (speaker)", + "headphoneMax":"Max. volume (headphones)" + }, + "equalizer":{ + "title":"Equalizer", + "gainLowPass":"Lows (in dB)", + "gainBandPass":"Mids (in dB)", + "gainHighPass":"Highs (in dB)", + "info":"According to the library (ESP32-audioI2S), the frequencies are 500 Hz LowShelf, 3000 Hz PeakEQ and 6000 Hz HighShelf." + }, + "neopixel":{ + "title":"Neopixel (brightness)", + "restart":"After restart", + "nightmode":"For nightmode" + }, + "sleep":{ + "title":"Deep Sleep", + "inactivity":"After n minutes inactivity" + }, + "battery":{ + "title":"Battery", + "desc":"Show voltage-status via Neopixel", + "lowWarning":"Show warning below this threshold (in volt)", + "lowCritical":"Lowest voltage (in volt), that is indicated by one LED", + "criticalShutoff":"Below this voltage (in volt), ESPuino turns off", + "high":"Voltage (in volt), that is indicated by all LEDs", + "measureInterval":"Interval between measurements (in minutes)" + }, + "playlist":{ + "title":"Playlist", + "sortMode":"Sorting mode for playlist and file browser", + "strcmp":"Standard sorting", + "strnatcmp":"Natural: case-sensitive", + "strnatcasecmp":"Natural: case-insensitive" + } + }, + "tools":{ + "nvserase":{ + "title":"Erase NVS RFID-assignments", + "desc":"Via importer new entries will only be inserted but old ones won't be erased. Only in case an old assignment to the same entry already exists, it will be overwritten. With this function all existing rfid-assignments will be erased. Further infos in German language.", + "button":"Delete assignments", + "prompt":"Erase all saved NVS RFID-assignments?" + }, + "nvsdelete":{ + "title":"Remove NVS RFID-assignment", + "prompt":"Remove assignment \"{{rfid}}\" ?" + }, + "nvsimport":{ + "title":"NVS RFID-Importer", + "desc":"Backupfile can be uploaded right here in order to import NVS-RFID-assignments." + }, + "fwupdate":{ + "title":"Firmware-Update", + "desc":"Firmware can be updated right here." + } + }, + "help":{ + "forum":{ + "title":"Forum", + "desc":"Having problems or aim to discuss about ESPuino?
Join us at ESPuino-Forum! Especially there's a lot of (german) documentation online!" + }, + "swagger":{ + "title":"Swagger", + "desc":"Documentation of the REST API: Swagger." + } + }, + "datetime":{ + "day":"day", + "days":"days", + "hour":"hour", + "hours":"hours", + "minute":"minute", + "minutes":"minutes", + "second":"second", + "seconds":"seconds" + }, + "systeminfo":{ + "title":"Information", + "softwareversion":"ESPuino {{softwareversion}}", + "gitversion":"ESPuino {{gitversion}}", + "arduinoversion":"Arduino Version: {{arduinoversion}} (ESP-IDF {{idfversion}})", + "hardware":"Hardware: {{hwmodel}}, Revision {{hwrevision}}, CPU: {{hwfreq}} MHZ", + "freeheap":"Free heap: {{freeheap}} Bytes", + "largestfreeblock":"Largest free heap-block: {{largestfreeblock}} Bytes", + "freepsram":"Free PS-RAM: {{freepsram}} Bytes", + "currentip":"Current IP-Address: {{currentip}}", + "macAddress":"MAC-Address: {{macAddress}}", + "rssi":"WiFi signal strength: {{rssi}} dBm", + "audiotimetotal":"Total audio playtime since {{firststart}}: {{audiotimetotal}}", + "audiotimesincestart":"Playtime since last start: {{audiotimesincestart}}", + "currvoltage":"Current battery voltage: {{currvoltage}} V", + "chargelevel":"Current charge level: {{chargelevel}} %", + "hallsensor":"HallEffectSensor NullFieldValue: {{hsnullfieldvalue}}, actual: {{hsactual}}, diff:{{hsdiff}}, LastWaitFor_State:{{hslastwaitforstate}} (waited:{{hswaited}} ms)" + } +} diff --git a/html/locales/fr.json b/html/locales/fr.json index 5c837515..65c07d98 100644 --- a/html/locales/fr.json +++ b/html/locales/fr.json @@ -250,6 +250,7 @@ }, "general":{ "language":"Langue", + "loadingLanguage": "Chargement de la traduction ...", "volume":{ "title":"Volume", "restart":"Après le redémarrage", diff --git a/html/management.html b/html/management.html index 81132f3d..0b77f692 100644 --- a/html/management.html +++ b/html/management.html @@ -220,10 +220,21 @@ /* Make sure the jstree context menu is most top */ z-index: 99999; } + + #splash { + z-index: 3000; + } +
+
+
+
+ Loading language ... +
+
-
-
@@ -893,8 +891,6 @@
-
-
Batterie @@ -1139,12 +1135,18 @@ // function to wrap the localize call into a reusable code block function localization() { if (localize) { - localize('body'); - // (re)initialize all popover buttons to get correct translations in the popovers - document.querySelectorAll('[data-bs-toggle="popover"]') - .forEach(popoverButton => { - new bootstrap.Popover(popoverButton, {html: true, trigger: 'focus'}) - }); + if (i18next.resolvedLanguage) { + localize('body'); + console.info('language changed to', i18next.resolvedLanguage); + // (re)initialize all popover buttons to get correct translations in the popovers + document.querySelectorAll('[data-bs-toggle="popover"]') + .forEach(popoverButton => { + new bootstrap.Popover(popoverButton, {html: true, trigger: 'focus'}) + }); + } else { + console.error("Language couldn't be loaded. Check your setup, maybe the translation files are misplaced or the remote server is not available."); + toaster.error("Language couldn't be loaded"); + } $('#splash').hide(); } } From 5a65e0074d6d4d3804ae1d5b5a34ddf99648bb9f Mon Sep 17 00:00:00 2001 From: fabian Date: Mon, 8 Jul 2024 14:21:30 +0200 Subject: [PATCH 06/18] Homogenously use `.mb-4` and `.mb-3` on tabs and adding it to `.slider-container` to reduce usage of `
` --- html/management.html | 156 ++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 83 deletions(-) diff --git a/html/management.html b/html/management.html index fcfe1071..75b19045 100644 --- a/html/management.html +++ b/html/management.html @@ -66,6 +66,7 @@ .slider-container { width: 100%; display: flex; + padding-bottom: 1rem } .slider-container-inner { @@ -242,7 +243,7 @@
-