Commit Graph
1334 Commits
Author SHA1 Message Date
Michael A. CojocariandCopilot b247fa3ace Wio Tracker L2: Clock settings and the cold-boot time sync
The Wio Tracker L2 has no battery-backed clock, so it gets the same
opt-in saved-Wi-Fi time sync at power-on as the T-Deck
(CAP_BOOT_TIME_SYNC / BootTimeSync).

Split out of 4844a9b (Touch UI follow-ups 4).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-13 09:31:38 -04:00
Michael A. CojocariandCopilot 9d7da2354d M9 chat: # and emoji move left of the message input
The composer reads QR | # | emoji | text | Send. With the caret at the
start of the input, LEFT walks to emoji, then #; RIGHT walks back.

Split out of 4844a9b (Touch UI follow-ups 4).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-13 09:31:38 -04:00
Michael A. CojocariandClaude Opus 5.5 10e0f84b35 Channel region scope on phone-app channel sends too (#614)
CMD_SEND_CHANNEL_TXT_MSG called sendGroupMessage directly, so a post from
the phone app on a scoped channel went out on the default scope. It now
pushes the channel's scope for the send and pops it afterwards, as the
on-device composer, web remote, terminal and Lua sends do. Touch builds
only, where per-channel scopes are stored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yt7fNCKmafm9LtRjyuUmS
2026-10-13 09:31:38 -04:00
Michael A. CojocariandClaude Opus 5.5 94a7c13ef5 M9: name the 0x88 key by its triangle; it no longer opens chat options
The key is printed with a triangle, not a microphone, so the docs and the
code now call it the triangle key (M9_KEY_TRIANGLE). In an open chat it
used to open the thread's options; keypad navigation reaches the
conversation header for that now (#623), so the key keeps only its other
job, the focused item's hold action. M9_PORT.md no longer calls it
unbound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yt7fNCKmafm9LtRjyuUmS
2026-10-13 09:31:38 -04:00
Michael A. Cojocari b63b4f3904 M9 and Tanmatsu feedback from #609
- M9: double-press Home opens the launcher settings (what Home opens, icon size)
- M9: "Mark all as read" is the first item in the chats menu
- M9: MIC key opens the chat options in a chat, else the focused item's hold action
- M9: stronger focus on the map overlay buttons
- M9: the at-a-glance card shows even when the message-flash wake lit the screen first
- Tanmatsu: screensaver preview ignores input for its first 1.2 s so it no longer ends at once

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit f479382c9b12070cffae530e3b4789d689c441c5)
2026-10-13 09:31:38 -04:00
Michael A. Cojocari 1700366f3f M9: white tab bar while the map loads, double-press Home for Settings, bubble-only chat cursor
- Map: the transparent tab bar shows white icons from opening the Map tab until
  its first tile render finishes, then returns to its map colours.
- Home: a second press within 450 ms opens Settings. The keyboard controller
  sends no key-up or long-press code for Home, so a hold can't be detected.
- Chat: the keypad cursor surrounds the message bubble only, not the info
  line under it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit 9523475232aa1a73e2c7c3395888407dfd4020c8)
