diff --git a/deploy/apps/lang/21/bg.lang b/deploy/apps/lang/21/bg.lang index 0310faf..8b684b2 100644 --- a/deploy/apps/lang/21/bg.lang +++ b/deploy/apps/lang/21/bg.lang @@ -32,6 +32,11 @@ About the map Относно картата Accent popups Изскачащи акценти Accent popups: off Изскачащи акценти: изкл Accent popups: on Изскачащи акценти: вкл +Accent colour Акцентен цвят +Appearance Изглед +Day Ден +Night Нощ +Theme save failed Неуспешно запазване на темата Ack Ack Active Активно Add Добави @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тестови компилации: изкл Test builds: on Тестови компилации: вкл Theme Тема -Theme colour Цвят на темата Then pick a mode: После избери режим: This contact hasn't shared\na GPS position. Този контакт не е споделил\nGPS позиция. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Това устройство може да ползва Wi-Fi и Bluetooth едновременно — като самостоятелно радио и телефонен компаньон (приложение MeshCore).\n\nДвете заедно ползват повече RAM, затова включвай само нужното.\n\nНастрой ги по всяко време в Настройки. diff --git a/deploy/apps/lang/21/de.lang b/deploy/apps/lang/21/de.lang index 01acbf2..e23ea54 100644 --- a/deploy/apps/lang/21/de.lang +++ b/deploy/apps/lang/21/de.lang @@ -32,6 +32,11 @@ About the map Über die Karte Accent popups Akzent-Popups Accent popups: off Akzent-Popups: aus Accent popups: on Akzent-Popups: ein +Accent colour Akzentfarbe +Appearance Erscheinungsbild +Day Tag +Night Nacht +Theme save failed Design konnte nicht gespeichert werden Ack Ack Active Aktiv Add Hinzufügen @@ -841,7 +846,6 @@ Temperature Temperatur Test builds: off Test-Builds: aus Test builds: on Test-Builds: an Theme Thema -Theme colour Themenfarbe Then pick a mode: Dann einen Modus wählen: This contact hasn't shared\na GPS position. Dieser Kontakt hat keine\nGPS-Position geteilt. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Dieses Gerät kann Wi-Fi und Bluetooth gleichzeitig als eigenständiges Funkgerät und Telefon-Begleiter (MeshCore-App) betreiben.\n\nBeides gleichzeitig braucht mehr RAM, aktiviere also nur, was du brauchst.\n\nJederzeit in den Einstellungen einrichtbar. diff --git a/deploy/apps/lang/21/el.lang b/deploy/apps/lang/21/el.lang index 79d84ba..f009067 100644 --- a/deploy/apps/lang/21/el.lang +++ b/deploy/apps/lang/21/el.lang @@ -32,6 +32,11 @@ About the map Σχετικά με τον χάρτη Accent popups Αναδυόμενα τόνων Accent popups: off Αναδυόμενα τόνων: όχι Accent popups: on Αναδυόμενα τόνων: ναι +Accent colour Χρώμα έμφασης +Appearance Εμφάνιση +Day Ημέρα +Night Νύχτα +Theme save failed Αποτυχία αποθήκευσης θέματος Ack Ack Active Ενεργό Add Προσθήκη @@ -845,7 +850,6 @@ Temperature Θερμοκρασία Test builds: off Δοκιμαστικά builds: off Test builds: on Δοκιμαστικά builds: on Theme Θέμα -Theme colour Χρώμα θέματος Then pick a mode: Μετά επιλέξτε λειτουργία: This contact hasn't shared\na GPS position. Αυτή η επαφή δεν μοιράστηκε\nθέση GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Αυτή η συσκευή μπορεί να χρησιμοποιεί Wi-Fi και Bluetooth ταυτόχρονα, ως αυτόνομος πομποδέκτης και συνοδός τηλεφώνου (εφαρμογή MeshCore).\n\nΚαι τα δύο μαζί χρησιμοποιούν περισσότερη RAM, οπότε ενεργοποιήστε μόνο ό,τι χρειάζεστε.\n\nΡυθμίστε τα οποτεδήποτε στις Ρυθμίσεις. diff --git a/deploy/apps/lang/21/es.lang b/deploy/apps/lang/21/es.lang index 259cc14..cf26eaf 100644 --- a/deploy/apps/lang/21/es.lang +++ b/deploy/apps/lang/21/es.lang @@ -32,6 +32,11 @@ About the map Acerca del mapa Accent popups Ventanas de acentos Accent popups: off Ventanas de acentos: desactivado Accent popups: on Ventanas de acentos: activado +Accent colour Color de acento +Appearance Apariencia +Day Día +Night Noche +Theme save failed No se pudo guardar el tema Ack Ack Active Activo Add Añadir @@ -845,7 +850,6 @@ Temperature Temperatura Test builds: off Compilaciones de prueba: off Test builds: on Compilaciones de prueba: on Theme Tema -Theme colour Color del tema Then pick a mode: Luego elige un modo: This contact hasn't shared\na GPS position. Este contacto no ha compartido\nuna posición GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Este dispositivo puede usar Wi-Fi y Bluetooth a la vez, como radio independiente y compañero del teléfono (app MeshCore).\n\nUsar ambos consume más RAM, así que activa solo lo que necesites.\n\nConfigúralos cuando quieras en Ajustes. diff --git a/deploy/apps/lang/21/fr.lang b/deploy/apps/lang/21/fr.lang index d3702cd..3ae1630 100644 --- a/deploy/apps/lang/21/fr.lang +++ b/deploy/apps/lang/21/fr.lang @@ -32,6 +32,11 @@ About the map À propos de la carte Accent popups Fenêtres d'accents Accent popups: off Fenêtres d'accents : désactivé Accent popups: on Fenêtres d'accents : activé +Accent colour Couleur d'accent +Appearance Apparence +Day Jour +Night Nuit +Theme save failed Échec de l’enregistrement du thème Ack Accusé Active Actif Add Ajouter @@ -844,7 +849,6 @@ Temperature Température Test builds: off Builds de test : off Test builds: on Builds de test : on Theme Thème -Theme colour Couleur du thème Then pick a mode: Puis choisissez un mode : This contact hasn't shared\na GPS position. Ce contact n'a pas partagé\nde position GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Cet appareil peut utiliser Wi-Fi et Bluetooth en même temps, comme radio autonome et compagnon de téléphone (app MeshCore).\n\nLes deux à la fois consomment plus de RAM, n'activez que le nécessaire.\n\nRéglez-les à tout moment dans Réglages. diff --git a/deploy/apps/lang/21/hu.lang b/deploy/apps/lang/21/hu.lang index 519a3f5..f5f2866 100644 --- a/deploy/apps/lang/21/hu.lang +++ b/deploy/apps/lang/21/hu.lang @@ -32,6 +32,11 @@ About the map A térképről Accent popups Ékezetes felugró ablakok Accent popups: off Accent popups: kikapcsolva Accent popups: on Accent popups: bekapcsolva +Accent colour Kiemelőszín +Appearance Megjelenés +Day Nappali +Night Éjszakai +Theme save failed Téma mentése sikertelen Ack Ack Active Aktív Add Hozzáad @@ -861,7 +866,6 @@ Temperature Hőmérséklet Test builds: off Tesztverziók: kikapcsolva Test builds: on Tesztverziók: bekapcsolva Theme Téma -Theme colour Téma szine Then pick a mode: Majd válassz módot: This contact hasn't shared\na GPS position. Ez a kapcsolat nem osztotta meg GPS-pozícióját. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Ez az eszköz egyszerre képes Wi-Fi-t és Bluetooth-t futtatni, önálló rádióként és telefonkiegészítőként (MeshCore alkalmazás) is.\n\nA kettő egyidejű futtatása több RAM-ot fogyaszt, ezért csak azt kapcsold be, amire szükséged van.\n\nBármikor beállíthatod őket a Beállításokban. diff --git a/deploy/apps/lang/21/it.lang b/deploy/apps/lang/21/it.lang index 9f5b7fe..b6df124 100644 --- a/deploy/apps/lang/21/it.lang +++ b/deploy/apps/lang/21/it.lang @@ -32,6 +32,11 @@ About the map Informazioni sulla mappa Accent popups Popup accenti Accent popups: off Popup accenti: disattivi Accent popups: on Popup accenti: attivi +Accent colour Colore accento +Appearance Aspetto +Day Giorno +Night Notte +Theme save failed Salvataggio tema non riuscito Ack Ack Active Attivo Add Aggiungi @@ -844,7 +849,6 @@ Temperature Temperatura Test builds: off Build di test: off Test builds: on Build di test: on Theme Tema -Theme colour Colore tema Then pick a mode: Poi scegli una modalità: This contact hasn't shared\na GPS position. Questo contatto non ha condiviso\nuna posizione GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Questo dispositivo può usare Wi-Fi e Bluetooth insieme, come radio autonoma e compagno del telefono (app MeshCore).\n\nUsarli entrambi consuma più RAM, quindi attiva solo ciò che serve.\n\nConfigurali quando vuoi in Impostazioni. diff --git a/deploy/apps/lang/21/nl.lang b/deploy/apps/lang/21/nl.lang index b47a9c5..a9123aa 100644 --- a/deploy/apps/lang/21/nl.lang +++ b/deploy/apps/lang/21/nl.lang @@ -32,6 +32,11 @@ About the map Over de kaart Accent popups Accent-popups Accent popups: off Accent-popups: uit Accent popups: on Accent-popups: aan +Accent colour Accentkleur +Appearance Weergave +Day Dag +Night Nacht +Theme save failed Thema opslaan mislukt Ack Ack Active Actief Add Toevoegen @@ -842,7 +847,6 @@ Temperature Temperatuur Test builds: off Testbuilds: uit Test builds: on Testbuilds: aan Theme Thema -Theme colour Themakleur Then pick a mode: Kies daarna een modus: This contact hasn't shared\na GPS position. Dit contact heeft geen\nGPS-positie gedeeld. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Dit apparaat kan Wi-Fi en Bluetooth tegelijk draaien, als zelfstandige radio én telefoon-companion (MeshCore-app) samen.\n\nBeide tegelijk gebruikt meer RAM, dus zet alleen aan wat je nodig hebt.\n\nStel ze altijd in via Instellingen. diff --git a/deploy/apps/lang/21/pt-br.lang b/deploy/apps/lang/21/pt-br.lang index 4cb9a1b..77391f9 100644 --- a/deploy/apps/lang/21/pt-br.lang +++ b/deploy/apps/lang/21/pt-br.lang @@ -32,6 +32,11 @@ About the map Sobre o mapa Accent popups Pop-ups de acento Accent popups: off Pop-ups de acento: desligados Accent popups: on Pop-ups de acento: ligados +Accent colour Cor de destaque +Appearance Aparência +Day Dia +Night Noite +Theme save failed Falha ao salvar o tema Ack Ack Active Ativo Add Adicionar @@ -844,7 +849,6 @@ Temperature Temperatura Test builds: off Builds de teste: off Test builds: on Builds de teste: on Theme Tema -Theme colour Cor do tema Then pick a mode: Depois escolha um modo: This contact hasn't shared\na GPS position. Este contato não compartilhou\numa posição GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Este aparelho pode usar Wi-Fi e Bluetooth ao mesmo tempo, como rádio autônomo e companheiro do celular (app MeshCore).\n\nUsar os dois juntos consome mais RAM, então ligue só o que precisar.\n\nConfigure quando quiser em Ajustes. diff --git a/deploy/apps/lang/21/ro.lang b/deploy/apps/lang/21/ro.lang index 8938e04..d52cef4 100644 --- a/deploy/apps/lang/21/ro.lang +++ b/deploy/apps/lang/21/ro.lang @@ -32,6 +32,11 @@ About the map Despre hartă Accent popups Popupuri cu accente Accent popups: off Popupuri accente: oprite Accent popups: on Popupuri accente: pornite +Accent colour Culoare de accent +Appearance Aspect +Day Zi +Night Noapte +Theme save failed Salvarea temei a eșuat Ack Ack Active Activ Add Adaugă @@ -845,7 +850,6 @@ Temperature Temperatură Test builds: off Versiuni de test: oprite Test builds: on Versiuni de test: pornite Theme Temă -Theme colour Culoare temă Then pick a mode: Apoi alege un mod: This contact hasn't shared\na GPS position. Acest contact nu a partajat\no poziţie GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Acest dispozitiv poate rula Wi-Fi şi Bluetooth simultan, ca radio de sine stătător şi companion de telefon (aplicaţia MeshCore) în acelaşi timp.\n\nRularea ambelor foloseşte mai multă memorie RAM, deci porneşte doar ce îţi trebuie.\n\nLe poţi configura oricând în Setări. diff --git a/deploy/apps/lang/21/ru.lang b/deploy/apps/lang/21/ru.lang index 26e1c3f..df0be32 100644 --- a/deploy/apps/lang/21/ru.lang +++ b/deploy/apps/lang/21/ru.lang @@ -32,6 +32,11 @@ About the map О карте Accent popups Подсказки акцентов Accent popups: off Подсказки акцентов: выкл Accent popups: on Подсказки акцентов: вкл +Accent colour Акцентный цвет +Appearance Оформление +Day День +Night Ночь +Theme save failed Не удалось сохранить тему Ack Подтв. Active Активно Add Добавить @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тестовые сборки: выкл Test builds: on Тестовые сборки: вкл Theme Тема -Theme colour Цвет темы Then pick a mode: Затем выберите режим: This contact hasn't shared\na GPS position. Этот контакт не делился\nGPS-позицией. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Это устройство может использовать Wi-Fi и Bluetooth одновременно — как автономную рацию и компаньон телефона (приложение MeshCore).\n\nОба сразу используют больше ОЗУ, включайте только нужное.\n\nНастройте их в любой момент в Настройках. diff --git a/deploy/apps/lang/21/sr.lang b/deploy/apps/lang/21/sr.lang index 9a1a555..bc0ee7b 100644 --- a/deploy/apps/lang/21/sr.lang +++ b/deploy/apps/lang/21/sr.lang @@ -32,6 +32,11 @@ About the map О мапи Accent popups Искачући акценти Accent popups: off Искачући акценти: искљ Accent popups: on Искачући акценти: укљ +Accent colour Акцентна боја +Appearance Изглед +Day Дан +Night Ноћ +Theme save failed Чување теме није успело Ack Ack Active Активно Add Додај @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тест верзије: искључено Test builds: on Тест верзије: укључено Theme Тема -Theme colour Боја теме Then pick a mode: Затим изабери режим: This contact hasn't shared\na GPS position. Овај контакт није поделио\nGPS позицију. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Овај уређај може користити Wi-Fi и Bluetooth истовремено — као самостални радио и телефонски пратилац (MeshCore апликација).\n\nОба заједно троше више RAM-а, зато укључи само оно што ти треба.\n\nПодеси их било кад у Подешавањима. diff --git a/deploy/apps/lang/21/uk.lang b/deploy/apps/lang/21/uk.lang index c86c43a..c275fcf 100644 --- a/deploy/apps/lang/21/uk.lang +++ b/deploy/apps/lang/21/uk.lang @@ -32,6 +32,11 @@ About the map Про карту Accent popups Підказки акцентів Accent popups: off Підказки акцентів: вимк Accent popups: on Підказки акцентів: увімк +Accent colour Акцентний колір +Appearance Вигляд +Day День +Night Ніч +Theme save failed Не вдалося зберегти тему Ack Підтв. Active Активно Add Додати @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тестові збірки: вимк Test builds: on Тестові збірки: увімк Theme Тема -Theme colour Колір теми Then pick a mode: Потім виберіть режим: This contact hasn't shared\na GPS position. Цей контакт не ділився\nGPS-позицією. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Цей пристрій може використовувати Wi-Fi і Bluetooth одночасно — як автономну рацію та компаньйон телефона (застосунок MeshCore).\n\nОбидва разом використовують більше ОЗП, вмикайте лише потрібне.\n\nНалаштуйте їх будь-коли в Налаштуваннях. diff --git a/deploy/apps/lang/bg.lang b/deploy/apps/lang/bg.lang index 4e2b878..aec1d48 100644 --- a/deploy/apps/lang/bg.lang +++ b/deploy/apps/lang/bg.lang @@ -32,6 +32,11 @@ About the map Относно картата Accent popups Изскачащи акценти Accent popups: off Изскачащи акценти: изкл Accent popups: on Изскачащи акценти: вкл +Accent colour Акцентен цвят +Appearance Изглед +Day Ден +Night Нощ +Theme save failed Неуспешно запазване на темата Ack Ack Active Активно Add Добави @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тестови компилации: изкл Test builds: on Тестови компилации: вкл Theme Тема -Theme colour Цвят на темата Then pick a mode: После избери режим: This contact hasn't shared\na GPS position. Този контакт не е споделил\nGPS позиция. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Това устройство може да ползва Wi-Fi и Bluetooth едновременно — като самостоятелно радио и телефонен компаньон (приложение MeshCore).\n\nДвете заедно ползват повече RAM, затова включвай само нужното.\n\nНастрой ги по всяко време в Настройки. diff --git a/deploy/apps/lang/de.lang b/deploy/apps/lang/de.lang index 52de0f3..0f23f14 100644 --- a/deploy/apps/lang/de.lang +++ b/deploy/apps/lang/de.lang @@ -32,6 +32,11 @@ About the map Über die Karte Accent popups Akzent-Popups Accent popups: off Akzent-Popups: aus Accent popups: on Akzent-Popups: ein +Accent colour Akzentfarbe +Appearance Erscheinungsbild +Day Tag +Night Nacht +Theme save failed Design konnte nicht gespeichert werden Ack Ack Active Aktiv Add Hinzufügen @@ -841,7 +846,6 @@ Temperature Temperatur Test builds: off Test-Builds: aus Test builds: on Test-Builds: an Theme Thema -Theme colour Themenfarbe Then pick a mode: Dann einen Modus wählen: This contact hasn't shared\na GPS position. Dieser Kontakt hat keine\nGPS-Position geteilt. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Dieses Gerät kann Wi-Fi und Bluetooth gleichzeitig als eigenständiges Funkgerät und Telefon-Begleiter (MeshCore-App) betreiben.\n\nBeides gleichzeitig braucht mehr RAM, aktiviere also nur, was du brauchst.\n\nJederzeit in den Einstellungen einrichtbar. diff --git a/deploy/apps/lang/el.lang b/deploy/apps/lang/el.lang index bf46ee0..7914e09 100644 --- a/deploy/apps/lang/el.lang +++ b/deploy/apps/lang/el.lang @@ -32,6 +32,11 @@ About the map Σχετικά με τον χάρτη Accent popups Αναδυόμενα τόνων Accent popups: off Αναδυόμενα τόνων: όχι Accent popups: on Αναδυόμενα τόνων: ναι +Accent colour Χρώμα έμφασης +Appearance Εμφάνιση +Day Ημέρα +Night Νύχτα +Theme save failed Αποτυχία αποθήκευσης θέματος Ack Ack Active Ενεργό Add Προσθήκη @@ -845,7 +850,6 @@ Temperature Θερμοκρασία Test builds: off Δοκιμαστικά builds: off Test builds: on Δοκιμαστικά builds: on Theme Θέμα -Theme colour Χρώμα θέματος Then pick a mode: Μετά επιλέξτε λειτουργία: This contact hasn't shared\na GPS position. Αυτή η επαφή δεν μοιράστηκε\nθέση GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Αυτή η συσκευή μπορεί να χρησιμοποιεί Wi-Fi και Bluetooth ταυτόχρονα, ως αυτόνομος πομποδέκτης και συνοδός τηλεφώνου (εφαρμογή MeshCore).\n\nΚαι τα δύο μαζί χρησιμοποιούν περισσότερη RAM, οπότε ενεργοποιήστε μόνο ό,τι χρειάζεστε.\n\nΡυθμίστε τα οποτεδήποτε στις Ρυθμίσεις. diff --git a/deploy/apps/lang/es.lang b/deploy/apps/lang/es.lang index 306cd60..63499fd 100644 --- a/deploy/apps/lang/es.lang +++ b/deploy/apps/lang/es.lang @@ -32,6 +32,11 @@ About the map Acerca del mapa Accent popups Ventanas de acentos Accent popups: off Ventanas de acentos: desactivado Accent popups: on Ventanas de acentos: activado +Accent colour Color de acento +Appearance Apariencia +Day Día +Night Noche +Theme save failed No se pudo guardar el tema Ack Ack Active Activo Add Añadir @@ -845,7 +850,6 @@ Temperature Temperatura Test builds: off Compilaciones de prueba: off Test builds: on Compilaciones de prueba: on Theme Tema -Theme colour Color del tema Then pick a mode: Luego elige un modo: This contact hasn't shared\na GPS position. Este contacto no ha compartido\nuna posición GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Este dispositivo puede usar Wi-Fi y Bluetooth a la vez, como radio independiente y compañero del teléfono (app MeshCore).\n\nUsar ambos consume más RAM, así que activa solo lo que necesites.\n\nConfigúralos cuando quieras en Ajustes. diff --git a/deploy/apps/lang/fr.lang b/deploy/apps/lang/fr.lang index 3dd6c87..0d65eab 100644 --- a/deploy/apps/lang/fr.lang +++ b/deploy/apps/lang/fr.lang @@ -32,6 +32,11 @@ About the map À propos de la carte Accent popups Fenêtres d'accents Accent popups: off Fenêtres d'accents : désactivé Accent popups: on Fenêtres d'accents : activé +Accent colour Couleur d'accent +Appearance Apparence +Day Jour +Night Nuit +Theme save failed Échec de l’enregistrement du thème Ack Accusé Active Actif Add Ajouter @@ -844,7 +849,6 @@ Temperature Température Test builds: off Builds de test : off Test builds: on Builds de test : on Theme Thème -Theme colour Couleur du thème Then pick a mode: Puis choisissez un mode : This contact hasn't shared\na GPS position. Ce contact n'a pas partagé\nde position GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Cet appareil peut utiliser Wi-Fi et Bluetooth en même temps, comme radio autonome et compagnon de téléphone (app MeshCore).\n\nLes deux à la fois consomment plus de RAM, n'activez que le nécessaire.\n\nRéglez-les à tout moment dans Réglages. diff --git a/deploy/apps/lang/hu.lang b/deploy/apps/lang/hu.lang index a308148..15822ba 100644 --- a/deploy/apps/lang/hu.lang +++ b/deploy/apps/lang/hu.lang @@ -32,6 +32,11 @@ About the map A térképről Accent popups Ékezetes felugró ablakok Accent popups: off Accent popups: kikapcsolva Accent popups: on Accent popups: bekapcsolva +Accent colour Kiemelőszín +Appearance Megjelenés +Day Nappali +Night Éjszakai +Theme save failed Téma mentése sikertelen Ack Ack Active Aktív Add Hozzáad @@ -861,7 +866,6 @@ Temperature Hőmérséklet Test builds: off Tesztverziók: kikapcsolva Test builds: on Tesztverziók: bekapcsolva Theme Téma -Theme colour Téma szine Then pick a mode: Majd válassz módot: This contact hasn't shared\na GPS position. Ez a kapcsolat nem osztotta meg GPS-pozícióját. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Ez az eszköz egyszerre képes Wi-Fi-t és Bluetooth-t futtatni, önálló rádióként és telefonkiegészítőként (MeshCore alkalmazás) is.\n\nA kettő egyidejű futtatása több RAM-ot fogyaszt, ezért csak azt kapcsold be, amire szükséged van.\n\nBármikor beállíthatod őket a Beállításokban. diff --git a/deploy/apps/lang/it.lang b/deploy/apps/lang/it.lang index 51cd29b..74d1840 100644 --- a/deploy/apps/lang/it.lang +++ b/deploy/apps/lang/it.lang @@ -32,6 +32,11 @@ About the map Informazioni sulla mappa Accent popups Popup accenti Accent popups: off Popup accenti: disattivi Accent popups: on Popup accenti: attivi +Accent colour Colore accento +Appearance Aspetto +Day Giorno +Night Notte +Theme save failed Salvataggio tema non riuscito Ack Ack Active Attivo Add Aggiungi @@ -844,7 +849,6 @@ Temperature Temperatura Test builds: off Build di test: off Test builds: on Build di test: on Theme Tema -Theme colour Colore tema Then pick a mode: Poi scegli una modalità: This contact hasn't shared\na GPS position. Questo contatto non ha condiviso\nuna posizione GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Questo dispositivo può usare Wi-Fi e Bluetooth insieme, come radio autonoma e compagno del telefono (app MeshCore).\n\nUsarli entrambi consuma più RAM, quindi attiva solo ciò che serve.\n\nConfigurali quando vuoi in Impostazioni. diff --git a/deploy/apps/lang/nl.lang b/deploy/apps/lang/nl.lang index 918947c..46c746f 100644 --- a/deploy/apps/lang/nl.lang +++ b/deploy/apps/lang/nl.lang @@ -32,6 +32,11 @@ About the map Over de kaart Accent popups Accent-popups Accent popups: off Accent-popups: uit Accent popups: on Accent-popups: aan +Accent colour Accentkleur +Appearance Weergave +Day Dag +Night Nacht +Theme save failed Thema opslaan mislukt Ack Ack Active Actief Add Toevoegen @@ -842,7 +847,6 @@ Temperature Temperatuur Test builds: off Testbuilds: uit Test builds: on Testbuilds: aan Theme Thema -Theme colour Themakleur Then pick a mode: Kies daarna een modus: This contact hasn't shared\na GPS position. Dit contact heeft geen\nGPS-positie gedeeld. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Dit apparaat kan Wi-Fi en Bluetooth tegelijk draaien, als zelfstandige radio én telefoon-companion (MeshCore-app) samen.\n\nBeide tegelijk gebruikt meer RAM, dus zet alleen aan wat je nodig hebt.\n\nStel ze altijd in via Instellingen. diff --git a/deploy/apps/lang/pt-br.lang b/deploy/apps/lang/pt-br.lang index af1a394..9567ff8 100644 --- a/deploy/apps/lang/pt-br.lang +++ b/deploy/apps/lang/pt-br.lang @@ -32,6 +32,11 @@ About the map Sobre o mapa Accent popups Pop-ups de acento Accent popups: off Pop-ups de acento: desligados Accent popups: on Pop-ups de acento: ligados +Accent colour Cor de destaque +Appearance Aparência +Day Dia +Night Noite +Theme save failed Falha ao salvar o tema Ack Ack Active Ativo Add Adicionar @@ -844,7 +849,6 @@ Temperature Temperatura Test builds: off Builds de teste: off Test builds: on Builds de teste: on Theme Tema -Theme colour Cor do tema Then pick a mode: Depois escolha um modo: This contact hasn't shared\na GPS position. Este contato não compartilhou\numa posição GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Este aparelho pode usar Wi-Fi e Bluetooth ao mesmo tempo, como rádio autônomo e companheiro do celular (app MeshCore).\n\nUsar os dois juntos consome mais RAM, então ligue só o que precisar.\n\nConfigure quando quiser em Ajustes. diff --git a/deploy/apps/lang/ro.lang b/deploy/apps/lang/ro.lang index a907930..f6df846 100644 --- a/deploy/apps/lang/ro.lang +++ b/deploy/apps/lang/ro.lang @@ -32,6 +32,11 @@ About the map Despre hartă Accent popups Popupuri cu accente Accent popups: off Popupuri accente: oprite Accent popups: on Popupuri accente: pornite +Accent colour Culoare de accent +Appearance Aspect +Day Zi +Night Noapte +Theme save failed Salvarea temei a eșuat Ack Ack Active Activ Add Adaugă @@ -845,7 +850,6 @@ Temperature Temperatură Test builds: off Versiuni de test: oprite Test builds: on Versiuni de test: pornite Theme Temă -Theme colour Culoare temă Then pick a mode: Apoi alege un mod: This contact hasn't shared\na GPS position. Acest contact nu a partajat\no poziţie GPS. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Acest dispozitiv poate rula Wi-Fi şi Bluetooth simultan, ca radio de sine stătător şi companion de telefon (aplicaţia MeshCore) în acelaşi timp.\n\nRularea ambelor foloseşte mai multă memorie RAM, deci porneşte doar ce îţi trebuie.\n\nLe poţi configura oricând în Setări. diff --git a/deploy/apps/lang/ru.lang b/deploy/apps/lang/ru.lang index dceffd9..7a106eb 100644 --- a/deploy/apps/lang/ru.lang +++ b/deploy/apps/lang/ru.lang @@ -32,6 +32,11 @@ About the map О карте Accent popups Подсказки акцентов Accent popups: off Подсказки акцентов: выкл Accent popups: on Подсказки акцентов: вкл +Accent colour Акцентный цвет +Appearance Оформление +Day День +Night Ночь +Theme save failed Не удалось сохранить тему Ack Подтв. Active Активно Add Добавить @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тестовые сборки: выкл Test builds: on Тестовые сборки: вкл Theme Тема -Theme colour Цвет темы Then pick a mode: Затем выберите режим: This contact hasn't shared\na GPS position. Этот контакт не делился\nGPS-позицией. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Это устройство может использовать Wi-Fi и Bluetooth одновременно — как автономную рацию и компаньон телефона (приложение MeshCore).\n\nОба сразу используют больше ОЗУ, включайте только нужное.\n\nНастройте их в любой момент в Настройках. diff --git a/deploy/apps/lang/sr.lang b/deploy/apps/lang/sr.lang index bf3c66f..aa910aa 100644 --- a/deploy/apps/lang/sr.lang +++ b/deploy/apps/lang/sr.lang @@ -32,6 +32,11 @@ About the map О мапи Accent popups Искачући акценти Accent popups: off Искачући акценти: искљ Accent popups: on Искачући акценти: укљ +Accent colour Акцентна боја +Appearance Изглед +Day Дан +Night Ноћ +Theme save failed Чување теме није успело Ack Ack Active Активно Add Додај @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тест верзије: искључено Test builds: on Тест верзије: укључено Theme Тема -Theme colour Боја теме Then pick a mode: Затим изабери режим: This contact hasn't shared\na GPS position. Овај контакт није поделио\nGPS позицију. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Овај уређај може користити Wi-Fi и Bluetooth истовремено — као самостални радио и телефонски пратилац (MeshCore апликација).\n\nОба заједно троше више RAM-а, зато укључи само оно што ти треба.\n\nПодеси их било кад у Подешавањима. diff --git a/deploy/apps/lang/uk.lang b/deploy/apps/lang/uk.lang index 8b6b52f..d998657 100644 --- a/deploy/apps/lang/uk.lang +++ b/deploy/apps/lang/uk.lang @@ -32,6 +32,11 @@ About the map Про карту Accent popups Підказки акцентів Accent popups: off Підказки акцентів: вимк Accent popups: on Підказки акцентів: увімк +Accent colour Акцентний колір +Appearance Вигляд +Day День +Night Ніч +Theme save failed Не вдалося зберегти тему Ack Підтв. Active Активно Add Додати @@ -845,7 +850,6 @@ Temperature Температура Test builds: off Тестові збірки: вимк Test builds: on Тестові збірки: увімк Theme Тема -Theme colour Колір теми Then pick a mode: Потім виберіть режим: This contact hasn't shared\na GPS position. Цей контакт не ділився\nGPS-позицією. This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings. Цей пристрій може використовувати Wi-Fi і Bluetooth одночасно — як автономну рацію та компаньйон телефона (застосунок MeshCore).\n\nОбидва разом використовують більше ОЗП, вмикайте лише потрібне.\n\nНалаштуйте їх будь-коли в Налаштуваннях. diff --git a/src/helpers/esp32/TouchPrefsSchema.h b/src/helpers/esp32/TouchPrefsSchema.h index 4b225c1..60c4cdf 100644 --- a/src/helpers/esp32/TouchPrefsSchema.h +++ b/src/helpers/esp32/TouchPrefsSchema.h @@ -9,7 +9,7 @@ namespace TouchPrefsSchema { static constexpr uint16_t MAGIC = 0x5743; // 'WC' (WadaCfg) -static constexpr uint8_t CURRENT_VERSION = 55; // v49: fem_lna default flip on the V4-R8; v50: map tile z/x/y line off by default (no new fields); v51: console_mode (boot into the text console; new trailing field, default OFF); v52: console_monitor (show incoming messages in the console, default ON); v54: boot_wifi_time + boot_wifi_open (cold-boot saved-Wi-Fi time sync, #383; both OFF); v55: loud_alerts (resonant-pitch chime, #388; OFF) +static constexpr uint8_t CURRENT_VERSION = 56; // v49: fem_lna default flip on the V4-R8; v50: map tile z/x/y line off by default (no new fields); v51: console_mode (boot into the text console; new trailing field, default OFF); v52: console_monitor (show incoming messages in the console, default ON); v54: boot_wifi_time + boot_wifi_open (cold-boot saved-Wi-Fi time sync, #383; both OFF); v55: loud_alerts (resonant-pitch chime, #388; OFF); v56: theme_mode (Day/Night firmware theme, #296; default Night) static constexpr uint8_t BROKEN_MID_INSERT_VERSION = 44; // Persisted byte layout. New fields must be appended at the end: older blobs @@ -102,6 +102,7 @@ struct __attribute__((packed)) Config { // louder near its mechanical resonance, typically around 4 kHz, than at the // 1-2.6 kHz the chime uses. This shifts the same chime up into that band (#388). uint8_t loud_alerts; // play the notification chime at the piezo's resonant pitch + uint8_t theme_mode; // v56: 0 Night, 1 Day }; static constexpr size_t HEADER_SIZE = offsetof(Config, bright); @@ -114,10 +115,10 @@ static_assert(offsetof(Config, web_mirror) == offsetof(Config, rx_queue) + sizeo // rejection is silent: cfgFlush just returns false and every preference stops // persisting, with nothing in the log to say why. The struct grows most releases, // so guard the ceiling here rather than discover it as "settings do not save" on -// whichever board is using the file backend. About 500 bytes today. +// whichever board is using the file backend. 114 bytes today. static_assert(sizeof(Config) <= 2048, "Config exceeds the SdNvsPrefs value cap; prefs would silently stop saving"); -static_assert(offsetof(Config, loud_alerts) + sizeof(Config::loud_alerts) == sizeof(Config), +static_assert(offsetof(Config, theme_mode) + sizeof(Config::theme_mode) == sizeof(Config), "new preference fields must remain trailing"); // lang_file must stay immediately before the tail, or a v48-era blob overlays // onto the wrong bytes. Checking both ends means the next person to append is @@ -128,12 +129,18 @@ static_assert(offsetof(Config, console_mode) == static_assert(offsetof(Config, console_monitor) == offsetof(Config, console_mode) + sizeof(Config::console_mode), "console_monitor must follow console_mode"); +static_assert(offsetof(Config, kb_force_legacy) == + offsetof(Config, console_monitor) + sizeof(Config::console_monitor), + "kb_force_legacy must follow console_monitor"); static_assert(offsetof(Config, boot_wifi_time) == offsetof(Config, kb_force_legacy) + sizeof(Config::kb_force_legacy), "boot_wifi_time must follow kb_force_legacy"); static_assert(offsetof(Config, boot_wifi_open) == offsetof(Config, boot_wifi_time) + sizeof(Config::boot_wifi_time), "boot_wifi_open must follow boot_wifi_time"); +static_assert(offsetof(Config, theme_mode) == + offsetof(Config, loud_alerts) + sizeof(Config::loud_alerts), + "theme_mode must follow loud_alerts"); // Overlay a persisted blob on caller-provided defaults. Beta 57 wrote v44 with // retry_echo inserted before web_mirror, shifting every later value. That blob diff --git a/src/helpers/esp32/TouchPrefsStore.cpp b/src/helpers/esp32/TouchPrefsStore.cpp index ae3b966..428824c 100644 --- a/src/helpers/esp32/TouchPrefsStore.cpp +++ b/src/helpers/esp32/TouchPrefsStore.cpp @@ -39,6 +39,9 @@ static const char* KEY_CFG = "cfg"; static const uint16_t TOUCH_CFG_MAGIC = TouchPrefsSchema::MAGIC; static const uint8_t TOUCH_CFG_VER = TouchPrefsSchema::CURRENT_VERSION; // v2 sig_probe/poll; v3 tz_zone; v4 hide_node_name; v5 map_night/map_zoom; v6 map text/marker visibility; v7 app_grid_large; v8 ui_scale; v9 tb_keypad; v10 sleep_idle; v11 nav_keys; v12 map_zoom_buttons; v13 nav_dir_keys; v14 home_is_drawer; v15 kbd_nav default ON (one-time migrate); v16 nav_scroll_keys; v17 notify_new_contact; v18 kbd_nav OFF by default (reverses v15; T-Deck/V4 only, Tanmatsu stays on); v19 show_sensors_tab; v20 map_show_links; v21 map_style (0=OSM default, 1=OpenTopoMap); v22 tb_nav; v23 scope_direct (opt-in: scope direct/login floods to the region); v24 tb_nav default OFF (experimental); v25 fem_lna (Heltec V4.3 high-gain FEM LNA, opt-in); v26 msg_flash (flash keyboard backlight + wake screen on a new message, opt-in); v27 flood_adv_hrs + local_adv_min (periodic self-advert intervals, the standard MeshCore flood/local advert on a timer); v28 beta_updates (opt-in to test/beta firmware on the OTA update check + install); v29 ui_scale default -> Large/150% (Tanmatsu; bumps the old 100% default, leaves an explicit Large/Huge choice); v30 boot_advert (opt-in one-shot flood self-advert ~6s after boot, all boards, #76); v31 compact_chat (opt-in IRC-style dense chat rows instead of bubbles); v32 clock_floor (highest epoch handed out — monotonic send-timestamp floor across reboots, #89); v33 rx_queue (buffered LoRa receive: drain task + packet ring, experimental, default OFF); v34 web_mirror (web control panel: mirror the live UI to a phone browser + inject taps, opt-in, default OFF); v35 remote_mode (render the UI off-screen at a web resolution instead of the panel; boot mode, default OFF); v36 remote_landscape (remote mode orientation: landscape 800x480 vs portrait 480x800); v37 remote_landscape now defaults ON (remote mode = landscape/desktop by default; one-time flip of existing installs, portrait stays a toggle); v38 web_terminal (web mesh CLI terminal served on the device IP; runtime toggle, mutually exclusive with VNC, default OFF); v40 hist_sync_after (chat-history flush: consecutive off-thread write failures before the blocking loop-task fallback, 0 = never); v41 p4_antenna (T-Display P4 antenna select; now RESERVED/unused - the choice is session-only so every boot comes up on the on-board antenna); v42 hist_per_chat (max stored messages PER chat, default 250 - a busy public channel used to be able to fill the whole shared ring and drag the UI down); v43 Pager UI-size presets (reset the previously ignored large-screen default to Small once); v44 broken retry_echo mid-struct insertion; v45 moves retry_echo to the actual tail and resets the ambiguous v44 suffix; v46 app_hide; v47 MQTT hidden by default; v48 lang_file; v49 fem_lna default ON on the V4-R8 (KCT8103L FEM; one-time flip of existing installs, no new field); v50 map_show_tilexyz default OFF (tile z/x/y line hidden; one-time flip, no new field) +// v56 appends theme_mode (Night by default). It was written as v54 on the +// contributing branch; v54 and v55 were taken by boot_wifi_* and loud_alerts +// before this merged, so the field moved to the tail behind them. // Defaults (kept identical to the historical per-key defaults). static const uint16_t DEFAULT_SCREEN_TIMEOUT_S = 20; static const uint8_t DEFAULT_BRIGHTNESS = 100; @@ -139,6 +142,7 @@ static void cfgSetDefaults(TouchCfg& c) { c.boot_wifi_time = 0; // OFF: no cold-boot Wi-Fi time sync (#383) — opt-in c.boot_wifi_open = 0; // OFF: and never a saved OPEN network even then c.loud_alerts = 0; // OFF: the standard chime pitch unless asked for + c.theme_mode = 0; // Night: preserves the existing firmware appearance c.compact_chat = 0; // OFF: bubble chat layout (opt-in IRC-style dense rows) c.clock_floor = 0; // no persisted send-timestamp floor yet c.rx_queue = 1; // ON: buffered receive (test-channel default; opt-out toggle in Radio & Mesh) @@ -252,6 +256,7 @@ static void cfgLoadOrMigrate() { // a garbage 1 would spend boot time on a Wi-Fi session nobody asked for. if (stored_version < 54) { s_cfg.boot_wifi_time = 0; s_cfg.boot_wifi_open = 0; } if (stored_version < 55) { s_cfg.loud_alerts = 0; } + if (stored_version < 56) { s_cfg.theme_mode = 0; } // Night: unchanged appearance if (stored_version < 31) s_cfg.compact_chat = 0; // new trailing field: compact chat rows off by default if (stored_version < 32) s_cfg.clock_floor = 0; // new trailing field: no send-timestamp floor persisted yet (#89) if (stored_version < 33) s_cfg.rx_queue = 1; // buffered LoRa receive ON for the test channel (opt-out toggle in Radio & Mesh) @@ -844,6 +849,19 @@ bool touchPrefsSetAccentColor(uint32_t rgb) { return cfgFlush(); } +uint8_t touchPrefsGetThemeMode() { + if (!s_begun) touchPrefsBegin(); + return s_cfg.theme_mode == TOUCH_THEME_DAY ? TOUCH_THEME_DAY : TOUCH_THEME_NIGHT; +} +bool touchPrefsSetThemeMode(uint8_t mode) { + if (!s_begun) touchPrefsBegin(); + const uint8_t old_mode = s_cfg.theme_mode; + s_cfg.theme_mode = mode == TOUCH_THEME_DAY ? TOUCH_THEME_DAY : TOUCH_THEME_NIGHT; + if (cfgFlush()) return true; + s_cfg.theme_mode = old_mode; + return false; +} + // Quick-reply macros. Stored as NVS strings keyed "qr0".."qr5". // Default factory set on first read so the picker isn't useless out of the // box and the user has examples to edit. diff --git a/src/helpers/esp32/TouchPrefsStore.h b/src/helpers/esp32/TouchPrefsStore.h index 4d1a9a9..d3a2b72 100644 --- a/src/helpers/esp32/TouchPrefsStore.h +++ b/src/helpers/esp32/TouchPrefsStore.h @@ -9,6 +9,9 @@ #include #include // size_t (blob helpers below) +static constexpr uint8_t TOUCH_THEME_NIGHT = 0; +static constexpr uint8_t TOUCH_THEME_DAY = 1; + void touchPrefsBegin(); // Force a fresh load of the settings blob. Call after SdNvsPrefs::useFile() at // boot: an earlier pref read may have cached the blob from the legacy backend. @@ -27,6 +30,10 @@ bool touchPrefsSetScreenTimeoutSecs(uint16_t seconds); uint8_t touchPrefsGetBrightness(); bool touchPrefsSetBrightness(uint8_t pct); +/** Firmware palette: 0 = Night (default), 1 = Day. Applied after restart. */ +uint8_t touchPrefsGetThemeMode(); +bool touchPrefsSetThemeMode(uint8_t mode); + /** Keyboard backlight mode: 0 = off, 1 = on, 2 = auto (on while typing). Default auto. */ uint8_t touchPrefsGetKbBacklight(); bool touchPrefsSetKbBacklight(uint8_t mode); diff --git a/src/ui-touch/ConsoleUI.cpp b/src/ui-touch/ConsoleUI.cpp index 1ced2d3..02bfbac 100644 --- a/src/ui-touch/ConsoleUI.cpp +++ b/src/ui-touch/ConsoleUI.cpp @@ -164,11 +164,28 @@ uint8_t ringGetSpl2(int i) { // and the greens were unreadable. Owning both ends removes the dependency on // which definition happens to win at link time. #define RGB565(r, g, b) ((uint16_t)((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3))) -constexpr uint16_t kBg = RGB565(0x0E, 0x12, 0x16); // the firmware's near-black +bool s_day_theme = false; +uint16_t consoleBg() { + return s_day_theme ? RGB565(0xF1, 0xF4, 0xF6) : RGB565(0x0E, 0x12, 0x16); +} uint16_t colourFor(uint8_t c) { // e-ink has one ink colour; anything else is invisible or dithered. if (s_disp && s_disp->isEink()) return UIColor::primary_txt; + if (s_day_theme) { + switch (c) { + case CC_DIM: return RGB565(0x56, 0x60, 0x6C); + case CC_ECHO: + case CC_OK: return RGB565(0x27, 0x67, 0x38); + case CC_WARN: return RGB565(0x80, 0x60, 0x00); + case CC_ERR: return RGB565(0xA5, 0x2B, 0x26); + case CC_CHAN: return RGB565(0x1F, 0x5F, 0x9E); + case CC_SENDER: return RGB565(0x8A, 0x5A, 0x00); + case CC_DM: return RGB565(0x68, 0x42, 0xA0); + case CC_HEAD: return RGB565(0x08, 0x77, 0x6D); + default: return RGB565(0x17, 0x20, 0x26); + } + } switch (c) { case CC_DIM: return RGB565(0x7A, 0x7F, 0x87); // grey, the theme's "sub" case CC_ECHO: return RGB565(0x53, 0xC0, 0x6B); // green, the shell-echo convention @@ -321,7 +338,7 @@ void measure() { // ---- render ----------------------------------------------------------------- void render() { if (!s_disp || !s_active) return; - s_disp->startFrame(kBg); + s_disp->startFrame(consoleBg()); s_disp->setTextSize(1); // Oldest-first from the scroll position, newest at the bottom. @@ -410,7 +427,7 @@ void drawInputLine(bool cursor_on) { const int iy = s_disp->height() - s_line_h; #endif // Clear only this row. fillScreen would take the scrollback and keypad with it. - s_disp->setColor(kBg); + s_disp->setColor(consoleBg()); s_disp->fillRect(0, iy, s_disp->width(), s_line_h); s_disp->setTextSize(1); @@ -452,7 +469,7 @@ void drawInputLine(bool cursor_on) { // Toggle just the cursor cell. Two fillRects, no text, no clear. void drawCursorOnly(bool on) { if (!s_disp) return; - s_disp->setColor(on ? colourFor(CC_TEXT) : kBg); + s_disp->setColor(on ? colourFor(CC_TEXT) : consoleBg()); s_disp->fillRect(s_cur_x, s_cur_y, s_char_w, s_line_h); } @@ -705,6 +722,9 @@ void submit() { void consoleBegin(DisplayDriver* d) { s_disp = d; if (!s_disp) return; +#if defined(ESP32) + s_day_theme = touchPrefsGetThemeMode() == TOUCH_THEME_DAY; +#endif if (!s_ring) { const size_t bytes = (size_t)kMaxLines * (kLineCap + 1); #if defined(ESP32) diff --git a/src/ui-touch/UITask.cpp b/src/ui-touch/UITask.cpp index c157465..e09030f 100644 --- a/src/ui-touch/UITask.cpp +++ b/src/ui-touch/UITask.cpp @@ -612,13 +612,9 @@ static uint32_t COLOR_SECONDARY_ACTION = kNightPalette.secondary_action; static uint32_t COLOR_TRACK = kNightPalette.track; static uint32_t COLOR_CHART_BG = kNightPalette.chart_bg; -// Day/Night belongs to the 296-day-night-theme branch, whose TouchPrefsStore -// half (the TOUCH_THEME_* modes and their accessors) is not on this branch. The -// UI is pinned to the night palette until that branch lands: s_theme_day stays -// false, so every `s_theme_day ? day : night` site below resolves to night. -static void applyThemeMode() { - s_theme_day = false; - const TouchPalette& p = kNightPalette; +static void applyThemeMode(uint8_t mode) { + s_theme_day = mode == TOUCH_THEME_DAY; + const TouchPalette& p = s_theme_day ? kDayPalette : kNightPalette; COLOR_BG = p.bg; COLOR_PANEL = p.panel; COLOR_TEXT = p.text; @@ -13070,6 +13066,22 @@ static void pagerKbBlCycleCb(lv_event_t* e) { } #endif +static void themeModeRestart(uint8_t mode) { +#if defined(ESP32) + if (touchPrefsGetThemeMode() == mode) return; + if (!touchPrefsSetThemeMode(mode)) { + if (g_lv.task) g_lv.task->showAlert(TR("Theme save failed"), 1600); + return; + } +#endif + if (g_lv.task) g_lv.task->rebootDevice(); +} + +static void themeModeSelectCb(lv_event_t* e) { + if (lv_event_get_code(e) != LV_EVENT_CLICKED) return; + themeModeRestart((uint8_t)(uintptr_t)lv_event_get_user_data(e)); +} + static void buildDeviceSettings(int sec) { // One detail page per section: each block below is gated to its DSEC_* section // (skipped blocks don't advance y, so every page lays out from the top). @@ -13638,6 +13650,37 @@ static void buildDeviceSettings(int sec) { } #endif + /* Firmware appearance: selecting a different palette saves and restarts so + every LVGL object is rebuilt with one coherent set of colours. */ + { + y += settingsRowLabel(body, y, 0, TR("Appearance"), COLOR_SUB, &g_font_12, 0) + 4; + const uint8_t current = touchPrefsGetThemeMode(); + const lv_coord_t gap = 4; + const lv_coord_t row_w = s_settings_content_w - 2; + const lv_coord_t button_w = (row_w - gap) / 2; + const char* labels[2] = { TR("Night"), TR("Day") }; + for (uint8_t mode = TOUCH_THEME_NIGHT; mode <= TOUCH_THEME_DAY; ++mode) { + lv_obj_t* button = lv_btn_create(body); + lv_obj_set_size(button, button_w, SC(34)); + lv_obj_set_pos(button, 2 + mode * (button_w + gap), y); + styleButton(button); + if (mode == current) { + lv_obj_set_style_bg_opa(button, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_border_opa(button, LV_OPA_COVER, LV_PART_MAIN); + } + lv_obj_set_style_text_color(button, + lv_color_hex(mode == current ? COLOR_ON_ACCENT : COLOR_TEXT), LV_PART_MAIN); + lv_obj_add_event_cb(button, themeModeSelectCb, LV_EVENT_CLICKED, + (void*)(uintptr_t)mode); + lv_obj_t* label = lv_label_create(button); + char text[32]; + snprintf(text, sizeof(text), "%s%s", mode == current ? LV_SYMBOL_OK " " : "", labels[mode]); + lv_label_set_text(label, text); + lv_obj_center(label); + } + y += SC(42); + } + /* Accent colour: opens a colour-wheel + hex picker. */ { y += settingsRowLabel(body, y, 0, TR("Accent colour"), COLOR_SUB, &g_font_12, 0) + 4; @@ -20009,6 +20052,14 @@ static lv_obj_t* openFullscreenView(const char* title) { lv_obj_set_size(home, 40, 28); lv_obj_align(home, LV_ALIGN_TOP_RIGHT, -6, 4); styleButton(home); +#if !defined(HAS_TANMATSU) + if (s_theme_day) { + lv_obj_set_style_bg_color(home, lv_color_hex(COLOR_ACCENT_PRESS), LV_PART_MAIN); + lv_obj_set_style_bg_opa(home, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_text_color(home, lv_color_hex(COLOR_ON_ACCENT), LV_PART_MAIN); + lv_obj_set_style_border_opa(home, LV_OPA_COVER, LV_PART_MAIN); + } +#endif lv_obj_add_event_cb(home, fullscreenHomeCb, LV_EVENT_CLICKED, nullptr); lv_obj_t* hl = lv_label_create(home); useChainedFont(hl); @@ -20017,6 +20068,7 @@ static lv_obj_t* openFullscreenView(const char* title) { lv_obj_set_style_text_color(hl, lv_color_hex(0xE05544), LV_PART_MAIN); #else lv_label_set_text(hl, LV_SYMBOL_HOME); + if (s_theme_day) lv_obj_set_style_text_font(hl, &g_font_16, LV_PART_MAIN); #endif lv_obj_center(hl); lv_obj_move_foreground(home); @@ -40617,6 +40669,13 @@ static void ccGpsNoneCb(lv_event_t* e) { g_lv.task->showAlert(TR("No onboard GPS"), 1200); } #endif +// Day/Night chip: persist the opposite palette and rebuild the complete UI on restart. +static void ccThemeCb(lv_event_t* e) { + if (lv_event_get_code(e) != LV_EVENT_CLICKED) return; + closeControlCenter(); + themeModeRestart(s_theme_day ? TOUCH_THEME_NIGHT : TOUCH_THEME_DAY); +} + #if defined(HAS_THINKNODE_M9) || defined(TLORA_PAGER) static uint8_t s_cc_screenshot_delay_s = 3; static lv_timer_t* s_cc_screenshot_timer = nullptr; @@ -41589,6 +41648,8 @@ static void openControlCenter() { // settings reorg gave GPS its own category (the GPS block used to live under radio/device). ccToggle(row, LV_SYMBOL_GPS, TR("GPS"), gps_on, ccGpsCb, tw, th, CAT_GPS); #endif + ccToggle(row, s_theme_day ? TOUCH_SYM_SUN : TOUCH_SYM_MOON, TR("Theme"), s_theme_day, + ccThemeCb, tw, th, CAT_DISPLAY); #if CAP_KEYBOARD // Keyboard-backlight chip: the keyboard glyph WITH its off/on/auto mode word beneath it, // so the mode stays visible at a glance (sub_text stacks a small caption under the icon). @@ -47123,7 +47184,7 @@ static void buildUiTree() { // Load the saved theme accent before any widget is built so the whole tree // adopts it. g_lv.tabview/keyboard are still null here, so applyAccent only // sets the colour globals (no live re-style needed at boot). - applyThemeMode(); + applyThemeMode(touchPrefsGetThemeMode()); applyAccent(touchPrefsGetAccentColor()); lv_obj_t* root = lv_scr_act(); @@ -53338,7 +53399,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no // accent itself), so without this its accent-tinted glyphs — the Wi-Fi/Bluetooth // icons — would freeze the compile-time default instead of the user's colour. // Idempotent: buildUiTree's own call just re-sets the same globals. - applyThemeMode(); + applyThemeMode(touchPrefsGetThemeMode()); applyAccent(touchPrefsGetAccentColor()); // Build the always-on top status bar AFTER the display driver is diff --git a/src/ui-touch/i18n_builtin.h b/src/ui-touch/i18n_builtin.h index c908fc9..1f9543a 100644 --- a/src/ui-touch/i18n_builtin.h +++ b/src/ui-touch/i18n_builtin.h @@ -32,6 +32,7 @@ static const I18nPair kBuiltin_hu[] = { { "About", "Névjegy" }, { "About / credits", "Névjegy / köszönet" }, { "About the map", "A térképről" }, + { "Accent colour", "Kiemelőszín" }, { "Accent popups", "Ékezetes felugró ablakok" }, { "Accent popups: off", "Accent popups: kikapcsolva" }, { "Accent popups: on", "Accent popups: bekapcsolva" }, @@ -60,6 +61,7 @@ static const I18nPair kBuiltin_hu[] = { { "App drawer as home", "Alkalmazásfiók kezdőlapként" }, { "App icon size", "Alkalmazás ikon mérete" }, { "App permissions", "Appengedélyek" }, + { "Appearance", "Megjelenés" }, { "Applies after restart.", "Újraindítás után érvényes." }, { "Apply", "Alkalmaz" }, { "Apply auto-poll", "Automatikus szavazás alkalmazása" }, @@ -231,6 +233,7 @@ static const I18nPair kBuiltin_hu[] = { { "Danger zone", "Veszélyes zóna" }, { "Data -> SD card on reboot\n(card must be inserted)", "Adatok -> SD-kártya újraindításkor\n(a kártyát be kell helyezni)" }, { "Data -> internal on reboot", "Adatok -> belső újraindításkor" }, + { "Day", "Nappali" }, { "Delete", "Töröl" }, { "Delete %d contact(s)?", "%d névjegy törlése?" }, { "Delete chat", "Csevegés törlése" }, @@ -531,6 +534,7 @@ static const I18nPair kBuiltin_hu[] = { { "New game", "Új játék" }, { "New room msg", "Új szobaüzenet" }, { "Next", "Következő" }, + { "Night", "Éjszakai" }, { "Night mode (invert)", "Éjszakai mód (invertált)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Nem található .json biztonsági mentés.\nElőször exportáljon egyet, vagy másolja át a\nmeshcore-backup.json fájlt az\nSD-kártyára vagy a belső flash memóriába." }, { "No @mentions yet", "Még nincsenek @említések" }, @@ -896,7 +900,7 @@ static const I18nPair kBuiltin_hu[] = { { "Test builds: off", "Tesztverziók: kikapcsolva" }, { "Test builds: on", "Tesztverziók: bekapcsolva" }, { "Theme", "Téma" }, - { "Theme colour", "Téma szine" }, + { "Theme save failed", "Téma mentése sikertelen" }, { "Then pick a mode:", "Majd válassz módot:" }, { "This contact hasn't shared\na GPS position.", "Ez a kapcsolat nem osztotta meg GPS-pozícióját." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Ez az eszköz egyszerre képes Wi-Fi-t és Bluetooth-t futtatni, önálló rádióként és telefonkiegészítőként (MeshCore alkalmazás) is.\n\nA kettő egyidejű futtatása több RAM-ot fogyaszt, ezért csak azt kapcsold be, amire szükséged van.\n\nBármikor beállíthatod őket a Beállításokban." }, @@ -1057,6 +1061,7 @@ static const I18nPair kBuiltin_nl[] = { { "AUTOMATIC ADVERTS", "AUTOMATISCHE ADVERTS" }, { "About", "Over" }, { "About the map", "Over de kaart" }, + { "Accent colour", "Accentkleur" }, { "Accent popups", "Accent-popups" }, { "Accent popups: off", "Accent-popups: uit" }, { "Accent popups: on", "Accent-popups: aan" }, @@ -1083,6 +1088,7 @@ static const I18nPair kBuiltin_nl[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Iedereen kan deelnemen. Sleutel komt van de hashtag (kleine letters)." }, { "App drawer as home", "App-lade als startscherm" }, { "App icon size", "Grootte app-pictogrammen" }, + { "Appearance", "Weergave" }, { "Applies after restart.", "Actief na herstart." }, { "Apply", "Toepassen" }, { "Apply auto-poll", "Auto-poll toepassen" }, @@ -1245,6 +1251,7 @@ static const I18nPair kBuiltin_nl[] = { { "Danger zone", "Gevarenzone" }, { "Data -> SD card on reboot\n(card must be inserted)", "Gegevens -> SD-kaart bij herstart\n(kaart moet geplaatst zijn)" }, { "Data -> internal on reboot", "Gegevens -> intern bij herstart" }, + { "Day", "Dag" }, { "Delete", "Verwijderen" }, { "Delete %d contact(s)?", "%d contact(en) verwijderen?" }, { "Delete chat", "Chat verwijderen" }, @@ -1515,6 +1522,7 @@ static const I18nPair kBuiltin_nl[] = { { "New game", "Nieuw spel" }, { "New room msg", "Nieuw roombericht" }, { "Next", "Volgende" }, + { "Night", "Nacht" }, { "Night mode (invert)", "Nachtmodus (omkeren)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Geen .json back-ups gevonden.\nExporteer er eerst een, of kopieer\neen meshcore-backup.json naar de\nSD-kaart of interne flash." }, { "No @mentions yet", "Nog geen @vermeldingen" }, @@ -1832,7 +1840,7 @@ static const I18nPair kBuiltin_nl[] = { { "Test builds: off", "Testbuilds: uit" }, { "Test builds: on", "Testbuilds: aan" }, { "Theme", "Thema" }, - { "Theme colour", "Themakleur" }, + { "Theme save failed", "Thema opslaan mislukt" }, { "Then pick a mode:", "Kies daarna een modus:" }, { "This contact hasn't shared\na GPS position.", "Dit contact heeft geen\nGPS-positie gedeeld." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Dit apparaat kan Wi-Fi en Bluetooth tegelijk draaien, als zelfstandige radio én telefoon-companion (MeshCore-app) samen.\n\nBeide tegelijk gebruikt meer RAM, dus zet alleen aan wat je nodig hebt.\n\nStel ze altijd in via Instellingen." }, @@ -1976,6 +1984,7 @@ static const I18nPair kBuiltin_de[] = { { "AUTOMATIC ADVERTS", "AUTOMATISCHE ADVERTS" }, { "About", "Über" }, { "About the map", "Über die Karte" }, + { "Accent colour", "Akzentfarbe" }, { "Accent popups", "Akzent-Popups" }, { "Accent popups: off", "Akzent-Popups: aus" }, { "Accent popups: on", "Akzent-Popups: ein" }, @@ -2002,6 +2011,7 @@ static const I18nPair kBuiltin_de[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Jeder kann beitreten. Schlüssel aus dem Hashtag (Kleinbuchstaben)." }, { "App drawer as home", "App-Drawer als Startseite" }, { "App icon size", "App-Symbolgröße" }, + { "Appearance", "Erscheinungsbild" }, { "Applies after restart.", "Gilt nach Neustart." }, { "Apply", "Anwenden" }, { "Apply auto-poll", "Auto-Poll übernehmen" }, @@ -2168,6 +2178,7 @@ static const I18nPair kBuiltin_de[] = { { "Danger zone", "Gefahrenzone" }, { "Data -> SD card on reboot\n(card must be inserted)", "Daten -> SD-Karte bei Neustart\n(Karte muss eingelegt sein)" }, { "Data -> internal on reboot", "Daten -> intern bei Neustart" }, + { "Day", "Tag" }, { "Delete", "Löschen" }, { "Delete %d contact(s)?", "%d Kontakt(e) löschen?" }, { "Delete chat", "Chat löschen" }, @@ -2440,6 +2451,7 @@ static const I18nPair kBuiltin_de[] = { { "New game", "Neues Spiel" }, { "New room msg", "Neue Raumnachricht" }, { "Next", "Weiter" }, + { "Night", "Nacht" }, { "Night mode (invert)", "Nachtmodus (invertieren)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Keine .json-Backups gefunden.\nZuerst eins exportieren oder\nmeshcore-backup.json auf die\nSD-Karte oder den Flash kopieren." }, { "No @mentions yet", "Noch keine @Erwähnungen" }, @@ -2756,7 +2768,7 @@ static const I18nPair kBuiltin_de[] = { { "Test builds: off", "Test-Builds: aus" }, { "Test builds: on", "Test-Builds: an" }, { "Theme", "Thema" }, - { "Theme colour", "Themenfarbe" }, + { "Theme save failed", "Design konnte nicht gespeichert werden" }, { "Then pick a mode:", "Dann einen Modus wählen:" }, { "This contact hasn't shared\na GPS position.", "Dieser Kontakt hat keine\nGPS-Position geteilt." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Dieses Gerät kann Wi-Fi und Bluetooth gleichzeitig als eigenständiges Funkgerät und Telefon-Begleiter (MeshCore-App) betreiben.\n\nBeides gleichzeitig braucht mehr RAM, aktiviere also nur, was du brauchst.\n\nJederzeit in den Einstellungen einrichtbar." }, @@ -2905,6 +2917,7 @@ static const I18nPair kBuiltin_fr[] = { { "AUTOMATIC ADVERTS", "ADVERTS AUTOMATIQUES" }, { "About", "À propos" }, { "About the map", "À propos de la carte" }, + { "Accent colour", "Couleur d'accent" }, { "Accent popups", "Fenêtres d'accents" }, { "Accent popups: off", "Fenêtres d'accents : désactivé" }, { "Accent popups: on", "Fenêtres d'accents : activé" }, @@ -2932,6 +2945,7 @@ static const I18nPair kBuiltin_fr[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Tout le monde peut rejoindre. Clé dérivée du hashtag (minuscules)." }, { "App drawer as home", "Tiroir d'apps comme accueil" }, { "App icon size", "Taille des icônes d'app" }, + { "Appearance", "Apparence" }, { "Applies after restart.", "Appliqué après redémarrage." }, { "Apply", "Appliquer" }, { "Apply auto-poll", "Appliquer l'auto-poll" }, @@ -3085,6 +3099,7 @@ static const I18nPair kBuiltin_fr[] = { { "Danger zone", "Zone de danger" }, { "Data -> SD card on reboot\n(card must be inserted)", "Données -> carte SD au redémarrage\n(carte requise)" }, { "Data -> internal on reboot", "Données -> interne au redémarrage" }, + { "Day", "Jour" }, { "Delete", "Supprimer" }, { "Delete %d contact(s)?", "Supprimer %d contact(s) ?" }, { "Delete chat", "Supprimer la discussion" }, @@ -3344,6 +3359,7 @@ static const I18nPair kBuiltin_fr[] = { { "New game", "Nouvelle partie" }, { "New room msg", "Nouveau msg de salon" }, { "Next", "Suivant" }, + { "Night", "Nuit" }, { "Night mode (invert)", "Mode nuit (inverser)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Aucune sauvegarde .json trouvée.\nExportez-en une, ou copiez un\nmeshcore-backup.json sur la\ncarte SD ou le flash interne." }, { "No @mentions yet", "Aucune @mention pour l'instant" }, @@ -3649,7 +3665,7 @@ static const I18nPair kBuiltin_fr[] = { { "Test builds: off", "Builds de test : off" }, { "Test builds: on", "Builds de test : on" }, { "Theme", "Thème" }, - { "Theme colour", "Couleur du thème" }, + { "Theme save failed", "Échec de l’enregistrement du thème" }, { "Then pick a mode:", "Puis choisissez un mode :" }, { "This contact hasn't shared\na GPS position.", "Ce contact n'a pas partagé\nde position GPS." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Cet appareil peut utiliser Wi-Fi et Bluetooth en même temps, comme radio autonome et compagnon de téléphone (app MeshCore).\n\nLes deux à la fois consomment plus de RAM, n'activez que le nécessaire.\n\nRéglez-les à tout moment dans Réglages." }, @@ -3789,6 +3805,7 @@ static const I18nPair kBuiltin_es[] = { { "AUTOMATIC ADVERTS", "ADVERTS AUTOMÁTICOS" }, { "About", "Acerca de" }, { "About the map", "Acerca del mapa" }, + { "Accent colour", "Color de acento" }, { "Accent popups", "Ventanas de acentos" }, { "Accent popups: off", "Ventanas de acentos: desactivado" }, { "Accent popups: on", "Ventanas de acentos: activado" }, @@ -3815,6 +3832,7 @@ static const I18nPair kBuiltin_es[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Cualquiera puede unirse. La clave deriva del hashtag (minúsculas)." }, { "App drawer as home", "Cajón de apps como inicio" }, { "App icon size", "Tamaño de iconos de app" }, + { "Appearance", "Apariencia" }, { "Applies after restart.", "Se aplica tras reiniciar." }, { "Apply", "Aplicar" }, { "Apply auto-poll", "Aplicar auto-poll" }, @@ -3967,6 +3985,7 @@ static const I18nPair kBuiltin_es[] = { { "Danger zone", "Zona de peligro" }, { "Data -> SD card on reboot\n(card must be inserted)", "Datos -> tarjeta SD al reiniciar\n(tarjeta requerida)" }, { "Data -> internal on reboot", "Datos -> interno al reiniciar" }, + { "Day", "Día" }, { "Delete", "Eliminar" }, { "Delete %d contact(s)?", "¿Eliminar %d contacto(s)?" }, { "Delete chat", "Eliminar chat" }, @@ -4231,6 +4250,7 @@ static const I18nPair kBuiltin_es[] = { { "New game", "Partida nueva" }, { "New room msg", "Nuevo msj de sala" }, { "Next", "Siguiente" }, + { "Night", "Noche" }, { "Night mode (invert)", "Modo noche (invertir)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "No se hallaron copias .json.\nExporta una, o copia un\nmeshcore-backup.json a la\ntarjeta SD o flash interna." }, { "No @mentions yet", "Aún no hay @menciones" }, @@ -4537,7 +4557,7 @@ static const I18nPair kBuiltin_es[] = { { "Test builds: off", "Compilaciones de prueba: off" }, { "Test builds: on", "Compilaciones de prueba: on" }, { "Theme", "Tema" }, - { "Theme colour", "Color del tema" }, + { "Theme save failed", "No se pudo guardar el tema" }, { "Then pick a mode:", "Luego elige un modo:" }, { "This contact hasn't shared\na GPS position.", "Este contacto no ha compartido\nuna posición GPS." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Este dispositivo puede usar Wi-Fi y Bluetooth a la vez, como radio independiente y compañero del teléfono (app MeshCore).\n\nUsar ambos consume más RAM, así que activa solo lo que necesites.\n\nConfigúralos cuando quieras en Ajustes." }, @@ -4678,6 +4698,7 @@ static const I18nPair kBuiltin_it[] = { { "AUTOMATIC ADVERTS", "ADVERT AUTOMATICI" }, { "About", "Informazioni" }, { "About the map", "Informazioni sulla mappa" }, + { "Accent colour", "Colore accento" }, { "Accent popups", "Popup accenti" }, { "Accent popups: off", "Popup accenti: disattivi" }, { "Accent popups: on", "Popup accenti: attivi" }, @@ -4703,6 +4724,7 @@ static const I18nPair kBuiltin_it[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Chiunque può unirsi. La chiave deriva dall'hashtag (minuscolo)." }, { "App drawer as home", "Drawer app come home" }, { "App icon size", "Dimensione icone app" }, + { "Appearance", "Aspetto" }, { "Applies after restart.", "Attivo dopo il riavvio." }, { "Apply", "Applica" }, { "Apply auto-poll", "Applica auto-poll" }, @@ -4857,6 +4879,7 @@ static const I18nPair kBuiltin_it[] = { { "Danger zone", "Zona pericolosa" }, { "Data -> SD card on reboot\n(card must be inserted)", "Dati -> scheda SD al riavvio\n(scheda richiesta)" }, { "Data -> internal on reboot", "Dati -> interno al riavvio" }, + { "Day", "Giorno" }, { "Delete", "Elimina" }, { "Delete %d contact(s)?", "Eliminare %d contatti?" }, { "Delete chat", "Elimina chat" }, @@ -5119,6 +5142,7 @@ static const I18nPair kBuiltin_it[] = { { "New game", "Nuova partita" }, { "New room msg", "Nuovo msg stanza" }, { "Next", "Avanti" }, + { "Night", "Notte" }, { "Night mode (invert)", "Modalità notte (inverti)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Nessun backup .json trovato.\nEsportane uno, o copia un\nmeshcore-backup.json sulla\nscheda SD o flash interna." }, { "No @mentions yet", "Ancora nessuna @menzione" }, @@ -5423,7 +5447,7 @@ static const I18nPair kBuiltin_it[] = { { "Test builds: off", "Build di test: off" }, { "Test builds: on", "Build di test: on" }, { "Theme", "Tema" }, - { "Theme colour", "Colore tema" }, + { "Theme save failed", "Salvataggio tema non riuscito" }, { "Then pick a mode:", "Poi scegli una modalità:" }, { "This contact hasn't shared\na GPS position.", "Questo contatto non ha condiviso\nuna posizione GPS." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Questo dispositivo può usare Wi-Fi e Bluetooth insieme, come radio autonoma e compagno del telefono (app MeshCore).\n\nUsarli entrambi consuma più RAM, quindi attiva solo ciò che serve.\n\nConfigurali quando vuoi in Impostazioni." }, @@ -5565,6 +5589,7 @@ static const I18nPair kBuiltin_ru[] = { { "AUTOMATIC ADVERTS", "АВТОМАТИЧЕСКИЕ АДВЕРТЫ" }, { "About", "О программе" }, { "About the map", "О карте" }, + { "Accent colour", "Акцентный цвет" }, { "Accent popups", "Подсказки акцентов" }, { "Accent popups: off", "Подсказки акцентов: выкл" }, { "Accent popups: on", "Подсказки акцентов: вкл" }, @@ -5592,6 +5617,7 @@ static const I18nPair kBuiltin_ru[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Любой может присоединиться. Ключ из хэштега (нижний регистр)." }, { "App drawer as home", "Меню приложений как главный экран" }, { "App icon size", "Размер значков приложений" }, + { "Appearance", "Оформление" }, { "Applies after restart.", "Применяется после перезапуска." }, { "Apply", "Применить" }, { "Apply auto-poll", "Применить автоопрос" }, @@ -5746,6 +5772,7 @@ static const I18nPair kBuiltin_ru[] = { { "Danger zone", "Опасная зона" }, { "Data -> SD card on reboot\n(card must be inserted)", "Данные -> SD-карта при перезагрузке\n(нужна карта)" }, { "Data -> internal on reboot", "Данные -> внутр. при перезагрузке" }, + { "Day", "День" }, { "Delete", "Удалить" }, { "Delete %d contact(s)?", "Удалить %d контакт(ов)?" }, { "Delete chat", "Удалить чат" }, @@ -6013,6 +6040,7 @@ static const I18nPair kBuiltin_ru[] = { { "New game", "Новая игра" }, { "New room msg", "Новое сообщ. комнаты" }, { "Next", "Далее" }, + { "Night", "Ночь" }, { "Night mode (invert)", "Ночной режим (инверсия)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Резервные копии .json не найдены.\nЭкспортируйте одну или скопируйте\nmeshcore-backup.json на\nSD-карту или внутр. флеш." }, { "No @mentions yet", "Пока нет @упоминаний" }, @@ -6320,7 +6348,7 @@ static const I18nPair kBuiltin_ru[] = { { "Test builds: off", "Тестовые сборки: выкл" }, { "Test builds: on", "Тестовые сборки: вкл" }, { "Theme", "Тема" }, - { "Theme colour", "Цвет темы" }, + { "Theme save failed", "Не удалось сохранить тему" }, { "Then pick a mode:", "Затем выберите режим:" }, { "This contact hasn't shared\na GPS position.", "Этот контакт не делился\nGPS-позицией." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Это устройство может использовать Wi-Fi и Bluetooth одновременно — как автономную рацию и компаньон телефона (приложение MeshCore).\n\nОба сразу используют больше ОЗУ, включайте только нужное.\n\nНастройте их в любой момент в Настройках." }, @@ -6465,6 +6493,7 @@ static const I18nPair kBuiltin_uk[] = { { "AUTOMATIC ADVERTS", "АВТОМАТИЧНІ АДВЕРТИ" }, { "About", "Про програму" }, { "About the map", "Про карту" }, + { "Accent colour", "Акцентний колір" }, { "Accent popups", "Підказки акцентів" }, { "Accent popups: off", "Підказки акцентів: вимк" }, { "Accent popups: on", "Підказки акцентів: увімк" }, @@ -6492,6 +6521,7 @@ static const I18nPair kBuiltin_uk[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Будь-хто може приєднатися. Ключ із хештегу (нижній регістр)." }, { "App drawer as home", "Меню додатків як головний екран" }, { "App icon size", "Розмір значків додатків" }, + { "Appearance", "Вигляд" }, { "Applies after restart.", "Діє після перезапуску." }, { "Apply", "Застосувати" }, { "Apply auto-poll", "Застосувати автоопитування" }, @@ -6646,6 +6676,7 @@ static const I18nPair kBuiltin_uk[] = { { "Danger zone", "Небезпечна зона" }, { "Data -> SD card on reboot\n(card must be inserted)", "Дані -> SD-картка при перезавантаженні\n(потрібна картка)" }, { "Data -> internal on reboot", "Дані -> внутр. при перезавантаженні" }, + { "Day", "День" }, { "Delete", "Видалити" }, { "Delete %d contact(s)?", "Видалити %d контакт(ів)?" }, { "Delete chat", "Видалити чат" }, @@ -6913,6 +6944,7 @@ static const I18nPair kBuiltin_uk[] = { { "New game", "Нова гра" }, { "New room msg", "Нове повід. кімнати" }, { "Next", "Далі" }, + { "Night", "Ніч" }, { "Night mode (invert)", "Нічний режим (інверсія)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Резервних копій .json не знайдено.\nЕкспортуйте одну або скопіюйте\nmeshcore-backup.json на\nSD-картку чи внутр. флеш." }, { "No @mentions yet", "Поки що немає @згадок" }, @@ -7220,7 +7252,7 @@ static const I18nPair kBuiltin_uk[] = { { "Test builds: off", "Тестові збірки: вимк" }, { "Test builds: on", "Тестові збірки: увімк" }, { "Theme", "Тема" }, - { "Theme colour", "Колір теми" }, + { "Theme save failed", "Не вдалося зберегти тему" }, { "Then pick a mode:", "Потім виберіть режим:" }, { "This contact hasn't shared\na GPS position.", "Цей контакт не ділився\nGPS-позицією." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Цей пристрій може використовувати Wi-Fi і Bluetooth одночасно — як автономну рацію та компаньйон телефона (застосунок MeshCore).\n\nОбидва разом використовують більше ОЗП, вмикайте лише потрібне.\n\nНалаштуйте їх будь-коли в Налаштуваннях." }, @@ -7364,6 +7396,7 @@ static const I18nPair kBuiltin_bg[] = { { "AUTOMATIC ADVERTS", "АВТОМАТИЧНИ АДВЕРТИ" }, { "About", "Относно" }, { "About the map", "Относно картата" }, + { "Accent colour", "Акцентен цвят" }, { "Accent popups", "Изскачащи акценти" }, { "Accent popups: off", "Изскачащи акценти: изкл" }, { "Accent popups: on", "Изскачащи акценти: вкл" }, @@ -7390,6 +7423,7 @@ static const I18nPair kBuiltin_bg[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Всеки може да се присъедини. Ключът е от хаштага (малки букви)." }, { "App drawer as home", "Меню с приложения като начален екран" }, { "App icon size", "Размер на иконите на приложенията" }, + { "Appearance", "Изглед" }, { "Applies after restart.", "Прилага се след рестарт." }, { "Apply", "Приложи" }, { "Apply auto-poll", "Приложи авто-запитване" }, @@ -7544,6 +7578,7 @@ static const I18nPair kBuiltin_bg[] = { { "Danger zone", "Опасна зона" }, { "Data -> SD card on reboot\n(card must be inserted)", "Данни -> SD карта при рестарт\n(нужна е карта)" }, { "Data -> internal on reboot", "Данни -> вътрешна при рестарт" }, + { "Day", "Ден" }, { "Delete", "Изтрий" }, { "Delete %d contact(s)?", "Изтриване на %d контакт(а)?" }, { "Delete chat", "Изтрий чата" }, @@ -7811,6 +7846,7 @@ static const I18nPair kBuiltin_bg[] = { { "New game", "Нова игра" }, { "New room msg", "Ново съобщ. в стая" }, { "Next", "Напред" }, + { "Night", "Нощ" }, { "Night mode (invert)", "Нощен режим (инвертиране)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Няма намерени .json архиви.\nЕкспортирайте един или копирайте\nmeshcore-backup.json на\nSD картата или вътр. флаш." }, { "No @mentions yet", "Още няма @споменавания" }, @@ -8118,7 +8154,7 @@ static const I18nPair kBuiltin_bg[] = { { "Test builds: off", "Тестови компилации: изкл" }, { "Test builds: on", "Тестови компилации: вкл" }, { "Theme", "Тема" }, - { "Theme colour", "Цвят на темата" }, + { "Theme save failed", "Неуспешно запазване на темата" }, { "Then pick a mode:", "После избери режим:" }, { "This contact hasn't shared\na GPS position.", "Този контакт не е споделил\nGPS позиция." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Това устройство може да ползва Wi-Fi и Bluetooth едновременно — като самостоятелно радио и телефонен компаньон (приложение MeshCore).\n\nДвете заедно ползват повече RAM, затова включвай само нужното.\n\nНастрой ги по всяко време в Настройки." }, @@ -8262,6 +8298,7 @@ static const I18nPair kBuiltin_sr[] = { { "AUTOMATIC ADVERTS", "АУТОМАТСКИ АДВЕРТИ" }, { "About", "О програму" }, { "About the map", "О мапи" }, + { "Accent colour", "Акцентна боја" }, { "Accent popups", "Искачући акценти" }, { "Accent popups: off", "Искачући акценти: искљ" }, { "Accent popups: on", "Искачући акценти: укљ" }, @@ -8288,6 +8325,7 @@ static const I18nPair kBuiltin_sr[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Свако може да се придружи. Кључ из хаштага (мала слова)." }, { "App drawer as home", "Фиока апликација као почетни екран" }, { "App icon size", "Величина икона апликација" }, + { "Appearance", "Изглед" }, { "Applies after restart.", "Важи након рестарта." }, { "Apply", "Примени" }, { "Apply auto-poll", "Примени ауто-упит" }, @@ -8442,6 +8480,7 @@ static const I18nPair kBuiltin_sr[] = { { "Danger zone", "Опасна зона" }, { "Data -> SD card on reboot\n(card must be inserted)", "Подаци -> SD картица при рестарту\n(потребна картица)" }, { "Data -> internal on reboot", "Подаци -> интерно при рестарту" }, + { "Day", "Дан" }, { "Delete", "Обриши" }, { "Delete %d contact(s)?", "Обрисати %d контакт(а)?" }, { "Delete chat", "Обриши ћаскање" }, @@ -8709,6 +8748,7 @@ static const I18nPair kBuiltin_sr[] = { { "New game", "Нова игра" }, { "New room msg", "Нова порука собе" }, { "Next", "Даље" }, + { "Night", "Ноћ" }, { "Night mode (invert)", "Ноћни режим (инвертуј)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Нема .json резервних копија.\nИзвезите једну или копирајте\nmeshcore-backup.json на\nSD картицу или интерни флеш." }, { "No @mentions yet", "Још нема @помена" }, @@ -9016,7 +9056,7 @@ static const I18nPair kBuiltin_sr[] = { { "Test builds: off", "Тест верзије: искључено" }, { "Test builds: on", "Тест верзије: укључено" }, { "Theme", "Тема" }, - { "Theme colour", "Боја теме" }, + { "Theme save failed", "Чување теме није успело" }, { "Then pick a mode:", "Затим изабери режим:" }, { "This contact hasn't shared\na GPS position.", "Овај контакт није поделио\nGPS позицију." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Овај уређај може користити Wi-Fi и Bluetooth истовремено — као самостални радио и телефонски пратилац (MeshCore апликација).\n\nОба заједно троше више RAM-а, зато укључи само оно што ти треба.\n\nПодеси их било кад у Подешавањима." }, @@ -9160,6 +9200,7 @@ static const I18nPair kBuiltin_el[] = { { "AUTOMATIC ADVERTS", "ΑΥΤΟΜΑΤΑ ADVERTS" }, { "About", "Σχετικά" }, { "About the map", "Σχετικά με τον χάρτη" }, + { "Accent colour", "Χρώμα έμφασης" }, { "Accent popups", "Αναδυόμενα τόνων" }, { "Accent popups: off", "Αναδυόμενα τόνων: όχι" }, { "Accent popups: on", "Αναδυόμενα τόνων: ναι" }, @@ -9186,6 +9227,7 @@ static const I18nPair kBuiltin_el[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Όλοι μπορούν να συμμετάσχουν. Κλειδί από το hashtag (πεζά)." }, { "App drawer as home", "Συρτάρι εφαρμογών ως αρχική" }, { "App icon size", "Μέγεθος εικονιδίων εφαρμογών" }, + { "Appearance", "Εμφάνιση" }, { "Applies after restart.", "Ισχύει μετά την επανεκκίνηση." }, { "Apply", "Εφαρμογή" }, { "Apply auto-poll", "Εφαρμογή auto-poll" }, @@ -9340,6 +9382,7 @@ static const I18nPair kBuiltin_el[] = { { "Danger zone", "Ζώνη κινδύνου" }, { "Data -> SD card on reboot\n(card must be inserted)", "Δεδομένα -> κάρτα SD στην επανεκκίνηση\n(απαιτείται κάρτα)" }, { "Data -> internal on reboot", "Δεδομένα -> εσωτερικά στην επανεκκίνηση" }, + { "Day", "Ημέρα" }, { "Delete", "Διαγραφή" }, { "Delete %d contact(s)?", "Διαγραφή %d επαφών;" }, { "Delete chat", "Διαγραφή συνομιλίας" }, @@ -9605,6 +9648,7 @@ static const I18nPair kBuiltin_el[] = { { "New game", "Νέο παιχνίδι" }, { "New room msg", "Νέο μήνυμα δωματίου" }, { "Next", "Επόμενο" }, + { "Night", "Νύχτα" }, { "Night mode (invert)", "Νυχτερινή λειτουργία (αντιστροφή)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Δεν βρέθηκαν αντίγραφα .json.\nΕξαγάγετε ένα ή αντιγράψτε\nmeshcore-backup.json στην\nκάρτα SD ή στο εσωτ. flash." }, { "No @mentions yet", "Καμία @αναφορά ακόμη" }, @@ -9911,7 +9955,7 @@ static const I18nPair kBuiltin_el[] = { { "Test builds: off", "Δοκιμαστικά builds: off" }, { "Test builds: on", "Δοκιμαστικά builds: on" }, { "Theme", "Θέμα" }, - { "Theme colour", "Χρώμα θέματος" }, + { "Theme save failed", "Αποτυχία αποθήκευσης θέματος" }, { "Then pick a mode:", "Μετά επιλέξτε λειτουργία:" }, { "This contact hasn't shared\na GPS position.", "Αυτή η επαφή δεν μοιράστηκε\nθέση GPS." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Αυτή η συσκευή μπορεί να χρησιμοποιεί Wi-Fi και Bluetooth ταυτόχρονα, ως αυτόνομος πομποδέκτης και συνοδός τηλεφώνου (εφαρμογή MeshCore).\n\nΚαι τα δύο μαζί χρησιμοποιούν περισσότερη RAM, οπότε ενεργοποιήστε μόνο ό,τι χρειάζεστε.\n\nΡυθμίστε τα οποτεδήποτε στις Ρυθμίσεις." }, @@ -10054,6 +10098,7 @@ static const I18nPair kBuiltin_pt_br[] = { { "AUTOMATIC ADVERTS", "ADVERTS AUTOMÁTICOS" }, { "About", "Sobre" }, { "About the map", "Sobre o mapa" }, + { "Accent colour", "Cor de destaque" }, { "Accent popups", "Pop-ups de acento" }, { "Accent popups: off", "Pop-ups de acento: desligados" }, { "Accent popups: on", "Pop-ups de acento: ligados" }, @@ -10079,6 +10124,7 @@ static const I18nPair kBuiltin_pt_br[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Qualquer um pode entrar. A chave vem da hashtag (minúsculas)." }, { "App drawer as home", "Gaveta de apps como tela inicial" }, { "App icon size", "Tamanho dos ícones de apps" }, + { "Appearance", "Aparência" }, { "Applies after restart.", "Aplica-se após reiniciar." }, { "Apply", "Aplicar" }, { "Apply auto-poll", "Aplicar auto-poll" }, @@ -10229,6 +10275,7 @@ static const I18nPair kBuiltin_pt_br[] = { { "Danger zone", "Zona de perigo" }, { "Data -> SD card on reboot\n(card must be inserted)", "Dados -> cartão SD ao reiniciar\n(cartão deve estar inserido)" }, { "Data -> internal on reboot", "Dados -> interno ao reiniciar" }, + { "Day", "Dia" }, { "Delete", "Excluir" }, { "Delete %d contact(s)?", "Excluir %d contato(s)?" }, { "Delete chat", "Excluir conversa" }, @@ -10489,6 +10536,7 @@ static const I18nPair kBuiltin_pt_br[] = { { "New game", "Novo jogo" }, { "New room msg", "Nova msg de sala" }, { "Next", "Avançar" }, + { "Night", "Noite" }, { "Night mode (invert)", "Modo noturno (inverter)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Nenhum backup .json encontrado.\nExporte um primeiro, ou copie um\nmeshcore-backup.json para o\ncartão SD ou a flash interna." }, { "No @mentions yet", "Ainda sem @menções" }, @@ -10793,7 +10841,7 @@ static const I18nPair kBuiltin_pt_br[] = { { "Test builds: off", "Builds de teste: off" }, { "Test builds: on", "Builds de teste: on" }, { "Theme", "Tema" }, - { "Theme colour", "Cor do tema" }, + { "Theme save failed", "Falha ao salvar o tema" }, { "Then pick a mode:", "Depois escolha um modo:" }, { "This contact hasn't shared\na GPS position.", "Este contato não compartilhou\numa posição GPS." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Este aparelho pode usar Wi-Fi e Bluetooth ao mesmo tempo, como rádio autônomo e companheiro do celular (app MeshCore).\n\nUsar os dois juntos consome mais RAM, então ligue só o que precisar.\n\nConfigure quando quiser em Ajustes." }, @@ -10933,6 +10981,7 @@ static const I18nPair kBuiltin_ro[] = { { "AUTOMATIC ADVERTS", "ADVERTURI AUTOMATE" }, { "About", "Despre" }, { "About the map", "Despre hartă" }, + { "Accent colour", "Culoare de accent" }, { "Accent popups", "Popupuri cu accente" }, { "Accent popups: off", "Popupuri accente: oprite" }, { "Accent popups: on", "Popupuri accente: pornite" }, @@ -10958,6 +11007,7 @@ static const I18nPair kBuiltin_ro[] = { { "Anyone can join. Key is derived from the hashtag (lowercase).", "Oricine poate intra. Cheia derivă din hashtag (litere mici)." }, { "App drawer as home", "Sertarul de aplicaţii ca ecran principal" }, { "App icon size", "Dimensiune pictograme aplicaţii" }, + { "Appearance", "Aspect" }, { "Applies after restart.", "Se aplică după repornire." }, { "Apply", "Aplică" }, { "Apply auto-poll", "Aplică auto-interogarea" }, @@ -11111,6 +11161,7 @@ static const I18nPair kBuiltin_ro[] = { { "Danger zone", "Zonă periculoasă" }, { "Data -> SD card on reboot\n(card must be inserted)", "Date -> card SD la repornire\n(cardul trebuie introdus)" }, { "Data -> internal on reboot", "Date -> stocare internă la repornire" }, + { "Day", "Zi" }, { "Delete", "Şterge" }, { "Delete %d contact(s)?", "Ştergi %d contact(e)?" }, { "Delete chat", "Şterge conversaţia" }, @@ -11371,6 +11422,7 @@ static const I18nPair kBuiltin_ro[] = { { "New game", "Joc nou" }, { "New room msg", "Mesaj nou în cameră" }, { "Next", "Înainte" }, + { "Night", "Noapte" }, { "Night mode (invert)", "Mod nocturn (inversare)" }, { "No .json backups found.\nExport one first, or copy a\nmeshcore-backup.json to the\nSD card or internal flash.", "Niciun backup .json găsit.\nExportă unul mai întâi sau copiază\nun meshcore-backup.json pe cardul\nSD ori în flash-ul intern." }, { "No @mentions yet", "Nicio menţiune @ încă" }, @@ -11674,7 +11726,7 @@ static const I18nPair kBuiltin_ro[] = { { "Test builds: off", "Versiuni de test: oprite" }, { "Test builds: on", "Versiuni de test: pornite" }, { "Theme", "Temă" }, - { "Theme colour", "Culoare temă" }, + { "Theme save failed", "Salvarea temei a eșuat" }, { "Then pick a mode:", "Apoi alege un mod:" }, { "This contact hasn't shared\na GPS position.", "Acest contact nu a partajat\no poziţie GPS." }, { "This device can run Wi-Fi and Bluetooth at once, as a standalone radio and a phone companion (MeshCore app) together.\n\nRunning both at the same time uses more RAM, so turn on only what you need.\n\nSet them up anytime in Settings.", "Acest dispozitiv poate rula Wi-Fi şi Bluetooth simultan, ca radio de sine stătător şi companion de telefon (aplicaţia MeshCore) în acelaşi timp.\n\nRularea ambelor foloseşte mai multă memorie RAM, deci porneşte doar ce îţi trebuie.\n\nLe poţi configura oricând în Setări." }, diff --git a/test/test_touch_prefs_schema.cpp b/test/test_touch_prefs_schema.cpp index 4c1be67..b03bcf2 100644 --- a/test/test_touch_prefs_schema.cpp +++ b/test/test_touch_prefs_schema.cpp @@ -25,6 +25,7 @@ static Config safeDefaults() { c.console_monitor = 1; c.boot_wifi_time = 0; c.boot_wifi_open = 0; + c.theme_mode = 0; return c; } @@ -32,6 +33,9 @@ int main() { constexpr size_t v43_size = offsetof(Config, retry_echo); constexpr size_t suffix_offset = offsetof(Config, web_mirror); constexpr size_t v43_suffix_size = v43_size - suffix_offset; + static_assert(offsetof(Config, retry_echo) == + offsetof(Config, p4_antenna) + sizeof(Config::p4_antenna), + "v45 retry field moved"); // The tail is append-only, so a blob written by an older firmware is always a // strict PREFIX of the current layout. Asserting an exact size delta pins the @@ -77,6 +81,8 @@ int main() { assert(migrated.retry_echo == 1); assert(migrated.boot_wifi_time == 0); assert(migrated.boot_wifi_open == 0); + assert(migrated.loud_alerts == 0); + assert(migrated.theme_mode == 0); // Reproduce beta 57 exactly: retry was inserted before the old suffix, then // the v43 bytes were copied and the full shifted v44 structure was written. @@ -106,7 +112,9 @@ int main() { // byte followed the blob — an inherited 1 would spend boot time on a Wi-Fi // session the user never asked for. constexpr size_t v53_size = offsetof(Config, boot_wifi_time); - static_assert(v53_size + 2 == sizeof(Config), "v54 appends exactly the two #383 bytes"); + static_assert(v53_size + sizeof(Config::boot_wifi_time) + sizeof(Config::boot_wifi_open) + + sizeof(Config::loud_alerts) + sizeof(Config::theme_mode) == sizeof(Config), + "v53 is the current layout minus every byte appended since"); Config v53 = safeDefaults(); v53.ver = 53; @@ -141,11 +149,49 @@ int main() { current.retry_echo = 0; current.boot_wifi_time = 1; current.boot_wifi_open = 1; + current.loud_alerts = 1; + current.theme_mode = 1; migrated = safeDefaults(); assert(TouchPrefsSchema::overlayStored(migrated, ¤t, sizeof(current), &stored_version)); assert(stored_version == TouchPrefsSchema::CURRENT_VERSION); assert(memcmp(&migrated, ¤t, sizeof(current)) == 0); + // Once rewritten as v45, every field through retry_echo is authoritative; + // fields appended by later versions retain their safe defaults. + constexpr size_t v45_size = offsetof(Config, app_hide); + Config v45 = safeDefaults(); + v45.ver = 45; + v45.remote_mode = 1; + v45.remote_landscape = 0; + v45.retry_echo = 0; + migrated = safeDefaults(); + assert(TouchPrefsSchema::overlayStored(migrated, &v45, v45_size, &stored_version)); + assert(stored_version == 45); + assert(migrated.remote_mode == 1); + assert(migrated.remote_landscape == 0); + assert(migrated.retry_echo == 0); + assert(migrated.app_hide == safeDefaults().app_hide); + assert(migrated.theme_mode == 0); + + // v56 appends only theme_mode. It was written as v54 on the contributing + // branch, but v54 and v55 were taken by boot_wifi_* and loud_alerts before it + // merged, so the field sits behind those and the blob one version short of + // current is the one that must leave it at the Night default. + constexpr size_t v55_size = offsetof(Config, theme_mode); + static_assert(v55_size + sizeof(Config::theme_mode) == sizeof(Config), + "theme field must remain last"); + Config v55 = safeDefaults(); + v55.ver = 55; + v55.kb_force_legacy = 1; + v55.loud_alerts = 1; + v55.theme_mode = 1; // outside the stored v55 extent + migrated = safeDefaults(); + assert(TouchPrefsSchema::overlayStored(migrated, &v55, v55_size, &stored_version)); + assert(stored_version == 55); + assert(migrated.kb_force_legacy == 1); + assert(migrated.loud_alerts == 1); + assert(migrated.theme_mode == 0); + Config invalid = safeDefaults(); uint8_t garbage[sizeof(Config)] = {}; assert(!TouchPrefsSchema::overlayStored(invalid, garbage, sizeof(garbage)));