Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b877e43d5e | ||
|
|
41c7b94a1d | ||
|
|
5c66a5b9cd | ||
|
|
c59a951449 | ||
|
|
fff611692f | ||
|
|
dbf2c43f7d | ||
|
|
708f4434f5 | ||
|
|
875ac92a48 | ||
|
|
afecfc0224 | ||
|
|
107367bf82 | ||
|
|
fe6741b26d |
No files matched your search
+1
-1
@@ -16,7 +16,7 @@ USB) and the [GitHub releases](https://github.com/ALLFATHER-BV/wadamesh/releases
|
||||
| LilyGo T-Lora Pager | ESP32-S3, LR1121 or SX1262 | 2.33" IPS LCD, 480x222 (no touch), QWERTY + rotary encoder | Web flasher (pick the build matching your radio) | Beta (new in beta_45) | Fully supported; keyboard-first navigation, microSD, map tile packs |
|
||||
| Heltec V4-R8 + Expansion Kit V2 | ESP32-S3 (8 MB octal PSRAM), SX1262 | 2.4" touch (CHSC6x) | Web flasher | Beta (new in beta_45) | As the V4 plus microSD and the Expansion Kit sensors; buzzer supported |
|
||||
| LilyGo T-Display P4 | ESP32-P4 + ESP32-C6, SX1262 | AMOLED or TFT-LCD, touch | Web flasher (AMOLED) or the .bin for the LCD SKU | Beta (new in beta_45) | Two screen SKUs; fuel-gauge battery reporting, full TX power |
|
||||
| Attaky Mesh Series | ESP32-S3, SX1262 | Touch display | Web flasher | Beta (new in beta_47) | Community port by attakygit (#158/#169); detachable keyboard supported |
|
||||
| Attaky Mesh Series | ESP32-S3, SX1262 | Touch display + front D-pad | Web flasher | Beta (new in beta_47) | Community port by attakygit (#158/#169); detachable keyboard supported; the front D-pad + SELECT navigate the UI |
|
||||
|
||||
## Feature notes per board
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: bg
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Български
|
||||
# base: bg
|
||||
(device behind) (устройството изостава)
|
||||
@@ -184,6 +184,7 @@ Contact added Контактът е добавен
|
||||
Contact deleted Контактът е изтрит
|
||||
Contact gone Контактът изчезна
|
||||
Contact missing Контактът липсва
|
||||
Contact shared Контактът е споделен
|
||||
Contacts Контакти
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контактите са във вътрешната памет - SD картата не се монтира при старт. Постави картата отново и рестартирай.
|
||||
Contacts are on internal flash. Контактите са във вътрешната памет.
|
||||
@@ -778,6 +779,8 @@ Settings Настройки
|
||||
Setup complete Настройката е готова
|
||||
Share QR Сподели QR
|
||||
Share channel Сподели канала
|
||||
Share contact Сподели контакт
|
||||
Share failed Споделянето неуспешно
|
||||
Share location in advert Споделяй местоположението в advert
|
||||
Share secret Сподели ключа
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Споделете 32-символната тайна, за да се присъединят други. Празно = случайна.
|
||||
@@ -1103,3 +1106,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: de
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Deutsch
|
||||
# base: de
|
||||
(device behind) (Gerät geht nach)
|
||||
@@ -184,6 +184,7 @@ Contact added Kontakt hinzugefügt
|
||||
Contact deleted Kontakt gelöscht
|
||||
Contact gone Kontakt weg
|
||||
Contact missing Kontakt fehlt
|
||||
Contact shared Kontakt geteilt
|
||||
Contacts Kontakte
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Kontakte liegen im internen Flash - die SD-Karte wurde beim Start nicht eingebunden. Karte neu einsetzen und neu starten.
|
||||
Contacts are on internal flash. Kontakte liegen im internen Flash.
|
||||
@@ -777,6 +778,8 @@ Settings Einstellungen
|
||||
Setup complete Einrichtung abgeschlossen
|
||||
Share QR QR teilen
|
||||
Share channel Kanal teilen
|
||||
Share contact Kontakt teilen
|
||||
Share failed Teilen fehlgeschlagen
|
||||
Share location in advert Standort im Advert teilen
|
||||
Share secret Geheimnis teilen
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Teilen Sie das 32-Zeichen-Geheimnis, damit andere beitreten. Leer lassen für ein zufälliges.
|
||||
@@ -1099,3 +1102,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: el
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Ελληνικά
|
||||
# base: el
|
||||
(device behind) (συσκευή πίσω)
|
||||
@@ -184,6 +184,7 @@ Contact added Η επαφή προστέθηκε
|
||||
Contact deleted Η επαφή διαγράφηκε
|
||||
Contact gone Η επαφή χάθηκε
|
||||
Contact missing Η επαφή λείπει
|
||||
Contact shared Η επαφή κοινοποιήθηκε
|
||||
Contacts Επαφές
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Οι επαφές είναι στην εσωτερική μνήμη - η κάρτα SD δεν προσαρτήθηκε στην εκκίνηση. Επανατοποθετήστε την και επανεκκινήστε.
|
||||
Contacts are on internal flash. Οι επαφές είναι στην εσωτερική μνήμη.
|
||||
@@ -778,6 +779,8 @@ Settings Ρυθμίσεις
|
||||
Setup complete Η ρύθμιση ολοκληρώθηκε
|
||||
Share QR Κοινοποίηση QR
|
||||
Share channel Κοινή χρήση καναλιού
|
||||
Share contact Κοινοποίηση επαφής
|
||||
Share failed Αποτυχία κοινοποίησης
|
||||
Share location in advert Κοινή χρήση θέσης στο advert
|
||||
Share secret Κοινοποίηση μυστικού
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Μοιραστείτε το μυστικό 32 χαρακτήρων για να συμμετάσχουν άλλοι. Κενό = τυχαίο.
|
||||
@@ -1103,3 +1106,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: es
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Español
|
||||
# base: es
|
||||
(device behind) (dispositivo atrasado)
|
||||
@@ -184,6 +184,7 @@ Contact added Contacto añadido
|
||||
Contact deleted Contacto eliminado
|
||||
Contact gone Contacto perdido
|
||||
Contact missing Falta el contacto
|
||||
Contact shared Contacto compartido
|
||||
Contacts Contactos
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Los contactos están en memoria interna - la tarjeta SD no se montó al arrancar. Reinserta la tarjeta y reinicia.
|
||||
Contacts are on internal flash. Los contactos están en la memoria interna.
|
||||
@@ -778,6 +779,8 @@ Settings Ajustes
|
||||
Setup complete Configuración completa
|
||||
Share QR Compartir QR
|
||||
Share channel Compartir canal
|
||||
Share contact Compartir contacto
|
||||
Share failed Error al compartir
|
||||
Share location in advert Compartir ubicación en anuncio
|
||||
Share secret Compartir secreto
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Comparte el secreto de 32 caracteres para que otros se unan. Déjalo vacío para uno aleatorio.
|
||||
@@ -1103,3 +1106,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: fr
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Français
|
||||
# base: fr
|
||||
(device behind) (appareil en retard)
|
||||
@@ -184,6 +184,7 @@ Contact added Contact ajouté
|
||||
Contact deleted Contact supprimé
|
||||
Contact gone Contact perdu
|
||||
Contact missing Contact manquant
|
||||
Contact shared Contact partagé
|
||||
Contacts Contacts
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Les contacts sont en mémoire interne - la carte SD ne s'est pas montée au démarrage. Réinsérez la carte et redémarrez.
|
||||
Contacts are on internal flash. Les contacts sont sur la mémoire interne.
|
||||
@@ -777,6 +778,8 @@ Settings Paramètres
|
||||
Setup complete Configuration terminée
|
||||
Share QR Partager le QR
|
||||
Share channel Partager le canal
|
||||
Share contact Partager le contact
|
||||
Share failed Échec du partage
|
||||
Share location in advert Partager la position dans l'annonce
|
||||
Share secret Partager le secret
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Partagez le secret de 32 caractères pour que d'autres rejoignent. Laissez vide pour un aléatoire.
|
||||
@@ -1102,3 +1105,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: hu
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Magyar
|
||||
# base: hu
|
||||
(device behind) (készülék hátulján)
|
||||
@@ -186,6 +186,7 @@ Contact added Névjegy hozzáadva
|
||||
Contact deleted Névjegy törölve
|
||||
Contact gone Eltűnt névjegy
|
||||
Contact missing Hiányzó névjegy
|
||||
Contact shared Névjegy megosztva
|
||||
Contacts Névjegyek
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. A névjegyek a belső tárolón vannak - az SD-kártya nem csatolódott induláskor. Helyezd be újra a kártyát, és indítsd újra.
|
||||
Contacts are on internal flash. A névjegyek a belső tárolón vannak.
|
||||
@@ -400,7 +401,7 @@ Join a private channel Belépés priváthoz
|
||||
Join hashtag channel Csatlakozz # csatornához
|
||||
Join network Csatlakozás a hálózathoz
|
||||
Join private channel Csatlakozz privát csatornához
|
||||
Join the public channel Csatlakozás a nyilvános csatornához
|
||||
Join the public channel Belépés a nyilvánoshoz
|
||||
Joined %.40s Csatlakozott %.40s alatt
|
||||
Keep per chat (messages) Megőrzés csevegésenként (üzenet)
|
||||
Key already in use Kulcs már hozzárendelve
|
||||
@@ -413,7 +414,7 @@ Keyboard nav: WASDZ on Billentyűzet navigáció: WASDZ bekapcsolva
|
||||
Keyboard nav: off Billentyűzetnavigáció: kikapcsolva
|
||||
Keyboard navigation Billentyűzetnavigáció
|
||||
Keys Kulcsok
|
||||
Known regions Known regions
|
||||
Known regions Ismert régiók
|
||||
LOS → %s Rálátás → %s
|
||||
Landscape (desktop) Fekvő (asztali)
|
||||
Landscape set - applies when remote mode starts. Fekvő beállítva - a távoli mód indulásakor lép életbe.
|
||||
@@ -471,7 +472,7 @@ Map — no tile pack on SPIFFS yet.\n\nUpload a tile pack to /tiles/<z>/<x>/<y>.
|
||||
Map — set your location\nin Settings → Profile to\nshow the map here. Térkép – a Beállítások → Profil menüpontban állítsd be a tartózkodási helyedet, hogy itt jelenjen meg a térkép.
|
||||
Mark all chats and channels as read? Az összes csevegést és csatornát megjelölöd olvasottként?
|
||||
Mark as read Olvasottnak jelöl
|
||||
Mark read Mark read
|
||||
Mark read Olvasott
|
||||
Marked read Olvasottként megjelölve
|
||||
Max hops (0..64) Max ugrások (0-64)
|
||||
Max zoom for this pack Maximális zoom ehhez a csomaghoz
|
||||
@@ -791,6 +792,8 @@ Settings Beállítások
|
||||
Setup complete Beállítás kész
|
||||
Share QR QR megosztása
|
||||
Share channel Csatorna megosztása
|
||||
Share contact Névjegy megosztása
|
||||
Share failed Megosztás sikertelen
|
||||
Share location in advert Helyszín megosztása a hirdetésben
|
||||
Share secret Titok megosztása
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Oszd meg a 32 karakteres titkot, hogy mások is csatlakozhassanak. Hagyd üresen a titkot, hogy véletlenszerű titkos kódot generálj.
|
||||
@@ -896,7 +899,7 @@ Turn this on, then open the address below in any web browser on the same Wi-Fi -
|
||||
Type Tipus
|
||||
Type a URL, then Go Írj be egy URL-t, majd Mehet
|
||||
Type a message... Írj be egy üzenetet...
|
||||
Type a new 6-digit code · applies after a reboot Írjon be egy új 6 jegyű kódot · újraindítás után érvényes
|
||||
Type a new 6-digit code · applies after a reboot Írjon be egy 6 jegyű kódot · újraindítás után él
|
||||
Type your network name — or switch to Wi-Fi in Settings to scan Írd be a hálózatod nevét – vagy válts Wi-Fi-re a beállításokban a kereséshez
|
||||
UI size (restart to apply) UI mérete (újraindítás az alkalmazáshoz)
|
||||
UI size saved — restart to apply UI mérete mentve – indítsa újra a programot az alkalmazáshoz
|
||||
@@ -1121,3 +1124,9 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal (stale) Jel (elavult)
|
||||
nothing heard yet Még semmi hír.
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: it
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Italiano
|
||||
# base: it
|
||||
(device behind) (dispositivo indietro)
|
||||
@@ -184,6 +184,7 @@ Contact added Contatto aggiunto
|
||||
Contact deleted Contatto eliminato
|
||||
Contact gone Contatto perso
|
||||
Contact missing Contatto mancante
|
||||
Contact shared Contatto condiviso
|
||||
Contacts Contatti
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. I contatti sono sulla memoria interna - la scheda SD non si è montata all'avvio. Reinserisci la scheda e riavvia.
|
||||
Contacts are on internal flash. I contatti sono sulla memoria interna.
|
||||
@@ -777,6 +778,8 @@ Settings Impostazioni
|
||||
Setup complete Configurazione completata
|
||||
Share QR Condividi QR
|
||||
Share channel Condividi canale
|
||||
Share contact Condividi contatto
|
||||
Share failed Condivisione non riuscita
|
||||
Share location in advert Condividi posizione in advert
|
||||
Share secret Condividi segreto
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Condividi il segreto di 32 caratteri per far unire altri. Lascia vuoto per uno casuale.
|
||||
@@ -1102,3 +1105,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: nl
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Nederlands
|
||||
# base: nl
|
||||
(device behind) (apparaat loopt achter)
|
||||
@@ -184,6 +184,7 @@ Contact added Contact toegevoegd
|
||||
Contact deleted Contact verwijderd
|
||||
Contact gone Contact weg
|
||||
Contact missing Contact ontbreekt
|
||||
Contact shared Contact gedeeld
|
||||
Contacts Contacten
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Contacten staan op intern flash - de SD-kaart is bij het opstarten niet gekoppeld. Plaats de kaart opnieuw en herstart.
|
||||
Contacts are on internal flash. Contacten staan op intern flashgeheugen.
|
||||
@@ -777,6 +778,8 @@ Settings Instellingen
|
||||
Setup complete Installatie voltooid
|
||||
Share QR QR delen
|
||||
Share channel Kanaal delen
|
||||
Share contact Contact delen
|
||||
Share failed Delen mislukt
|
||||
Share location in advert Locatie delen in advert
|
||||
Share secret Geheim delen
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Deel het 32-teken geheim zodat anderen kunnen deelnemen. Leeg laten voor een willekeurig geheim.
|
||||
@@ -1100,3 +1103,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: pt-br
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Português (BR)
|
||||
# base: pt-br
|
||||
(device behind) (dispositivo atrasado)
|
||||
@@ -184,6 +184,7 @@ Contact added Contato adicionado
|
||||
Contact deleted Contato excluído
|
||||
Contact gone Contato sumiu
|
||||
Contact missing Contato ausente
|
||||
Contact shared Contato compartilhado
|
||||
Contacts Contatos
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Os contatos estão na memória interna - o cartão SD não montou na inicialização. Recoloque o cartão e reinicie.
|
||||
Contacts are on internal flash. Os contatos estão na memória interna.
|
||||
@@ -778,6 +779,8 @@ Settings Ajustes
|
||||
Setup complete Configuração concluída
|
||||
Share QR Compartilhar QR
|
||||
Share channel Compartilhar canal
|
||||
Share contact Compartilhar contato
|
||||
Share failed Falha ao compartilhar
|
||||
Share location in advert Compartilhar local no advert
|
||||
Share secret Compartilhar segredo
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Compartilhe o segredo de 32 caracteres para outros entrarem. Deixe vazio para gerar um aleatório.
|
||||
@@ -1102,3 +1105,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: ro
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Română
|
||||
# base: ro
|
||||
(device behind) (dispozitiv în urmă)
|
||||
@@ -184,6 +184,7 @@ Contact added Contact adăugat
|
||||
Contact deleted Contact şters
|
||||
Contact gone Contact dispărut
|
||||
Contact missing Contact lipsă
|
||||
Contact shared Contact partajat
|
||||
Contacts Contacte
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Contactele sunt pe memoria internă - cardul SD nu s-a montat la pornire. Reaşază cardul şi reporneşte.
|
||||
Contacts are on internal flash. Contactele sunt pe memoria internă.
|
||||
@@ -778,6 +779,8 @@ Settings Setări
|
||||
Setup complete Configurare finalizată
|
||||
Share QR Partajează QR
|
||||
Share channel Partajează canalul
|
||||
Share contact Partajează contactul
|
||||
Share failed Partajare eşuată
|
||||
Share location in advert Partajează locaţia în advert
|
||||
Share secret Partajează secretul
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Partajează secretul de 32 caractere ca să poată intra şi alţii. Lasă secretul gol pentru a genera unul aleatoriu.
|
||||
@@ -1104,3 +1107,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: ru
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Русский
|
||||
# base: ru
|
||||
(device behind) (устройство отстаёт)
|
||||
@@ -184,6 +184,7 @@ Contact added Контакт добавлен
|
||||
Contact deleted Контакт удалён
|
||||
Contact gone Контакт пропал
|
||||
Contact missing Контакт отсутствует
|
||||
Contact shared Контакт отправлен
|
||||
Contacts Контакты
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакты во внутренней памяти - SD-карта не смонтировалась при загрузке. Переустановите карту и перезагрузитесь.
|
||||
Contacts are on internal flash. Контакты во внутренней памяти.
|
||||
@@ -778,6 +779,8 @@ Settings Настройки
|
||||
Setup complete Настройка завершена
|
||||
Share QR Поделиться QR
|
||||
Share channel Поделиться каналом
|
||||
Share contact Поделиться контактом
|
||||
Share failed Не удалось отправить контакт
|
||||
Share location in advert Делиться местоположением в advert
|
||||
Share secret Поделиться ключом
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поделитесь секретом из 32 символов, чтобы другие присоединились. Пусто = случайный.
|
||||
@@ -1103,3 +1106,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: sr
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Српски
|
||||
# base: sr
|
||||
(device behind) (уређај касни)
|
||||
@@ -184,6 +184,7 @@ Contact added Контакт додат
|
||||
Contact deleted Контакт обрисан
|
||||
Contact gone Контакт нестао
|
||||
Contact missing Контакт недостаје
|
||||
Contact shared Контакт подељен
|
||||
Contacts Контакти
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакти су у унутрашњој меморији - SD картица се није монтирала при покретању. Поново убаци картицу и рестартуј.
|
||||
Contacts are on internal flash. Контакти су у унутрашњој меморији.
|
||||
@@ -778,6 +779,8 @@ Settings Подешавања
|
||||
Setup complete Подешавање завршено
|
||||
Share QR Подели QR
|
||||
Share channel Подели канал
|
||||
Share contact Подели контакт
|
||||
Share failed Дељење није успело
|
||||
Share location in advert Дели локацију у advert-у
|
||||
Share secret Подели тајну
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поделите тајну од 32 знака да се други придруже. Празно = насумична.
|
||||
@@ -1103,3 +1106,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: uk
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Українська
|
||||
# base: uk
|
||||
(device behind) (пристрій відстає)
|
||||
@@ -184,6 +184,7 @@ Contact added Контакт додано
|
||||
Contact deleted Контакт видалено
|
||||
Contact gone Контакт зник
|
||||
Contact missing Контакт відсутній
|
||||
Contact shared Контакт надіслано
|
||||
Contacts Контакти
|
||||
Contacts are on internal flash - the SD card did not mount at boot. Re-seat the card and reboot. Контакти у внутрішній пам'яті - SD-карта не змонтувалася під час завантаження. Переставте картку і перезавантажте.
|
||||
Contacts are on internal flash. Контакти у внутрішній пам'яті.
|
||||
@@ -778,6 +779,8 @@ Settings Налаштування
|
||||
Setup complete Налаштування завершено
|
||||
Share QR Поділитися QR
|
||||
Share channel Поділитися каналом
|
||||
Share contact Поділитися контактом
|
||||
Share failed Не вдалося надіслати контакт
|
||||
Share location in advert Ділитися місцезнаходженням в advert
|
||||
Share secret Поділитися ключем
|
||||
Share the 32-char secret so others can join. Leave the secret empty to generate a random one. Поділіться секретом із 32 символів, щоб інші приєдналися. Порожньо = випадковий.
|
||||
@@ -1103,3 +1106,10 @@ Glance shows message previews\nwhile the screen is locked Glance shows message p
|
||||
Snake — swipe, roll, or press a direction Snake — swipe, roll, or press a direction
|
||||
N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: bg
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Български
|
||||
# base: bg
|
||||
(device behind) (устройството изостава)
|
||||
@@ -1109,3 +1109,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: de
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Deutsch
|
||||
# base: de
|
||||
(device behind) (Gerät geht nach)
|
||||
@@ -1105,3 +1105,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: el
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Ελληνικά
|
||||
# base: el
|
||||
(device behind) (συσκευή πίσω)
|
||||
@@ -1109,3 +1109,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: es
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Español
|
||||
# base: es
|
||||
(device behind) (dispositivo atrasado)
|
||||
@@ -1109,3 +1109,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: fr
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Français
|
||||
# base: fr
|
||||
(device behind) (appareil en retard)
|
||||
@@ -1108,3 +1108,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: hu
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Magyar
|
||||
# base: hu
|
||||
(device behind) (készülék hátulján)
|
||||
@@ -401,7 +401,7 @@ Join a private channel Belépés priváthoz
|
||||
Join hashtag channel Csatlakozz # csatornához
|
||||
Join network Csatlakozás a hálózathoz
|
||||
Join private channel Csatlakozz privát csatornához
|
||||
Join the public channel Csatlakozás a nyilvános csatornához
|
||||
Join the public channel Belépés a nyilvánoshoz
|
||||
Joined %.40s Csatlakozott %.40s alatt
|
||||
Keep per chat (messages) Megőrzés csevegésenként (üzenet)
|
||||
Key already in use Kulcs már hozzárendelve
|
||||
@@ -414,7 +414,7 @@ Keyboard nav: WASDZ on Billentyűzet navigáció: WASDZ bekapcsolva
|
||||
Keyboard nav: off Billentyűzetnavigáció: kikapcsolva
|
||||
Keyboard navigation Billentyűzetnavigáció
|
||||
Keys Kulcsok
|
||||
Known regions Known regions
|
||||
Known regions Ismert régiók
|
||||
LOS → %s Rálátás → %s
|
||||
Landscape (desktop) Fekvő (asztali)
|
||||
Landscape set - applies when remote mode starts. Fekvő beállítva - a távoli mód indulásakor lép életbe.
|
||||
@@ -472,7 +472,7 @@ Map — no tile pack on SPIFFS yet.\n\nUpload a tile pack to /tiles/<z>/<x>/<y>.
|
||||
Map — set your location\nin Settings → Profile to\nshow the map here. Térkép – a Beállítások → Profil menüpontban állítsd be a tartózkodási helyedet, hogy itt jelenjen meg a térkép.
|
||||
Mark all chats and channels as read? Az összes csevegést és csatornát megjelölöd olvasottként?
|
||||
Mark as read Olvasottnak jelöl
|
||||
Mark read Mark read
|
||||
Mark read Olvasott
|
||||
Marked read Olvasottként megjelölve
|
||||
Max hops (0..64) Max ugrások (0-64)
|
||||
Max zoom for this pack Maximális zoom ehhez a csomaghoz
|
||||
@@ -899,7 +899,7 @@ Turn this on, then open the address below in any web browser on the same Wi-Fi -
|
||||
Type Tipus
|
||||
Type a URL, then Go Írj be egy URL-t, majd Mehet
|
||||
Type a message... Írj be egy üzenetet...
|
||||
Type a new 6-digit code · applies after a reboot Írjon be egy új 6 jegyű kódot · újraindítás után érvényes
|
||||
Type a new 6-digit code · applies after a reboot Írjon be egy 6 jegyű kódot · újraindítás után él
|
||||
Type your network name — or switch to Wi-Fi in Settings to scan Írd be a hálózatod nevét – vagy válts Wi-Fi-re a beállításokban a kereséshez
|
||||
UI size (restart to apply) UI mérete (újraindítás az alkalmazáshoz)
|
||||
UI size saved — restart to apply UI mérete mentve – indítsa újra a programot az alkalmazáshoz
|
||||
@@ -1126,3 +1126,7 @@ N/A N/A
|
||||
This board cannot run this app. This board cannot run this app.
|
||||
Signal (stale) Jel (elavult)
|
||||
nothing heard yet Még semmi hír.
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: it
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Italiano
|
||||
# base: it
|
||||
(device behind) (dispositivo indietro)
|
||||
@@ -1108,3 +1108,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: nl
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Nederlands
|
||||
# base: nl
|
||||
(device behind) (apparaat loopt achter)
|
||||
@@ -1106,3 +1106,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: pt-br
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Português (BR)
|
||||
# base: pt-br
|
||||
(device behind) (dispositivo atrasado)
|
||||
@@ -1108,3 +1108,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: ro
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Română
|
||||
# base: ro
|
||||
(device behind) (dispozitiv în urmă)
|
||||
@@ -1110,3 +1110,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: ru
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Русский
|
||||
# base: ru
|
||||
(device behind) (устройство отстаёт)
|
||||
@@ -1109,3 +1109,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: sr
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Српски
|
||||
# base: sr
|
||||
(device behind) (уређај касни)
|
||||
@@ -1109,3 +1109,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
@@ -1,7 +1,7 @@
|
||||
# wadamesh language file
|
||||
# canonical source - translators: edit this file and PR it
|
||||
# code: uk
|
||||
# ver: 19
|
||||
# ver: 21
|
||||
# name: Українська
|
||||
# base: uk
|
||||
(device behind) (пристрій відстає)
|
||||
@@ -1109,3 +1109,7 @@ This board cannot run this app. This board cannot run this app.
|
||||
Signal Signal
|
||||
Signal (stale) Signal (stale)
|
||||
nothing heard yet nothing heard yet
|
||||
Detecting the keyboard protocol Detecting the keyboard protocol
|
||||
Older keyboard protocol Older keyboard protocol
|
||||
Using the older keyboard protocol Using the older keyboard protocol
|
||||
turn on if your keyboard types the wrong letters; disables modifier latching turn on if your keyboard types the wrong letters; disables modifier latching
|
||||
+13
-13
@@ -3,67 +3,67 @@
|
||||
{
|
||||
"code": "bg",
|
||||
"name": "Български",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "de",
|
||||
"name": "Deutsch",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "el",
|
||||
"name": "Ελληνικά",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "es",
|
||||
"name": "Español",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "fr",
|
||||
"name": "Français",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "hu",
|
||||
"name": "Magyar",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "it",
|
||||
"name": "Italiano",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "nl",
|
||||
"name": "Nederlands",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "pt-br",
|
||||
"name": "Português (BR)",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "ro",
|
||||
"name": "Română",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "ru",
|
||||
"name": "Русский",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "sr",
|
||||
"name": "Српски",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
},
|
||||
{
|
||||
"code": "uk",
|
||||
"name": "Українська",
|
||||
"ver": "19"
|
||||
"ver": "21"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# beta_73 - test build. Stable stays beta_65.
|
||||
# One user-facing note per non-blank, non-# line; # lines are section comments.
|
||||
|
||||
# --- Older T-Decks could not be typed on ------------------------------------------------------
|
||||
If your T-Deck types the wrong letters, this release fixes it. Pressing "a" produced "q " and "m" produced "qa ", which made the keyboard unusable for writing, navigating or locking the screen.
|
||||
It affects the older T-Deck keyboards, the ones without the controllable backlight, and it started in beta_70. The firmware asks the keyboard at startup whether it speaks the newer protocol that modifier latching needs, and an older keyboard's answer looked enough like a yes to be taken as one. Everything typed after that was read the wrong way round.
|
||||
Nothing can tell the two keyboards apart while nobody is typing, so the firmware now simply corrects itself: the first letter you press is unmistakably a character rather than a key-position report, and it switches to the older protocol on the spot and delivers that letter. You lose modifier latching, which your keyboard cannot do anyway, and you get a working keyboard.
|
||||
Newer keyboards are unaffected and keep latching.
|
||||
The beta_72 change that was meant to make this detection more reliable made it worse, because it gave an older keyboard more chances to look like a newer one.
|
||||
|
||||
# --- Translations ---------------------------------------------------------------------------------
|
||||
Two Hungarian strings: "Mark read", which had never been translated, and a shorter wording for joining the public channel so it fits its button. These are already on devices, since language files publish separately from the firmware.
|
||||
|
||||
# --- For testers -------------------------------------------------------------------------------
|
||||
If your keyboard was typing nonsense, you should be able to install this normally rather than needing a cable.
|
||||
A reminder that two settings control whether an arriving message lights a dark or locked screen, and they are separate: Message flash wakes the screen, and At a glance draws the preview text on it. Both are in Options, Display. Turning off At a glance alone will not stop the screen lighting up.
|
||||
Still open and not fixed here: a map that renders nothing after beta_71, a screen that will not stay dark after a manual lock, and a web flasher that hangs at "wrapping up" on the T-Display P4.
|
||||
@@ -0,0 +1,25 @@
|
||||
# beta_74 - test build. Stable stays beta_65.
|
||||
# One user-facing note per non-blank, non-# line; # lines are section comments.
|
||||
|
||||
# --- If your T-Deck types the wrong letters -----------------------------------------------
|
||||
There is now a switch that fixes it, and you can reach it without typing: Settings, Keyboard, "Older keyboard protocol". It skips the automatic detection and uses the protocol every T-Deck keyboard understands.
|
||||
This exists because the detection cannot always be certain, and when it gets it wrong the keyboard types the wrong letters, so any fix that needs you to type is not a fix. The switch is operated by touch and applies immediately, with no reboot.
|
||||
Turning it on costs modifier latching, which a keyboard that needs the switch cannot do anyway.
|
||||
The automatic detection is unchanged and still the default. If beta_73 fixed your keyboard, nothing here changes for you.
|
||||
|
||||
# --- Web settings could quietly change your radio ------------------------------------------
|
||||
The remote web page showed a bandwidth of 62.5 as 62, and pressing Apply sent 62 back to the device. Opening the page and applying anything reconfigured the radio onto a bandwidth the mesh was not using. Both halves of that are fixed: the device now sends the fraction, and the form accepts it.
|
||||
|
||||
# --- Keyboard ---------------------------------------------------------------------------------
|
||||
Shift latches like the symbol and alt keys do: tap once for the next letter, tap twice to lock until you tap again. No more holding shift down while reaching for a key.
|
||||
The Attaky Mesh Deck's front D-pad and SELECT button work now. The board has nine buttons and only the power button did anything.
|
||||
|
||||
# --- Reading a route ------------------------------------------------------------------------
|
||||
Each hop in a message route shows its path prefix next to the repeater name. When a repeater is named misleadingly, or two share a name, the prefix is the part that still identifies it, which is exactly when you are looking at a route.
|
||||
|
||||
# --- Translations ---------------------------------------------------------------------------------
|
||||
"Known regions" and the Bluetooth pairing hint are translatable and translated into Hungarian.
|
||||
|
||||
# --- For testers ------------------------------------------------------------------------------
|
||||
Still open and not fixed here: a map that renders nothing since beta_71, a screen that will not stay dark after a manual lock, the web flasher hanging at "wrapping up" on the T-Display P4, and an M9 that reports no SD card when formatting.
|
||||
A reminder that two separate settings control whether an arriving message lights a dark screen. "Flash on new message" is in Settings, Keyboard, and it is the one that wakes the screen. "At a glance" is in Settings, Display, and it draws the preview text. Turning off the second one alone will not stop the screen lighting up.
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace TouchPrefsSchema {
|
||||
|
||||
static constexpr uint16_t MAGIC = 0x5743; // 'WC' (WadaCfg)
|
||||
static constexpr uint8_t CURRENT_VERSION = 52; // 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)
|
||||
static constexpr uint8_t CURRENT_VERSION = 53; // 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)
|
||||
static constexpr uint8_t BROKEN_MID_INSERT_VERSION = 44;
|
||||
|
||||
// Persisted byte layout. New fields must be appended at the end: older blobs
|
||||
@@ -83,6 +83,12 @@ struct __attribute__((packed)) Config {
|
||||
// every field after it, which is what v45 had to undo. Append, never insert.
|
||||
uint8_t console_mode; // v51: boot into the LVGL-free text console (CONSOLE_MODE.md)
|
||||
uint8_t console_monitor; // v52: console mode shows incoming messages as they arrive
|
||||
// v53: never probe for the raw keyboard protocol, always use the older one.
|
||||
// The detection cannot be certain while nobody is typing, and when it guesses
|
||||
// wrong the keyboard types nonsense -- which also makes it very hard to reach
|
||||
// a setting to fix it. This is reachable by touch, so it is a way out that
|
||||
// does not need the keyboard that is broken (#341, #351).
|
||||
uint8_t kb_force_legacy;
|
||||
};
|
||||
|
||||
static constexpr size_t HEADER_SIZE = offsetof(Config, bright);
|
||||
@@ -90,7 +96,7 @@ static constexpr size_t STABLE_V44_PREFIX_SIZE = offsetof(Config, web_mirror);
|
||||
|
||||
static_assert(offsetof(Config, web_mirror) == offsetof(Config, rx_queue) + sizeof(Config::rx_queue),
|
||||
"the pre-v44 suffix moved");
|
||||
static_assert(offsetof(Config, console_monitor) + sizeof(Config::console_monitor) == sizeof(Config),
|
||||
static_assert(offsetof(Config, kb_force_legacy) + sizeof(Config::kb_force_legacy) == 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
|
||||
|
||||
@@ -135,6 +135,7 @@ static void cfgSetDefaults(TouchCfg& c) {
|
||||
c.boot_advert = 0; // OFF: no automatic advert on boot — opt-in (#76)
|
||||
c.console_mode = 0; // OFF: boot into the graphical UI (CONSOLE_MODE.md)
|
||||
c.console_monitor = 1; // ON: the console shows messages as they arrive
|
||||
c.kb_force_legacy = 0; // OFF: detect the keyboard protocol automatically
|
||||
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)
|
||||
@@ -242,6 +243,7 @@ static void cfgLoadOrMigrate() {
|
||||
// a garbage 1 would boot a user into a console they did not ask for.
|
||||
if (stored_version < 51) s_cfg.console_mode = 0;
|
||||
if (stored_version < 52) s_cfg.console_monitor = 1; // new trailing field: on by default
|
||||
if (stored_version < 53) s_cfg.kb_force_legacy = 0; // new trailing field: auto-detect
|
||||
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)
|
||||
@@ -1114,6 +1116,16 @@ bool touchPrefsSetConsoleMode(bool on) {
|
||||
return cfgFlush();
|
||||
}
|
||||
|
||||
bool touchPrefsGetKbForceLegacy() {
|
||||
if (!s_begun) touchPrefsBegin();
|
||||
return s_cfg.kb_force_legacy != 0;
|
||||
}
|
||||
bool touchPrefsSetKbForceLegacy(bool on) {
|
||||
if (!s_begun) touchPrefsBegin();
|
||||
s_cfg.kb_force_legacy = on ? 1 : 0;
|
||||
return cfgFlush();
|
||||
}
|
||||
|
||||
bool touchPrefsGetConsoleMonitor() {
|
||||
if (!s_begun) touchPrefsBegin();
|
||||
return s_cfg.console_monitor != 0;
|
||||
|
||||
@@ -193,6 +193,13 @@ bool touchPrefsSetMsgFlash(bool on);
|
||||
* refresh our pubkey (useful after a reflash wiped storage). Opt-in, default off. All boards. */
|
||||
bool touchPrefsGetConsoleMode(); // boot into the LVGL-free console (CONSOLE_MODE.md)
|
||||
bool touchPrefsSetConsoleMode(bool on);
|
||||
// Skip raw-protocol detection on the T-Deck keyboard and always use the older
|
||||
// one. Reachable by touch, so it is a way out when a misdetection has left the
|
||||
// keyboard typing nonsense (#341, #351).
|
||||
bool touchPrefsGetKbForceLegacy();
|
||||
bool touchPrefsSetKbForceLegacy(bool on);
|
||||
bool touchPrefsGetKbForceLegacy();
|
||||
bool touchPrefsSetKbForceLegacy(bool on);
|
||||
bool touchPrefsGetConsoleMonitor(); // console: show incoming messages live
|
||||
bool touchPrefsSetConsoleMonitor(bool on);
|
||||
bool touchPrefsGetBootAdvert();
|
||||
|
||||
@@ -374,7 +374,7 @@ static const char WS_HTML_TERMINAL_PAGE[] =
|
||||
"function showSettings(d){var g=E;\n"
|
||||
" var h='<div class=sset><label>NODE NAME</label><div class=srow><input type=text id=sfname><button class=sbtn id=sbname>Save</button></div>';\n"
|
||||
" h+='<label>RADIO (applies live)</label><div class=sgrid>';\n"
|
||||
" h+='<div class=f><label>Freq MHz</label><input type=number step=0.001 id=sffreq></div><div class=f><label>BW kHz</label><input type=number id=sfbw></div>';\n"
|
||||
" h+='<div class=f><label>Freq MHz</label><input type=number step=0.001 id=sffreq></div><div class=f><label>BW kHz</label><input type=number step=0.1 id=sfbw></div>';\n"
|
||||
" h+='<div class=f><label>SF</label><input type=number id=sfsf></div><div class=f><label>CR</label><input type=number id=sfcr></div>';\n"
|
||||
" h+='<div class=f><label>TX dBm</label><input type=number id=sftx></div><div class=f><label> </label><button class=sbtn id=sbradio style=width:100%>Apply</button></div></div>';\n"
|
||||
" h+='<label>CONNECTIVITY</label><div class=stog><b>Wi-Fi</b><div class=sw id=swifi><i></i></div></div>';\n"
|
||||
|
||||
@@ -75,6 +75,27 @@ static void processRawFrame(const uint8_t frame[TDeckKeyboardState::COLS], uint3
|
||||
portEXIT_CRITICAL(&s_keyboard_mux);
|
||||
}
|
||||
|
||||
// True when a five-byte answer can only be a legacy ASCII reply: the character
|
||||
// in byte 0 with padding after it. A real matrix frame puts one bit per pressed
|
||||
// key in that key's own column, so three or more bits in byte 0 with every other
|
||||
// column empty is not something the hardware can report.
|
||||
static bool looksLikeAscii(const uint8_t frame[TDeckKeyboardState::COLS]) {
|
||||
for (size_t col = 1; col < TDeckKeyboardState::COLS; ++col) if (frame[col]) return false;
|
||||
if (frame[0] < 0x20 || frame[0] > 0x7E) return false; // must be a printable character
|
||||
int bits = 0;
|
||||
for (int b = 0; b < 8; ++b) if (frame[0] & (1u << b)) ++bits;
|
||||
return bits > 2;
|
||||
}
|
||||
|
||||
// Verified against the real tables rather than assumed:
|
||||
// - all 26 lowercase letters set 3 or more bits, so ANY letter demotes on the
|
||||
// first press. Only '0', ' ' and '!' do not, and space happens to render
|
||||
// correctly anyway (column 0 bit 5 IS space).
|
||||
// - going the other way, a genuine frame reaching this needs three or more of
|
||||
// {q, w, a, space} held at once and nothing else. The printable-range test
|
||||
// above removes q+w+a (0x0B); what remains are combinations including space,
|
||||
// which is a fumble rather than typing, and costs a reboot to undo.
|
||||
|
||||
static void processLegacyKey(uint8_t key) {
|
||||
portENTER_CRITICAL(&s_keyboard_mux);
|
||||
const uint32_t generation = s_modifier_mode_generation;
|
||||
@@ -90,6 +111,12 @@ static void processLegacyKey(uint8_t key) {
|
||||
portEXIT_CRITICAL(&s_keyboard_mux);
|
||||
}
|
||||
|
||||
// Set from the UI at boot (Settings > Keyboard). When true the probe is skipped
|
||||
// entirely and the older protocol is used, which is the escape hatch for a
|
||||
// controller that detection gets wrong (#351).
|
||||
static bool s_force_legacy = false;
|
||||
void tdeckKeyboardForceLegacy(bool on) { s_force_legacy = on; }
|
||||
|
||||
void tdeckKeyboardBegin() {
|
||||
s_mode = KeyboardMode::Probe;
|
||||
s_raw_state = TDeckKeyboardState{};
|
||||
@@ -127,17 +154,34 @@ void tdeckKeyboardFlushBacklight() {
|
||||
void tdeckKeyboardPoll() {
|
||||
if (!s_inited) return;
|
||||
tdeckKeyboardFlushBacklight();
|
||||
if (s_force_legacy && s_mode != KeyboardMode::Legacy) {
|
||||
keyboardCommand(0x04);
|
||||
s_mode = KeyboardMode::Legacy;
|
||||
Serial.println("[keyboard] T-Deck legacy mode: forced in settings");
|
||||
}
|
||||
if (s_mode == KeyboardMode::Probe) {
|
||||
// LilyGO keyboard firmware from June 2025 onward accepts 0x03 and returns
|
||||
// five column-state bytes. Older controllers ignore it and keep returning
|
||||
// one resolved ASCII byte; restore 0x04 key mode when that is what we have.
|
||||
// Deciding whether this controller speaks the raw column protocol.
|
||||
//
|
||||
// KEEP RETRYING before concluding "old firmware". This used to decide on a
|
||||
// SINGLE read, and the first I2C read after boot is the least trustworthy
|
||||
// one there is: the C3 is still coming up, so a short or garbled frame is
|
||||
// ordinary. One such frame committed the device to legacy mode for the whole
|
||||
// session, with no recovery short of a reboot -- reported as latching simply
|
||||
// not working on a T-Deck carrying the June 2025 firmware (#332).
|
||||
// The old test was "five bytes came back and no high bit is set", which a
|
||||
// LEGACY controller passes trivially: it answers a five-byte read with the
|
||||
// pressed character followed by padding, and every lowercase letter has its
|
||||
// high bit clear. Read as a column bitmap, 'a' (0x61) emits "q " and 'm'
|
||||
// (0x6d) emits "qa ". That is the garbage Vybo reported on an older T-Deck
|
||||
// (#341), and the retry window added in beta_72 made it MORE likely to
|
||||
// latch, not less.
|
||||
//
|
||||
// The positive test: a real matrix frame from a key press has ONE bit set,
|
||||
// in whichever column that key lives. A legacy reply only ever has byte 0
|
||||
// non-zero, and an ASCII letter sets three or four bits at once. So:
|
||||
//
|
||||
// any non-zero byte in columns 1..4 -> genuinely raw (padding is never
|
||||
// non-zero there)
|
||||
// byte 0 with >2 bits set, rest zero -> an ASCII character, so legacy
|
||||
//
|
||||
// An all-zero frame is idle and proves nothing either way, so keep probing.
|
||||
// If the window expires having seen only column-0 activity, fall back to
|
||||
// LEGACY. That is the safe default: the cost of being wrong is losing
|
||||
// modifier latching, never losing the keyboard.
|
||||
static uint32_t s_probe_start_ms = 0;
|
||||
const uint32_t now = millis();
|
||||
if (!s_probe_start_ms) s_probe_start_ms = now;
|
||||
@@ -145,37 +189,70 @@ void tdeckKeyboardPoll() {
|
||||
keyboardCommand(0x03);
|
||||
uint8_t frame[TDeckKeyboardState::COLS] = {};
|
||||
const int count = keyboardRead(frame, sizeof frame);
|
||||
bool valid_raw = count == (int)sizeof frame;
|
||||
size_t bad_col = 0;
|
||||
for (size_t col = 0; col < sizeof frame && valid_raw; ++col) {
|
||||
if (frame[col] & 0x80) { valid_raw = false; bad_col = col; }
|
||||
}
|
||||
if (valid_raw) {
|
||||
|
||||
bool shape_ok = (count == (int)sizeof frame);
|
||||
for (size_t col = 0; col < sizeof frame && shape_ok; ++col)
|
||||
if (frame[col] & 0x80) shape_ok = false;
|
||||
|
||||
if (shape_ok) {
|
||||
bool cols1plus = false;
|
||||
for (size_t col = 1; col < sizeof frame; ++col) if (frame[col]) cols1plus = true;
|
||||
int b0bits = 0;
|
||||
for (int b = 0; b < 8; ++b) if (frame[0] & (1u << b)) ++b0bits;
|
||||
|
||||
if (cols1plus) { // only a real matrix reaches here
|
||||
s_mode = KeyboardMode::Raw;
|
||||
Serial.println("[keyboard] T-Deck raw mode: modifier latching enabled");
|
||||
processRawFrame(frame, now);
|
||||
return;
|
||||
}
|
||||
if (frame[0] && b0bits > 2) { // an ASCII byte, not a column
|
||||
keyboardCommand(0x04);
|
||||
s_mode = KeyboardMode::Legacy;
|
||||
Serial.printf("[keyboard] T-Deck legacy mode: controller answered with a character "
|
||||
"(0x%02X), not a column frame\n", frame[0]);
|
||||
processLegacyKey(frame[0]);
|
||||
return;
|
||||
}
|
||||
if ((uint32_t)(now - s_probe_start_ms) < kProbeWindowMs) return; // idle: keep looking
|
||||
// Window expired with a well-formed, idle frame every time. That is what a
|
||||
// raw controller looks like when nobody is typing, so take it -- a legacy
|
||||
// one would have shown us a character by now if it had one, and if it has
|
||||
// not, looksLikeAscii() below still demotes the moment it does.
|
||||
s_mode = KeyboardMode::Raw;
|
||||
Serial.println("[keyboard] T-Deck raw mode: modifier latching enabled");
|
||||
processRawFrame(frame, millis());
|
||||
return;
|
||||
} else if ((uint32_t)(now - s_probe_start_ms) < kProbeWindowMs) {
|
||||
if (count == 1) { keyboardCommand(0x04); processLegacyKey(frame[0]); }
|
||||
return; // short/garbled read: the C3 may still be waking
|
||||
}
|
||||
// A legacy controller answers with one resolved byte. Deliver it either way
|
||||
// so nothing typed during the probe window is dropped.
|
||||
if (count == 1) { keyboardCommand(0x04); processLegacyKey(frame[0]); }
|
||||
if ((uint32_t)(now - s_probe_start_ms) < kProbeWindowMs) return; // try again next poll
|
||||
|
||||
keyboardCommand(0x04);
|
||||
s_mode = KeyboardMode::Legacy;
|
||||
// Say WHY, so the next report of "latching does not work" is one line to
|
||||
// diagnose instead of a guess about which firmware someone has.
|
||||
Serial.printf("[keyboard] T-Deck legacy mode: update keyboard C3 firmware for modifier "
|
||||
"latching (probe read %d bytes, wanted %d%s)\n",
|
||||
count, (int)sizeof frame,
|
||||
(count == (int)sizeof frame) ? ", high bit set in a column" : "");
|
||||
(void)bad_col;
|
||||
Serial.printf("[keyboard] T-Deck legacy mode: no raw column frame seen in %lu ms "
|
||||
"(probe read %d bytes)\n", (unsigned long)kProbeWindowMs, count);
|
||||
if (count == 1) processLegacyKey(frame[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_mode == KeyboardMode::Raw) {
|
||||
uint8_t frame[TDeckKeyboardState::COLS] = {};
|
||||
if (keyboardRead(frame, sizeof frame) != (int)sizeof frame) return;
|
||||
for (size_t col = 0; col < sizeof frame; ++col) if (frame[col] & 0x80) return;
|
||||
// Raw mode has to be able to admit it guessed wrong. An idle controller of
|
||||
// either kind answers with zeros, so the probe cannot tell them apart until
|
||||
// someone types -- and on a legacy controller that first character arrives
|
||||
// in byte 0 with three or four bits set, which no single key press can
|
||||
// produce. Demote on the spot and deliver the character, so the worst case
|
||||
// is one odd keystroke rather than a keyboard that types nonsense forever.
|
||||
if (looksLikeAscii(frame)) {
|
||||
keyboardCommand(0x04);
|
||||
s_mode = KeyboardMode::Legacy;
|
||||
Serial.printf("[keyboard] T-Deck legacy mode: raw guess withdrawn, controller sent a "
|
||||
"character (0x%02X)\n", frame[0]);
|
||||
processLegacyKey(frame[0]);
|
||||
return;
|
||||
}
|
||||
processRawFrame(frame, millis());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
* driver, so this just enables polling. */
|
||||
void tdeckKeyboardBegin();
|
||||
|
||||
/** Force the older keyboard protocol, skipping raw detection. Escape hatch for a
|
||||
* controller the probe gets wrong; call before/at begin and on the setting. */
|
||||
void tdeckKeyboardForceLegacy(bool on);
|
||||
|
||||
/** Read one key over I2C and push it into the ring. CORE-0 ONLY (touch task). */
|
||||
void tdeckKeyboardPoll();
|
||||
|
||||
|
||||
@@ -39,13 +39,17 @@ class TDeckKeyboardState {
|
||||
if (!modifiers_enabled) {
|
||||
symbol_.baseline(down(0, 2));
|
||||
alt_.baseline(down(0, 4));
|
||||
shift_.baseline(down(1, 6) || down(2, 3));
|
||||
}
|
||||
if (modifiers_enabled && pressed(0, 2)) symbol_.press();
|
||||
if (modifiers_enabled && pressed(0, 4)) alt_.press();
|
||||
if (modifiers_enabled && released(0, 2)) symbol_.release(now_ms);
|
||||
if (modifiers_enabled && released(0, 4)) alt_.release(now_ms);
|
||||
if (modifiers_enabled && (pressed(1, 6) || pressed(2, 3))) shift_.press();
|
||||
if (modifiers_enabled && (released(1, 6) || released(2, 3))) shift_.release(now_ms);
|
||||
|
||||
const bool shift = modifiers_enabled && (down(1, 6) || down(2, 3));
|
||||
// Held OR latched: a tap arms it for the next key, a double tap locks it.
|
||||
const bool shift = modifiers_enabled && (down(1, 6) || down(2, 3) || shift_.latched());
|
||||
size_t written = 0;
|
||||
auto emit = [&](uint8_t key) {
|
||||
if (written < out_capacity) out[written++] = key;
|
||||
@@ -81,6 +85,7 @@ class TDeckKeyboardState {
|
||||
if (modifiers_enabled) {
|
||||
symbol_.consumeForKey();
|
||||
if (!physical_alt) alt_.consumeForKey();
|
||||
shift_.consumeForKey(); // one-shot shift expires on the key it capitalised
|
||||
}
|
||||
if (key == '\0') continue;
|
||||
char resolved = key;
|
||||
@@ -108,4 +113,9 @@ class TDeckKeyboardState {
|
||||
uint8_t previous_[COLS] = {};
|
||||
LatchedModifier symbol_;
|
||||
LatchedModifier alt_;
|
||||
// Shift latches like the other two (#344). It used to be a bare "is it held"
|
||||
// test, so a capital letter meant holding shift down while reaching for the
|
||||
// key. The board has two shift keys and they share one latch: whichever you
|
||||
// press arms it, and either releases it.
|
||||
LatchedModifier shift_;
|
||||
};
|
||||
+172
-9
@@ -1917,6 +1917,18 @@ static bool tbFingerTouchOnTabBarBlocked(uint16_t y) {
|
||||
static bool s_kbd_nav = true;
|
||||
#endif
|
||||
|
||||
#if defined(ATTAKY_MESH_SERIES)
|
||||
// Attaky Mesh Deck: touch is the primary input, and the front D-pad + SELECT are
|
||||
// a second one — so this takes the same CAP_KEYPAD_NAV "secondary indev" path as
|
||||
// the M9 block below, fed by attakyNavPump() draining the @0x59 expander queue.
|
||||
// The three symbols are the ones that path needs (see the M9's note); nav is
|
||||
// always on because the buttons are soldered to the board — there is nothing to
|
||||
// toggle off, and with no press the group just sits unfocused and invisible.
|
||||
static bool s_kbd_nav = true;
|
||||
static bool s_tb_nav = false; // no trackball — read by the shared nav-rebuild gate, never set
|
||||
static lv_indev_drv_t s_nav_keypad_drv;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_THINKNODE_M9)
|
||||
// Keyboard-only device (no touch, no trackball): nav is always on, same as Tanmatsu above.
|
||||
// Unlike Tanmatsu (which registers its KEYPAD indev as the PRIMARY one, driven by navPump()
|
||||
@@ -11840,6 +11852,20 @@ static void enterSendsToggleCb(lv_event_t* e) {
|
||||
static volatile uint32_t s_msgflash_until = 0; // keyboard-backlight pulse deadline (0 = idle)
|
||||
static volatile bool s_msgflash_wake = false; // one-shot screen-wake request (consumed in loop())
|
||||
static uint32_t s_notify_wake_ms = 0; // screen lit BY a message (not input) at this ms — re-dims after a short window (burn-in)
|
||||
#if defined(HAS_TDECK_KEYBOARD)
|
||||
// Escape hatch for a keyboard the protocol detection gets wrong. Reachable by
|
||||
// TOUCH, which is the whole point: when detection is wrong the keyboard types
|
||||
// nonsense, so any fix that needs the keyboard is no fix at all (#341, #351).
|
||||
static void kbForceLegacyToggleCb(lv_event_t* e) {
|
||||
if (lv_event_get_code(e) != LV_EVENT_VALUE_CHANGED) return;
|
||||
const bool on = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
|
||||
touchPrefsSetKbForceLegacy(on);
|
||||
tdeckKeyboardForceLegacy(on); // applies now; no reboot needed to get typing back
|
||||
if (g_lv.task) g_lv.task->showAlert(on ? TR("Using the older keyboard protocol")
|
||||
: TR("Detecting the keyboard protocol"), 1600);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void msgFlashToggleCb(lv_event_t* e) {
|
||||
if (lv_event_get_code(e) != LV_EVENT_VALUE_CHANGED) return;
|
||||
const bool on = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
|
||||
@@ -13324,6 +13350,25 @@ static void buildDeviceSettings(int sec) {
|
||||
y += settingsRowLabel(body, y, 0, TR("lights the keyboard + wakes the screen on an incoming message"),
|
||||
COLOR_SUB, &g_font_12, 0) + 2;
|
||||
}
|
||||
#if defined(HAS_TDECK_KEYBOARD)
|
||||
/* Older keyboard controllers do not speak the raw protocol that modifier
|
||||
latching needs, and the detection cannot be certain while nobody is typing.
|
||||
When it guesses wrong the keyboard types the wrong letters, so this switch
|
||||
exists to be reachable BY TOUCH and end it. */
|
||||
{
|
||||
int h = settingsRowLabel(body, y, 4, TR("Older keyboard protocol"), COLOR_TEXT, &g_font_12, 56);
|
||||
lv_obj_t* sw = lv_switch_create(body);
|
||||
lv_obj_align(sw, LV_ALIGN_TOP_RIGHT, 0, y);
|
||||
#if defined(ESP32)
|
||||
if (touchPrefsGetKbForceLegacy()) lv_obj_add_state(sw, LV_STATE_CHECKED);
|
||||
#endif
|
||||
lv_obj_add_event_cb(sw, kbForceLegacyToggleCb, LV_EVENT_VALUE_CHANGED, nullptr);
|
||||
y += LV_MAX(34, h + 10);
|
||||
y += settingsRowLabel(body, y, 0, TR("turn on if your keyboard types the wrong letters; disables modifier latching"),
|
||||
COLOR_SUB, &g_font_12, 0) + 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAS_TANMATSU)
|
||||
@@ -19887,7 +19932,7 @@ static void webPushSettings() {
|
||||
const bool wc = (WiFi.status() == WL_CONNECTED);
|
||||
char* p = s_webdata_buf; const char* e = s_webdata_buf + WEBDATA_BUF;
|
||||
p += snprintf(p, e - p,
|
||||
"{\"t\":\"sg\",\"freq\":%.3f,\"bw\":%.0f,\"sf\":%d,\"cr\":%d,\"tx\":%d,\"wifi\":%d,\"ble\":%d,\"blecap\":%d,\"tcp\":%d,\"name\":\"",
|
||||
"{\"t\":\"sg\",\"freq\":%.3f,\"bw\":%.1f,\"sf\":%d,\"cr\":%d,\"tx\":%d,\"wifi\":%d,\"ble\":%d,\"blecap\":%d,\"tcp\":%d,\"name\":\"",
|
||||
pr ? pr->freq : 0.0f, pr ? pr->bw : 0.0f, pr ? pr->sf : 0, pr ? pr->cr : 0, pr ? (int)pr->tx_power_dbm : 0,
|
||||
wc ? 1 : 0, g_lv.task->isBleEnabled() ? 1 : 0, g_lv.task->hasBleCapability() ? 1 : 0,
|
||||
g_lv.task->isTcpEnabled() ? 1 : 0);
|
||||
@@ -32929,15 +32974,20 @@ static void openMessageInfoPopup(int msg_idx) {
|
||||
blen += snprintf(body + blen, sizeof(body) - blen, "\nRoute");
|
||||
int off = 0;
|
||||
for (uint8_t h = 0; h < cnt && off + (int)hsz <= m.in_path_n; ++h, off += hsz) {
|
||||
if (blen >= (int)sizeof(body) - 56) break; // hard guard: never overflow body[]
|
||||
if (blen >= (int)sizeof(body) - 72) break; // hard guard: never overflow body[]
|
||||
// Always lead with the path-hash prefix, then the name when we know it.
|
||||
// The hash is what the node is actually keyed by on the wire, so it is
|
||||
// the part that stays true when a repeater is named misleadingly or two
|
||||
// of them share a name -- which is exactly when you are reading a route
|
||||
// (#348). Showing only the resolved name threw that away.
|
||||
char hashstr[9] = {0};
|
||||
for (uint8_t b = 0; b < hsz && b < 4; ++b)
|
||||
snprintf(hashstr + b * 2, sizeof(hashstr) - b * 2, "%02X", m.in_path[off + b]);
|
||||
char nm[33]; // ContactInfo.name is 32B; hold the full name (emoji eat 4B each)
|
||||
if (the_mesh.uiHopName(&m.in_path[off], hsz, nm, sizeof(nm))) {
|
||||
blen += snprintf(body + blen, sizeof(body) - blen, "\n %u. #%06X %s#",
|
||||
(unsigned)(h + 1), (unsigned)nodeSigColorHex(nm), nm);
|
||||
blen += snprintf(body + blen, sizeof(body) - blen, "\n %u. #%06X %s %s#",
|
||||
(unsigned)(h + 1), (unsigned)nodeSigColorHex(nm), hashstr, nm);
|
||||
} else {
|
||||
char hashstr[9] = {0};
|
||||
for (uint8_t b = 0; b < hsz && b < 4; ++b)
|
||||
snprintf(hashstr + b * 2, sizeof(hashstr) - b * 2, "%02X", m.in_path[off + b]);
|
||||
blen += snprintf(body + blen, sizeof(body) - blen, "\n %u. #%06X %s#",
|
||||
(unsigned)(h + 1), (unsigned)nodeSigColorHex(hashstr), hashstr);
|
||||
}
|
||||
@@ -36938,11 +36988,14 @@ static bool popupRegistryBlocksSwipe();
|
||||
// True if any popup/modal is currently up (rows flagged PF_COUNT).
|
||||
static bool anyPopupOpen() { return popupRegistryAny(); }
|
||||
|
||||
#if CAP_KEYBOARD
|
||||
#if CAP_KEYBOARD || CAP_KEYPAD_NAV
|
||||
// Close the topmost popup/modal (registry order = front-to-back priority),
|
||||
// like tapping its X / close button. Returns true if one was dismissed.
|
||||
// Widened past CAP_KEYBOARD for the Attaky: navGoToMainTab() (inside the
|
||||
// CAP_KEYPAD_NAV block) calls this, and that board navigates with a D-pad but
|
||||
// has no physical keyboard, so the old gate left the declaration undefined.
|
||||
static bool hwKeyDismissTopPopup() { return popupRegistryDismissTop(); }
|
||||
#endif // HAS_TDECK_KEYBOARD || HAS_TANMATSU (hwKeyDismissTopPopup)
|
||||
#endif // CAP_KEYBOARD || CAP_KEYPAD_NAV (hwKeyDismissTopPopup)
|
||||
|
||||
#if defined(HAS_TDECK_KEYBOARD) || defined(HAS_PAGER_KEYBOARD) || defined(HAS_M9_KEYBOARD)
|
||||
// Keys that act as "close the popup" when no text field is focused.
|
||||
@@ -38993,6 +39046,89 @@ if (g_lv.task && g_lv.task->isManualLock()) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ATTAKY_MESH_SERIES)
|
||||
// ---- Attaky front D-pad -> focus navigation ---------------------------------
|
||||
// The five nav buttons on the @0x59 expander (P00 down, P01 left, P02 select,
|
||||
// P03 right, P04 up) drive the SAME focus group the Tanmatsu arrows and the
|
||||
// T-Deck trackball use, so they reach every screen with no per-screen handling.
|
||||
// Touch stays this board's primary input and the D-pad is a second one — which
|
||||
// is why the focus ring starts hidden (s_nav_show is false until a press) and
|
||||
// nothing here is toggleable: the buttons are soldered on, so "off" would just
|
||||
// make them dead.
|
||||
//
|
||||
// This board compiles no handleHwKey() (its keyboard module types straight into
|
||||
// the focused textarea), so the nav routing the T-Deck and M9 do from there
|
||||
// lives here instead. Deliberately narrower than the M9's: that board has no
|
||||
// touch, so it also needs d-pad paths for Back, Home, the chat-bubble action
|
||||
// menu and map panning — all of which are still a tap away here.
|
||||
static void attakyNavPump() {
|
||||
// The field currently bound to the keyboard, and whether the D-pad should be
|
||||
// editing it: focus has to be really ON it (a tap sets s_nav_ta_editing), so
|
||||
// arrows moving through a page don't get swallowed as caret moves.
|
||||
lv_obj_t* const ta_focused = g_lv.keyboard ? lv_keyboard_get_textarea(g_lv.keyboard) : nullptr;
|
||||
lv_obj_t* const ta = (ta_focused && s_nav_ta_editing) ? ta_focused : nullptr;
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
const int ev = attakyNavKeyRead();
|
||||
if (ev == ATTAKY_NAV_NONE) break;
|
||||
|
||||
switch (ev) {
|
||||
case ATTAKY_NAV_UP:
|
||||
case ATTAKY_NAV_DOWN: {
|
||||
const bool up = (ev == ATTAKY_NAV_UP);
|
||||
// The @-mention picker owns up/down while it shows: its cells carry
|
||||
// NAV_SKIP_FLAG (they're tap targets on touch boards), so the focus
|
||||
// group cannot reach them at all.
|
||||
if (mentionNavActive()) { mentionNavMove(up ? -1 : +1); break; }
|
||||
// An open dropdown LIST owns them too — navMoveDir would move focus
|
||||
// off the dropdown, which closes it. The FIFO'd LV_KEY_UP/DOWN reach
|
||||
// the dropdown's own handler, which moves the highlighted option.
|
||||
if (navOpenDropdown()) { navPushTap(up ? LV_KEY_UP : LV_KEY_DOWN); break; }
|
||||
lv_obj_t* const was = s_nav_group ? lv_group_get_focused(s_nav_group) : nullptr;
|
||||
navMoveDir(up ? NAV_UP : NAV_DOWN);
|
||||
// Focus had nowhere to go: page-scroll instead. A display-only Lua app
|
||||
// scrolls its own body; everything else falls to navScrollFocused, so
|
||||
// pages with few or no focusable rows still move under the D-pad.
|
||||
if (s_nav_group && lv_group_get_focused(s_nav_group) == was) {
|
||||
if (!(luaAppIsOpen() && luaAppScroll(up))) navScrollFocused(up);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATTAKY_NAV_LEFT:
|
||||
case ATTAKY_NAV_RIGHT: {
|
||||
const bool left = (ev == ATTAKY_NAV_LEFT);
|
||||
if (mentionNavActive() || navOpenDropdown()) break; // vertical-only: swallow
|
||||
if (ta) {
|
||||
// Caret already at the edge: fall through to a focus move, so the
|
||||
// pad always eventually LEAVES the field instead of no-oping.
|
||||
const uint32_t p = lv_textarea_get_cursor_pos(ta);
|
||||
if (left) lv_textarea_cursor_left(ta); else lv_textarea_cursor_right(ta);
|
||||
if (lv_textarea_get_cursor_pos(ta) == p) navMoveDir(left ? NAV_LEFT : NAV_RIGHT);
|
||||
}
|
||||
else if (navOnTabBar()) navSwitchTab(left ? -1 : +1);
|
||||
else navMoveDir(left ? NAV_LEFT : NAV_RIGHT);
|
||||
break;
|
||||
}
|
||||
case ATTAKY_NAV_SELECT:
|
||||
if (mentionNavActive()) { mentionNavConfirm(); break; }
|
||||
if (navOnTabBar()) { navSwitchTab(+1); break; }
|
||||
// First SELECT on a focused field starts typing (the caret appears and
|
||||
// left/right walk it); the next one activates whatever is focused.
|
||||
if (ta_focused && !ta && s_nav_group && lv_group_get_focused(s_nav_group) == ta_focused) {
|
||||
s_nav_ta_editing = true;
|
||||
break;
|
||||
}
|
||||
navMarkEntered(s_nav_group ? lv_group_get_focused(s_nav_group) : nullptr);
|
||||
navPushTap(LV_KEY_ENTER);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
s_nav_show = true;
|
||||
if (g_lv.task) g_lv.task->noteUserInput();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void refreshLiveDiag(unsigned long now) {
|
||||
if (!s_live_diag_label) return;
|
||||
if (now < s_live_diag_next_ms) return;
|
||||
@@ -51566,6 +51702,12 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
uint16_t to_s = touchPrefsGetScreenTimeoutSecs();
|
||||
_screen_timeout_ms = static_cast<uint32_t>(to_s) * 1000u;
|
||||
s_lock_on_screen_off = touchPrefsGetLockOnScreenOff();
|
||||
#if defined(HAS_TDECK_KEYBOARD)
|
||||
// Applied here rather than at tdeckKeyboardBegin(), which runs on the touch
|
||||
// task before prefs are up. The driver re-checks this every poll, so it takes
|
||||
// effect on the next one either way, including demoting out of raw mode.
|
||||
tdeckKeyboardForceLegacy(touchPrefsGetKbForceLegacy());
|
||||
#endif
|
||||
#endif
|
||||
_last_input_ms = millis();
|
||||
_screen_off = false;
|
||||
@@ -52032,6 +52174,11 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
#if defined(ESP32)
|
||||
#if defined(HAS_TANMATSU) || defined(HAS_THINKNODE_M9)
|
||||
s_kbd_nav = true; // keyboard-only device: nav is always on (no touch to fall back to)
|
||||
#elif defined(ATTAKY_MESH_SERIES)
|
||||
// Soldered-on D-pad, and no settings row toggles it (the "Keyboard navigation"
|
||||
// switch is CAP_TRACKBALL-only) — reading the pref here would let a value left
|
||||
// over from another board leave the buttons dead with no way to turn them back on.
|
||||
s_kbd_nav = true;
|
||||
#else
|
||||
s_kbd_nav = touchPrefsGetKbdNav();
|
||||
#endif
|
||||
@@ -55023,6 +55170,22 @@ void UITask::loop() {
|
||||
if (_screen_off) wakeScreen();
|
||||
else sleepScreen();
|
||||
}
|
||||
// Front D-pad (P00..P04) -> focus navigation. Two things have to happen before
|
||||
// the drain: with the screen dark a press only WAKES (and is swallowed, so a
|
||||
// wake never also activates whatever the ring happened to be on — the pager's
|
||||
// encoder-wake bug), and in remote mode the panel is a placeholder the browser
|
||||
// drives. Otherwise sync the focus group to the current tree first: Enter's
|
||||
// tree mutations only land inside lv_timer_handler at the END of a tick, so a
|
||||
// drain against a stale mirror navigates the screen behind a just-opened modal
|
||||
// (the same fix the M9's branch above carries).
|
||||
if (_screen_off || s_remote_mode) {
|
||||
const bool any = (attakyNavKeyRead() != ATTAKY_NAV_NONE);
|
||||
attakyNavKeysDiscard();
|
||||
if (any && _screen_off) wakeScreen();
|
||||
} else {
|
||||
navMaybeRebuild();
|
||||
attakyNavPump();
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ATTAKY_MESH_KEYBOARD)
|
||||
{
|
||||
|
||||
@@ -163,13 +163,16 @@
|
||||
// Focus-group D-pad navigation (no pointer): Tanmatsu keypad, T-Deck trackball,
|
||||
// the pager (no touch at all — the rotary encoder is its only nav input, so
|
||||
// like Tanmatsu this is always-on, not an optional toggle like the T-Deck's),
|
||||
// or the ThinkNode M9's d-pad. The underlying machinery (navFifo, navMoveDir,
|
||||
// the focus group, the secondary KEYPAD indev) is generic — only the *pump*
|
||||
// that feeds it differs per board: Tanmatsu's navPump() reads bsp-input events;
|
||||
// T-Deck's WASDZ-letter nav and the M9's raw d-pad bytes are both fed straight
|
||||
// from handleHwKey() instead (see UITask.cpp's `#elif defined(HAS_M9_KEYBOARD)`
|
||||
// block, parallel to the T-Deck's `#if CAP_TRACKBALL` block).
|
||||
#if defined(HAS_TANMATSU) || defined(HAS_TDECK_TRACKBALL) || defined(TLORA_PAGER) || defined(HAS_THINKNODE_M9)
|
||||
// the ThinkNode M9's d-pad, or the Attaky's front D-pad + SELECT. The underlying
|
||||
// machinery (navFifo, navMoveDir, the focus group, the secondary KEYPAD indev)
|
||||
// is generic — only the *pump* that feeds it differs per board: Tanmatsu's
|
||||
// navPump() reads bsp-input events; T-Deck's WASDZ-letter nav and the M9's raw
|
||||
// d-pad bytes are both fed straight from handleHwKey() instead (see UITask.cpp's
|
||||
// `#elif defined(HAS_M9_KEYBOARD)` block, parallel to the T-Deck's `#if
|
||||
// CAP_TRACKBALL` block); the Attaky drains its expander queue in attakyNavPump().
|
||||
// NOTE: the Attaky is the first board here with CAP_KEYBOARD == 0, so anything
|
||||
// this flag pulls in must not assume a physical keyboard is also compiled.
|
||||
#if defined(HAS_TANMATSU) || defined(HAS_TDECK_TRACKBALL) || defined(TLORA_PAGER) || defined(HAS_THINKNODE_M9) || defined(ATTAKY_MESH_SERIES)
|
||||
#define CAP_KEYPAD_NAV 1
|
||||
#else
|
||||
#define CAP_KEYPAD_NAV 0
|
||||
|
||||
@@ -404,7 +404,7 @@ static const I18nPair kBuiltin_hu[] = {
|
||||
{ "Join hashtag channel", "Csatlakozz # csatornához" },
|
||||
{ "Join network", "Csatlakozás a hálózathoz" },
|
||||
{ "Join private channel", "Csatlakozz privát csatornához" },
|
||||
{ "Join the public channel", "Csatlakozás a nyilvános csatornához" },
|
||||
{ "Join the public channel", "Belépés a nyilvánoshoz" },
|
||||
{ "Join w/ password", "Csatlakozás jelszóval" },
|
||||
{ "Joined %.40s", "Csatlakozott %.40s alatt" },
|
||||
{ "Keep per chat (messages)", "Megőrzés csevegésenként (üzenet)" },
|
||||
@@ -418,6 +418,7 @@ static const I18nPair kBuiltin_hu[] = {
|
||||
{ "Keyboard nav: off", "Billentyűzetnavigáció: kikapcsolva" },
|
||||
{ "Keyboard navigation", "Billentyűzetnavigáció" },
|
||||
{ "Keys", "Kulcsok" },
|
||||
{ "Known regions", "Ismert régiók" },
|
||||
{ "LOS → %s", "Rálátás → %s" },
|
||||
{ "Landscape (desktop)", "Fekvő (asztali)" },
|
||||
{ "Landscape set - applies when remote mode starts.", "Fekvő beállítva - a távoli mód indulásakor lép életbe." },
|
||||
@@ -482,6 +483,7 @@ static const I18nPair kBuiltin_hu[] = {
|
||||
{ "Map — set your location\nin Settings → Profile to\nshow the map here.", "Térkép – a Beállítások → Profil menüpontban állítsd be a tartózkodási helyedet, hogy itt jelenjen meg a térkép." },
|
||||
{ "Mark all chats and channels as read?", "Az összes csevegést és csatornát megjelölöd olvasottként?" },
|
||||
{ "Mark as read", "Olvasottnak jelöl" },
|
||||
{ "Mark read", "Olvasott" },
|
||||
{ "Marked read", "Olvasottként megjelölve" },
|
||||
{ "Max dots", "Max. pontok" },
|
||||
{ "Max hops (0..64)", "Max ugrások (0-64)" },
|
||||
@@ -934,7 +936,7 @@ static const I18nPair kBuiltin_hu[] = {
|
||||
{ "Type", "Tipus" },
|
||||
{ "Type a URL, then Go", "Írj be egy URL-t, majd Mehet" },
|
||||
{ "Type a message...", "Írj be egy üzenetet..." },
|
||||
{ "Type a new 6-digit code · applies after a reboot", "Írjon be egy új 6 jegyű kódot · újraindítás után érvényes" },
|
||||
{ "Type a new 6-digit code · applies after a reboot", "Írjon be egy 6 jegyű kódot · újraindítás után él" },
|
||||
{ "Type your network name — or switch to Wi-Fi in Settings to scan", "Írd be a hálózatod nevét – vagy válts Wi-Fi-re a beállításokban a kereséshez" },
|
||||
{ "UI size (restart to apply)", "UI mérete (újraindítás az alkalmazáshoz)" },
|
||||
{ "UI size saved — restart to apply", "UI mérete mentve – indítsa újra a programot az alkalmazáshoz" },
|
||||
|
||||
@@ -20,15 +20,50 @@ static const uint8_t POWER_BIT = (1u << 7); // P07 = POWER_BTN
|
||||
static const uint8_t DEBOUNCE_POLLS = 2;
|
||||
static const uint32_t POLL_INTERVAL_MS = 30;
|
||||
|
||||
// Auto-repeat for the four directions (never SELECT — one press must stay one
|
||||
// activation). Without it, walking a long contact list means one press per row.
|
||||
static const uint32_t REPEAT_DELAY_MS = 450;
|
||||
static const uint32_t REPEAT_RATE_MS = 130;
|
||||
|
||||
// P0 bit -> nav event. 0 = not a nav button (L1/R2 are read but unbound, POWER
|
||||
// has its own edge flag below).
|
||||
static const uint8_t BIT_NAV[8] = {
|
||||
ATTAKY_NAV_DOWN, // P00
|
||||
ATTAKY_NAV_LEFT, // P01
|
||||
ATTAKY_NAV_SELECT, // P02
|
||||
ATTAKY_NAV_RIGHT, // P03
|
||||
ATTAKY_NAV_UP, // P04
|
||||
ATTAKY_NAV_NONE, // P05 BTN_L1 — unbound
|
||||
ATTAKY_NAV_NONE, // P06 BTN_R2 — unbound
|
||||
ATTAKY_NAV_NONE, // P07 POWER_BTN — attakyPowerKeyPressed()
|
||||
};
|
||||
|
||||
static bool s_inited = false;
|
||||
static bool s_present = false;
|
||||
static uint32_t s_next_ms = 0;
|
||||
|
||||
static bool s_power_down = false; // debounced state
|
||||
static uint8_t s_pending_n = 0; // consecutive polls agreeing with s_pending_down
|
||||
static bool s_pending_down = false;
|
||||
// Debounced whole-port state, active-low (a 0 bit = that button is down).
|
||||
static uint8_t s_stable = 0xFF;
|
||||
static uint8_t s_pending = 0xFF; // candidate awaiting DEBOUNCE_POLLS agreement
|
||||
static uint8_t s_pending_n = 0;
|
||||
static volatile bool s_power_event = false;
|
||||
|
||||
// Nav press queue. Small ring: the poll runs at ~30 ms and the UI drains every
|
||||
// tick, so it only has to absorb a burst, never buffer.
|
||||
static const uint8_t NAV_Q_LEN = 8;
|
||||
static uint8_t s_navq[NAV_Q_LEN];
|
||||
static uint8_t s_navq_head = 0, s_navq_tail = 0;
|
||||
|
||||
static int8_t s_repeat_bit = -1; // direction currently held, or -1
|
||||
static uint32_t s_repeat_ms = 0; // when it next repeats
|
||||
|
||||
static void navPush(uint8_t ev) {
|
||||
const uint8_t next = (uint8_t)((s_navq_head + 1) % NAV_Q_LEN);
|
||||
if (next == s_navq_tail) return; // full — drop the newest rather than stall
|
||||
s_navq[s_navq_head] = ev;
|
||||
s_navq_head = next;
|
||||
}
|
||||
|
||||
static bool awWrite(uint8_t reg, uint8_t val) {
|
||||
Wire.beginTransmission(KEYS_ADDR);
|
||||
Wire.write(reg);
|
||||
@@ -75,14 +110,37 @@ void attakyKeysPoll() {
|
||||
}
|
||||
if (!ok) return; // bus busy or read failed — hold the previous state
|
||||
|
||||
const bool down = (p0 & POWER_BIT) == 0; // active low
|
||||
// Every button reading pressed at once is a bad read, not a hand: acting on
|
||||
// it would inject a burst of nav keys AND a panel toggle from one glitch.
|
||||
// Resync the debouncer instead of treating the recovery as presses.
|
||||
if (p0 == 0x00) { s_pending = s_stable; s_pending_n = 0; return; }
|
||||
|
||||
if (down != s_pending_down) { s_pending_down = down; s_pending_n = 1; return; }
|
||||
if (p0 != s_pending) { s_pending = p0; s_pending_n = 1; return; }
|
||||
if (s_pending_n < DEBOUNCE_POLLS) { s_pending_n++; return; }
|
||||
|
||||
if (down != s_power_down) {
|
||||
s_power_down = down;
|
||||
if (down) s_power_event = true; // fire on the press edge
|
||||
const uint8_t changed = (uint8_t)(s_stable ^ p0);
|
||||
if (changed) {
|
||||
const uint8_t went_down = (uint8_t)(changed & ~p0); // active low: 1 -> 0
|
||||
s_stable = p0;
|
||||
if (went_down & POWER_BIT) s_power_event = true; // fire on the press edge
|
||||
for (uint8_t b = 0; b < 8; b++) {
|
||||
if (!(went_down & (1u << b)) || BIT_NAV[b] == ATTAKY_NAV_NONE) continue;
|
||||
navPush(BIT_NAV[b]);
|
||||
// Only the directions repeat, and only the most recent one: rolling a
|
||||
// thumb across the pad should follow the finger, not fire two axes.
|
||||
if (BIT_NAV[b] != ATTAKY_NAV_SELECT) {
|
||||
s_repeat_bit = (int8_t)b;
|
||||
s_repeat_ms = now + REPEAT_DELAY_MS;
|
||||
}
|
||||
}
|
||||
// The repeating direction was released (or another button's edge arrived
|
||||
// while it was already up) — stop repeating.
|
||||
if (s_repeat_bit >= 0 && (s_stable & (1u << (uint8_t)s_repeat_bit))) s_repeat_bit = -1;
|
||||
}
|
||||
|
||||
if (s_repeat_bit >= 0 && (int32_t)(now - s_repeat_ms) >= 0) {
|
||||
navPush(BIT_NAV[(uint8_t)s_repeat_bit]);
|
||||
s_repeat_ms = now + REPEAT_RATE_MS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,12 +150,26 @@ bool attakyPowerKeyPressed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int attakyNavKeyRead() {
|
||||
if (s_navq_tail == s_navq_head) return ATTAKY_NAV_NONE;
|
||||
const uint8_t ev = s_navq[s_navq_tail];
|
||||
s_navq_tail = (uint8_t)((s_navq_tail + 1) % NAV_Q_LEN);
|
||||
return (int)ev;
|
||||
}
|
||||
|
||||
void attakyNavKeysDiscard() {
|
||||
s_navq_tail = s_navq_head;
|
||||
s_repeat_bit = -1;
|
||||
}
|
||||
|
||||
bool attakyKeysPresent() { return s_present; }
|
||||
|
||||
#else
|
||||
|
||||
void attakyKeysPoll() {}
|
||||
bool attakyPowerKeyPressed() { return false; }
|
||||
int attakyNavKeyRead() { return ATTAKY_NAV_NONE; }
|
||||
void attakyNavKeysDiscard() {}
|
||||
bool attakyKeysPresent() { return false; }
|
||||
|
||||
#endif
|
||||
@@ -3,9 +3,24 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// Front buttons on the board's AW9523 @0x59 (P00-P07, active-low). Only
|
||||
// POWER_BTN (P07) is used: short-press toggles the panel. A long press is the
|
||||
// board's hardware power-cut, outside firmware control.
|
||||
// Front buttons on the board's AW9523 @0x59 (P00-P07, active-low), per Attaky's
|
||||
// hardware catalog:
|
||||
// P00 DOWN P01 LEFT P02 SELECT P03 RIGHT P04 UP
|
||||
// P05 BTN_L1 (top-left shoulder) P06 BTN_R2 (top-right shoulder)
|
||||
// P07 POWER_BTN
|
||||
// POWER_BTN short-press toggles the panel (a long press is the board's hardware
|
||||
// power-cut, outside firmware control). The D-pad + SELECT feed the UI's focus
|
||||
// navigation. L1/R2 are read but deliberately unbound — nothing claims them yet.
|
||||
|
||||
/** D-pad events drained by attakyNavKeyRead(). */
|
||||
enum AttakyNavKey {
|
||||
ATTAKY_NAV_NONE = 0,
|
||||
ATTAKY_NAV_UP,
|
||||
ATTAKY_NAV_DOWN,
|
||||
ATTAKY_NAV_LEFT,
|
||||
ATTAKY_NAV_RIGHT,
|
||||
ATTAKY_NAV_SELECT,
|
||||
};
|
||||
|
||||
/** Poll the expander. Call once per UI tick; rate-limits its own I2C traffic. */
|
||||
void attakyKeysPoll();
|
||||
@@ -13,5 +28,11 @@ void attakyKeysPoll();
|
||||
/** True once per POWER_BTN press edge (consumes the event). */
|
||||
bool attakyPowerKeyPressed();
|
||||
|
||||
/** Next queued D-pad event, or ATTAKY_NAV_NONE when the queue is empty. */
|
||||
int attakyNavKeyRead();
|
||||
|
||||
/** Drop every queued D-pad event (screen-off wake, remote mode). */
|
||||
void attakyNavKeysDiscard();
|
||||
|
||||
/** Whether the @0x59 expander answered at init (false = keys unavailable). */
|
||||
bool attakyKeysPresent();
|
||||
Reference in new issue
Block a user