2026-10-13 09:31:38 -04:00
Michael A. Cojocari 7f4d3fd0b6 M9: action menus focus first row (X last); lift message-menu X clear of buttons
The ⋯ / thread action list creates its close X after the rows on the M9, so
keypad focus opens on the first action and reaches the X last. The message
action menu's X moves up into the card padding so the first button row no
longer clips its focus cursor. Other boards unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit 8fdb23ce5f5dbf58514304ab3be7a5dd04c4cdd8)
2026-10-13 09:31:37 -04:00
Michael A. Cojocari 2964ff02e3 fix(time): cold-boot Wi-Fi time sync gets past a slow first join (#620)
The first attempt on the active network brings the radio up from cold and
searches every channel for the AP, inside the same 4 s as every other
attempt. A T-Deck that joins in about 7 s by hand never made it, and the
scan retry then skipped that network as already tried, so a home with one
saved network always ended "no association".

The first attempt now gets 8 s. The scan retry keeps the active network
and joins each candidate on the channel and BSSID the scan found it on,
which skips the all-channel search. The whole session is capped at 16 s
(was 12 s) so the retry and SNTP still fit.

Fixes #620

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yt7fNCKmafm9LtRjyuUmS
(cherry picked from commit 477e0163ccf64d65706737a9558f1ef9ab439539)
2026-10-13 09:31:37 -04:00
Michael A. Cojocari 9bbe0a468b Chat: compact rows fit emoji; composer keeps the newest message in view and its text inside the box (#617)
- Compact rows that carry a colour emoji get its overhang above the text
  line as extra top padding, measured into the row height so the
  virtualizer agrees (chatCompactEmojiLift).
- When the composer grows while the list is at the bottom, the list is
  scrolled back to the newest message instead of being covered.
- The composer's corner radius stays at its one-line size, so a four-line
  box no longer curves through the start and end of its lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QkSqsocfpbhCD2AtpskvQo
(cherry picked from commit 867db9917e682ac24f2542ecd77224fcf27f232a)
2026-10-13 09:31:37 -04:00
Michael A. Cojocari 2463bc238b Channel region scope on web remote, terminal and Lua sends (#614)
The chat composer tagged a channel post with the channel's own region scope,
but termDoSend (web remote and terminal) and luaHostMeshSendChannel called
sendGroupMessage directly, so those posts went out on the default scope.
All three now go through sendGroupMessageScoped, which pushes the channel's
scope for the send and pops it afterwards.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit fa1ec9868fdee31922ee57a5ed0a940522bb86c1)
2026-10-13 09:31:37 -04:00
Michael A. Cojocari ae473ee86d Contacts: A-Z sorts by name only; Select all covers every contact (#605)
- Name (A-Z) no longer sinks "?" (never heard) contacts below the heard
  ones; that rule now applies to the Last heard / Last message modes
  only. Favourites with and without a last-heard sort together by name.
- Select all selected at most 128 contacts, in storage order, while the
  list shows the first 128 in sorted order. Past 128 contacts it picked
  mostly rows that were not on screen, so nothing visible was ticked and
  a delete seemed to do nothing. The selection is now sized to
  MAX_CONTACTS and Select all takes every non-favourite that passes the
  filter.
- Bulk delete removes without saving (uiRemoveContactNoSave) and writes
  /contacts3 once at the end, keeps only the public keys for the run,
  and matches the selection by binary search.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QkSqsocfpbhCD2AtpskvQo
(cherry picked from commit f30ca794039ff11358903938d70e402019908776)
2026-10-13 09:31:37 -04:00
Michael A. Cojocari 477b7d5981 fix(touch): backup Import dialog opens on Import, loops Import/Cancel, no X (#603)
On the T-LoRa Pager the "Import this backup?" confirm started on the
close X, then stopped on the message text before reaching the buttons:
keypad navigation follows the card's tree order (X, message, Cancel,
Import), and confirmBackupImport() used none of showConfirm()'s options
for that.

- confirmBackupImport() now passes actions_only_nav (the message box is
  not a focus stop) and focus_confirm (focus opens on Import). With two
  stops, the group's wrap loops Import <-> Cancel in both directions.
- showConfirm() no longer creates the X at all for actions_only_nav
  dialogs, rather than only skipping it in navigation. Cancel and the
  Back key already dismiss them. The Purge-discovered dialog uses the
  same flag and loses its X too, which keeps the two consistent.

Fixes #603

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zE15egJdCZ9nRBZmg1YUq
(cherry picked from commit 1df7b93ef91d5ca3790271e3d216409988cabf1c)
(cherry picked from commit 29a842b4a2de8bb2ff8a849b14d57955d17b2729)
2026-10-13 09:31:37 -04:00
Kaj SchittecatandClaude Opus 5.5 6c6fb32d8d i18n: rows for the beta_94 strings
Temperature in Fahrenheit, Up to 15 characters and Favorites only in all 14
languages; the full-Home toast as an English placeholder like the other Home
widget strings. The V4 keeps its pinned beta_92 table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:24:59 +02:00
Kaj SchittecatandClaude Opus 5.5 3b47e089b3 touch: temperatures in Fahrenheit, as an option
"Temperature in Fahrenheit" next to "Distance in miles" (Settings > Display >
Status bar & units), asked for on Discord. Only what is shown converts: the
sensor text, Sensors widget and page, remote sensor widget, telemetry replies
and chart (its axis, shared with humidity, already spans -20..100). Stored
readings, logs, telemetry sent out and the Lua SDK stay in degrees C. Saved as
a one-byte blob (temp_f), so no settings-schema bump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:24:59 +02:00
Kaj SchittecatandClaude Opus 5.5 0b409b1f3c touch(admin): the login password field says it takes up to 15 characters
MeshCore carries at most 15: the core's sendLogin() cuts there and stock
servers store 15, on the phone app too. A longer password is used as its first
15 characters, which the empty field never said (Discord).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:24:59 +02:00
Kaj SchittecatandClaude Opus 5.5 57d1840df6 touch(home): the radar fits a two-cell slot; a full Home says how to make room
The radar was 2x2 only, and the default Glance layout fills all twelve cells
of the T-Deck grid, so adding it (or anything) only flashed "No room for it
on Home" (Discord). The radar now also comes in the two-across size (it draws
into the shorter side), and when no cell at all is free the toast says to hold
a widget to remove one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:24:59 +02:00
Kaj SchittecatandClaude Opus 5.5 46279eef92 touch(chats): a text symbol picked as a chat icon is drawn (#647)
The icon picker's last rows are text symbols (a star, a heart, a currency
sign). They were saved and announced as "Chat icon set", but the avatar only
draws colour-emoji images, so the plain avatar stayed. Now a pick with no
colour glyph is drawn as text in the colour the initials had.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:24:59 +02:00
CyrioandClaude Opus 5.5 6ee9424ece i18n: wording nits from review (nl, de, hu)
jcyrio's follow-up to #632 (ea2315e), pushed after the merge so it never
reached main. Only the .lang rows; i18n_builtin.h is generated and the V4
builds from its pinned copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:18:50 +02:00
Kaj SchittecatandClaude Opus 5.5 1130ed62e3 Merge follow-ups: Pager shortcut table says Nothing, built-in language table back to the V4 pin
#624's new Special keys row ended in an em dash; the other rows say Nothing.
#635 edited the generated i18n_builtin.h; regenerated from the pinned
beta_92 .lang copy the V4 builds from, so the V4 table is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:18:37 +02:00
Kaj Schittecat 133df4ca7f Merge PR #635 (Confituurke): feat(ui): pick your advert position on the map 2026-10-13 09:18:20 +02:00
Kaj Schittecat 01182d1be1 Merge PR #624 (jcyrio): Pager: Fn+V pastes the clipboard (no touch path to the edit menu) 2026-10-13 09:18:18 +02:00
Kaj Schittecat 4e73bcc34a Merge PR #645 (oumike): T-Deck Pro / Max: Normal, Large and Huge text sizes, as on the T-Deck (#639) 2026-10-13 09:18:17 +02:00
Kaj Schittecat f817646932 Merge PR #658 (oumike): Day mode: readable figures on the count badges (#657) 2026-10-13 09:18:15 +02:00
Kaj Schittecat 449b8abb67 Merge PR #649 (oumike): Contacts: show the chat icon, picked or the first emoji in the name (#646) 2026-10-13 09:18:14 +02:00
Kaj Schittecat 18882e975a Merge PR #650 (oumike): web app: add Reply to channel message long-press (#642) 2026-10-13 09:18:13 +02:00
Kaj Schittecat 016983e4b9 Merge PR #656 (oumike): Keyboard: readable labels on the control keys 2026-10-13 09:18:12 +02:00
Kaj SchittecatandClaude Opus 5.5 2d5e1b25ad touch(home): the Advert widget is a solid button again (#637)
hwAdvertBuild recoloured only bg_color. On glass (the aurora default) the box
is a translucent gradient into the panel colour, and the widget's dark
ON_GLOW text vanished on it. Gradient off, opacity full.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:18:05 +02:00
Kaj SchittecatandClaude Opus 5.5 793660f3fd touch(map): "Favorites only" in the map options
A switch under "Direct (0-hop) only" that leaves only favourite contacts on
the map (markers and link lines), asked for on Discord. Saved as a one-byte
blob (map_fav), so no settings-schema bump. Both filters now go through one
mapHidesContact() check, and the favourites list is read once per render
instead of a blob read per contact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:18:05 +02:00
Kaj SchittecatandClaude Opus 5.5 c8dc7f486e touch(home): the radar widget's tap opens the screensaver the way Settings' preview does
hwRadarTap called ssaverStart() directly, which never marked the screen off,
so loop() tore the saver down again on its next pass: a tap only flickered it
and dipped the backlight to 40% for a frame. It now sets the same preview
request as Settings, which starts it and marks the screen off, so it stays
until a touch ends it. ssaverStart() also refuses a second start, so the
dimmed 40% can never be saved as the user's brightness.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 09:18:05 +02:00
Pratik Patel 8dbb349fc6 thinknode_m9: pick GPS enable polarity from the board revision
The GPS enable pin (GPIO11) is active-LOW on the original ThinkNode-M9 but
active-HIGH on the newer revision (keyboard controller at 0x6D, e.g. Elecrow's
Meshtastic SKU LMM15409D2). Driven LOW on those units the GPS never gets a
fix: on one unit, same spot, 0 satellites with EN active-LOW vs 15 with
active-HIGH, and 34 after 20 minutes outdoors with the GPS toggled off and on
again from the UI. Meshtastic's ELECROW-ThinkNode-M9 variant makes the same
split, keyed on the same keyboard address (m9Version > 1 ? HIGH : LOW), and
Elecrow engineers have confirmed the split.

WadaNmeaLocationProvider: keep the enable level in a member that defaults to
the compile-time GPS_EN_ACTIVE, add setEnActive() to override it at runtime
(re-driving the pin so a running GPS stays on), and an optional
setPostEnableHook() run at the end of begin(). Every other board is unaffected.

thinknode_m9: m9KeyboardAddr() and a one-shot found-callback on the keyboard
driver; target.cpp uses it, when the controller is at 0x6D, to call
gps.setEnActive(true) and to register a GPIO10 wake pulse (50 ms, HIGH 5 ms,
LOW, 50 ms) after enabling, as Elecrow engineers confirmed. Any other address
keeps the existing default (LOW, no pulse), so the 0x6C path is unchanged; it
is not tested here, no 0x6C unit was available.

Depends on the keyboard 0x6D probe change.

Signed-off-by: Pratik Patel <Pratik@MakerNova.io>
2026-10-13 08:22:55 +02:00
Kaj Schittecat 9cd10dfe30 Merge PR #662 (Bfindlay): detect the ThinkNode M9 V1.1 keyboard at 0x6D (#644) 2026-10-13 08:22:30 +02:00
bfindlay 7025f79b30 no-mistakes(lint): Guard host-test runner against failed directory changes 2026-10-13 15:00:33 +11:00
bfindlay 04d8a606c5 no-mistakes(document): Consolidate M9 keyboard address documentation 2026-10-13 14:59:30 +11:00
bfindlay ad13d42a12 Fix M9 keyboard detection at the V1.1 I2C address
Signed-off-by: bfindlay <bfindlay@acm.org>
2026-10-13 14:43:28 +11:00
Michael A. CojocariandCopilot d94273bde3 Badges: paper-white with a black ring on the T-Deck Pro (#657)
The Day glow fill thresholds to solid black on e-paper, and the 11 px
anti-aliased white figures mostly fall under the one-bit cut, so every
count badge read as a black blob. On the Pro the tab-bar/launcher pills,
the Chats badge and the Discovered-nodes badge now draw white with a 1 px
black ring and black figures, like the Pro's avatars and buttons.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 19:39:51 -04:00
Michael A. CojocariandCopilot 0cba7ce037 Badges: figures in the glow's ink, readable in Day (#657)
The unread and Discovered count badges hard-coded Night's dark ink
(0x00201C) on the glow fill. Day's glow is the accent darkened, so the
figures read at 1.6-2.4:1 on every preset accent. Use COLOR_ON_GLOW,
which the theme already sets per mode and look (white in Day, the
look's own ink for Neon and Pastel). Under MORE COLORS! the chat-row
pill takes the row's hue, so its figures pick their ink by that hue's
luma, as Taste the rainbow's drifting badge already does.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 18:22:33 -04:00
Michael A. CojocariandCopilot 11dd04c6b7 Keyboard: theme text colour on the control keys
The control keys (1#, ABC, backspace, enter, the arrows, the tick) are
CHECKED keys. The stock theme's CHECKED key style carries its light-mode
text colour, near black, and a CHECKED style outranks the plain key text
colour, so their labels were dark on every theme. Set the theme text
colour on our CHECKED key style as well.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-12 11:10:23 -04:00
Michael A. CojocariandCopilot c05153ef85 web app: add Reply to the channel message long-press sheet
Long-pressing someone else's message in a channel chat in the remote web
app now offers Reply (above Copy and Info). It prefills the composer with
the device's mention syntax '@[sender] ', keeps any draft, clamps to the
160-char limit and focuses the input. DMs and our own messages are
unchanged.

Fixes #642

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-11 13:46:37 -04:00
Michael A. CojocariandCopilot b0a6f59ea3 Contacts: show the chat icon, picked or the first emoji in the name (#646)
The Contacts list now gives each contact the same icon as its chat: the
chat icon picked for it (keyed on the advertised name), else the first
emoji in its shown name, as #640 does for the chat list. Picking or
resetting a chat icon marks the Contacts list for a rebuild.

Fixes #646

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-11 13:00:53 -04:00
Michael A. CojocariandCopilot 67680763ed T-Deck Pro / Max: Normal, Large and Huge text sizes, as on the T-Deck (#639)
Enable CAP_UI_SIZE and the font-only text-size presets (montserrat
12/14/16, 16/18/20, 18/20/24) for HAS_TDECK_PRO boards, compile the
18/20/24 px UI fonts for them, and size the status bar to match.
Docs list the T-Deck Pro and Max under Text size.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-10 21:44:37 -04:00
Confituurke 15ca3f8902 feat(ui): pick your advert position on the map
Typing a latitude and longitude by hand is the only way to set a
position on a node without GPS, and few people know their coordinates to
six decimals. The map already knows where its centre is, so let it do
the work.

Settings > Profile gets a "Pick on the map" row under the lat/lon fields
in the Advert location card. It opens the Map tab centred on the current
position, with a crosshair pinned over the map centre and a Cancel /
Save position bar. Pan and zoom as usual, then "Save position" saves the
centre as the advert position. Leaving the tab cancels it, and so does
Back on the M9, the pager and a Bluetooth keyboard. Auto-follow pauses
while picking so it cannot pull the centre away.

With GPS on and a fix, the GPS sets the position on every loop, so a
picked one would not stay: the row is hidden then, and a fix that
arrives while picking is reported instead of saved. A centre panned past
the antimeridian is wrapped to -180..180 before it is saved.

A node without GPS usually has no map view yet either, so it starts from
the first contact that has a position; only with none at all does it ask
for a rough location first. A typed but unsaved lat/lon is saved before
the jump. The bar sits above the zoom slider, so zooming still works
while picking, and left of the right-edge map buttons, so it never
covers them on a short screen.

The four new strings are translated in every deploy/apps/lang/*.lang
file and i18n_builtin.h is regenerated, so the i18n audit stays clean
for them.

Signed-off-by: Confituurke <9595028+Confituurke@users.noreply.github.com>
2026-10-10 23:40:51 +02:00
Kaj SchittecatandClaude Opus 5.5 2dfe3727cd docs: beta_93 in the guide and the repo docs
Guide (wadamesh.com/docs.html): contact nicknames, the redesigned control
panel with the Battery saver tile, keyboard tooltips and the amber cursor,
automatic chat icons, the default lock wallpaper, the GPS serial speed and
battery notes, the V4 built-in apps and the Lua send budget, and a new
T-LoRa Pager section (hotkeys, navigation memory, Power off confirm, power
saving). Three new screenshots, GPS position and IP masked.

Repo docs: the Pager and M9 key guides describe tooltips, per-tab memory
and Power off, and README, TLORA_PAGER_SHORTCUTS and THINKNODE_M9_SHORTCUTS
no longer use em dashes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:38:01 +02:00
CyrioandClaude Fable 5.1 5a3c1be63d Pager: paste chord on Fn+Enter instead of Fn+V
Review follow-up (B0N3-GD): Fn is the Pager's only symbol key, so a
held-Fn letter chord takes that letter's symbol away -- Fn+V cost the
question mark with Fn held. Fn+Enter types nothing today (Enter has no
entry in the symbol map), so the chord moves there and costs nothing.

- PagerKeyboardState: V_POS -> ENTER_POS (row 1, col 9); the chord is
  still resolved by matrix position before the symbol map, only while
  Fn is physically held, and cleared by discardAlt().
- PagerKeyboard.h/.cpp, UITask.cpp: renamed to *AltEnterChord*; the
  paste path itself (txtPasteInto, hex-key extraction, toasts, drain
  sites) is unchanged.
- test_pager_keyboard_state: chord on Enter fires once and swallows the
  press; a plain Enter still returns '\r'; tap-Fn-then-Enter is not a
  chord and types nothing, as before; Fn held + V types '?' again.
- TLORA_PAGER_SHORTCUTS.md: both rows now say Fn held + Enter, and the
  em dash is gone from the prose.

Rebuilt and flashed on a Pager (RAM 37.8 %, Flash 90.0 %, unchanged).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKtRiAcddFBAUDogBWmZk4
2026-10-10 13:57:18 -07:00
Kaj SchittecatandClaude Opus 5.5 d68f276b06 touch: beta_93, contact nicknames, new control panel, tooltips, Pager shortcuts, speed and battery
Contact nicknames: TouchPrefsStore nick blob (48 x 38 B), display-only lookups
(contactShownName, threadShownName, senderShownName), Contact options >
Nickname on the shared text prompt (an empty OK clears it).
Control panel restyled in the launcher's tile language, with a Battery saver
tile; keyboard tooltips (navSetTip), an amber cursor and touch long-press
tooltips (the T-Deck touch read hid them on every poll).
T-LoRa Pager: M/C/A/S on Home, H/S tap and hold, Backspace = Back, N = jump to
new, held Enter = long press, per-tab focus memory, Power off confirm; LVGL
-O2 and IRAM, INT-gated keyboard, idle yield, status-bar setter guards, instant
tabs; PagerGps (u-blox software standby for rests, GPS rail cut when off),
panel sleep, amp off at boot, power-off parks the radio (NSS held), GPS, panel
and keyboard light.
Fixes: the DM duplicate check keys on the attempt and a path reset clears it,
the direct timeout masks the packed path byte, web remote hops (#636);
changelog over http (#638); Lua SDK send budgets and duplicate guard (#606);
GPS speed note (#613, CAP_GPS_BAUD_AUTO); emoji chat icon (#640); default
wallpaper (#626).
Heltec V4: Tetris, 2048 and Breakout unseeded and the built-in Lua stripped of
comments (identical bytecode), 27 KB freed; the baked language table is pinned
to beta_92's files (scripts/build/lang-pin-beta92) so it still fits.
Translations: 39 new keys in 14 languages, language store v24.
Site: theme, dark mode, aurora and guide refresh, SDK send limits, nicknames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
beta_93
2026-10-10 22:08:16 +02:00
Kaj c66f70f852 Merge PR #632 (jcyrio): translate the 18 beta_90/91 strings missing from every .lang
i18n: translate the 18 beta_90/91 strings missing from every .lang
2026-10-10 21:56:48 +02:00
Kaj 45c977ff11 Merge PR #633 (oumike): LR1110 old-firmware patch applies to RadioLib 7.8.1
build(m9): the LR1110 old-firmware patch applies to RadioLib 7.8.1
2026-10-10 21:46:19 +02:00
Michael A. CojocariandClaude Opus 5.5 9c0cccd2fb build(m9): the LR1110 old-firmware patch applies to RadioLib 7.8.1 too
lib_deps takes RadioLib ^7.6.0, and a fresh fetch now brings 7.8.1. Its
LR11x0::config() wraps driveDiosInSleepMode in its own skip for LR1110
firmware below 0x0306, so the call sits one level deeper and the patch
script no longer found it. It failed closed, stopping every M9 build at
its pre-script.

The script now knows both shapes. The patch still matters on 7.8.1:
firmware 0x0306 and 0x0307 get past RadioLib's own skip, send the
command, answer CMD_PERR and would abort radio init with -706.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016yt7fNCKmafm9LtRjyuUmS
2026-10-09 11:26:32 -04:00
CyrioandClaude Fable 5.1 9b891ff501 i18n: translate the 18 beta_90/91 strings missing from every .lang
scripts/build/i18n-audit.py reported the same 18 keys missing in all
14 language files -- the background picker (Background, Background
colour, Still/Moving aurora, Image, None, Choose an image, Choose the
colour, Set as background, the JPEG hints and the restart notice), the
GPS battery saver (Save battery, Check position every, the two
descriptions, "GPS: resting, next check in %lum%02lus") and the
"remote view open" touch-sleep block reason.

Each file gets the 18 rows in its alphabetical slot, translated rather
than left as English placeholders, reusing the terms the files already
use for the older wallpaper strings (Hintergrund, fond d'écran, sfondo,
achtergrond, háttérkép, pozadí, papel de parede/fundo, fundal, фон,
позадина, φόντο ...) and for the battery saver. "%lum%02lus" is kept
verbatim in every language. src/ui-touch/i18n_builtin.h regenerated
with scripts/build/gen-lang-builtin.py; the audit now passes for all
14 languages. "# ver: 23" left alone, since that is bumped at release.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKtRiAcddFBAUDogBWmZk4
2026-10-09 07:05:06 -07:00
CyrioandClaude Fable 5.1 2f811a7a6b i18n: add "Clipboard empty" to every .lang (Fn+V toast)
Review follow-up: the new TR("Clipboard empty") toast had no row in
deploy/apps/lang/*.lang, so i18n-audit.py flagged it in all 14
languages. Added in each file's alphabetical slot (after "Client
repeat") and regenerated src/ui-touch/i18n_builtin.h with
scripts/build/gen-lang-builtin.py. The audit no longer lists the key.
"# ver: 23" is left alone, since that is bumped at release.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKtRiAcddFBAUDogBWmZk4
2026-10-09 05:36:36 -07:00
Kaj SchittecatandClaude Opus 5.5 33ae4c61bd tanmatsu: drop the Wi-Fi OTA path so the app fits the launcher's load window
The launcher's AppFS bootloader maps only the first 50 x 64 KB of an app
while it checks and starts it (appfsBlMmap in badgeteam/appfs 2.1.0).
beta_91 (3,329,568 B) and the first beta_92 build (3,331,120 B) were past
it, so neither would start on a Tanmatsu.

On the Tanmatsu the launcher updates the app (CAP_OTA 0) and the only OTA
slots are the launcher's own 2 MB ones, so the core's "ota start" upload
page and URL install could never work there. DISABLE_WIFI_OTA stubs them
("ERR: OTA not supported in this build"), and with them go ElegantOTA,
the async web server and AsyncTCP: the app drops to 3,200,864 B, 75,936 B
under the window.

tanmatsu-appstore-publish.sh now refuses a binary over the window, and
its PR text no longer has an em dash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 12:40:02 +02:00