1450 Commits
Author SHA1 Message Date
Kaj SchittecatandClaude Opus 5.5 5833e00d25 touch: beta_97 release notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
beta_97
2026-10-17 21:18:07 +02:00
Kaj SchittecatandClaude Opus 5.5 18279edac9 release: the CrowPanel Advanced 10.1 (P4) ships in betas and the web flasher
- p4-release.sh builds and verifies the three revisions (V1.2, V1.1, V1.0)
  from crowpanel_p4_101/ in the same loop as the T-Display P4 images, with
  the same OTA-name and tag checks.
- Self-update is on (CAP_OTA 1): each revision updates from its own
  wadamesh-crowpanel-p4-101-v1x.bin, so a V1.0 never takes a V1.2 image.
- gen-flasher-meta writes a manifest per revision; wadamesh.com gets a
  CrowPanel Advanced 10.1 card with a V1.2 / V1.1 / V1.0 picker, and the
  standalone flasher one card per revision. Both point at the beta feed,
  so nothing shows until the next beta publishes the images.
- README, DEVICES.md and the site's board count (15).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:02:37 +02:00
Kaj Schittecat cff8bd4eea Merge crowpanel-p4-101: experimental Elecrow CrowPanel Advanced 10.1" ESP32-P4 port 2026-10-17 20:56:50 +02:00
Kaj SchittecatandClaude Opus 5.5 328434cbda touch: repeater status and telemetry requests go direct first (#683)
The Request button (and Ping) always reset the path, flooded a blank guest
LOGIN, and sent the STATUS/TELEMETRY REQ from inside the LOGIN-OK callback,
while the repeater's flooded login reply was still being repeated around us.
Bench against a repeater next to a T-Deck, 8 tries each: login-first got the
login answer 7 times but telemetry back only 2 times; a direct request like
the MeshCore app's got 8 of 8, about 1 s each (#683 reports under 5% from the
device, over 90% from the app on the same T-Deck).

Now the REQ goes out directly first on the stored path (flood when there is
none). Only when no reply comes within 6 s (12 s when it flooded) does the UI
fall back to the guest login, and after LOGIN-OK the REQ waits 2 s instead of
firing from the callback. Same bench: 7 of 8 answered (one through the
fallback, 17 s), and the login route alone went from 2 of 8 to 6 of 8. A reply
cancels the pending fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 20:54:39 +02:00
Kaj SchittecatandClaude Opus 5.5 e37258018a crowpanel_p4_101: experimental Elecrow CrowPanel Advanced 10.1" ESP32-P4 port
Standalone ESP-IDF target (crowpanel_p4_101/) modelled on tdisplay_p4/, sharing its
ESP-IDF, components and esp-hosted 2.12.3 backend. Untested on hardware.

- variants/crowpanel_p4_101: EK79007 MIPI-DSI 1024x600 display (Elecrow timings,
  LEDC backlight on GPIO31), GT911 touch on I2C0 45/46 (RST40/INT42), SX1262 on the
  J9/J11 header with a real DIO1 IRQ, LDO3/LDO4 bring-up, C6_EN reset callback on
  GPIO32, full-system-reset restart shim.
- Board revision is a build option: WADA_CP_REV=1.0|1.1|1.2 (default 1.2). V1.2 moves
  LoRa DIO1/NRST from GPIO53/54 to 27/28; V1.0 has the C6 SDIO data lines reversed
  (run 1-bit like Elecrow's V1.0 lesson). hostedSetPins() overrides Arduino's
  generic esp32p4 SDIO pin defaults, which only match V1.0.
- LVGL at native 1024x600 with the large-screen layouts; fixed landscape.
- Shared src/: one CAP_* block in device_caps.h plus HAS_CROWPANEL_P4_101 at the P4
  platform sites (storage law, SD_MMC, hosted BLE, no RTC_CNTL, no MQTT, fonts) and
  the CrowPanel no-unlock-control sites. navOpenChatPanel/navGoToMainTab get
  fallbacks for boards without CAP_KEYPAD_NAV.
- build.sh merge writes a 0x0 merged image per revision.

T-Display P4 still builds from the same tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 20:22:13 +02:00
Kaj SchittecatandClaude Opus 5.5 ed896b3404 touch: history never drops records at the segment cap; host test for the scheduler
fcb392a merged two neighbouring segments at the 24-file cap and, when no pair
fitted in one file, retired the oldest segment. A host simulation showed that
fallback does fire for heavy users (many quiet chats next to a few busy ones):
up to 626 old messages dropped over 60 reboots on 3 of 8 seeds. Now 24 is a
soft cap: at 24 pending compactions run first, then the best merge, and only
when no pair fits may a new segment open, up to a hard cap of 48. Below 41
files some adjacent pair of the 5000 ring records always fits, so the hard
cap never stops a save and nothing is dropped; files only pass 24 in that
heavy case, so older builds still read every file for almost everyone.

test/history_segments/run.sh lifts the scheduler out of UITask.cpp verbatim
and runs it against a simulated card: mixed, many-quiet, one-busy and
reboot-heavy workloads plus power cuts between a merged write and the
absorbed file's removal. 60k messages per run, every live record must
survive every reboot with no duplicates. beta_95's code loses ~48k of 60k in
the same run; this passes every mode (max 29 files).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 17:59:29 +02:00
Kaj SchittecatandClaude Opus 5.5 0351cf4410 apps: Store installs no longer leave a cut-off app behind
luaStoreDownloadWorker wrote each downloaded file to the card with one
f.write() straight from its PSRAM buffer, and an SD write from PSRAM can come
back short. Blackjack (48 KB, the first downloaded app past ~32 KB) landed cut
off near 32 KB: the install reported a network error, and the half .lua stayed
behind as an installed app that failed with "syntax error near <eof>"
(Discord). Files now go through the internal bounce-buffer writer into a .tmp,
are size-checked on the card and only then replace the real name, so a failed
install leaves nothing and a failed update keeps the old version.

wada.fs.write and the Home widget snapshot wrote from PSRAM the same way (Lua
strings live in the app's PSRAM heap); both go through a 2 KB internal buffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 17:32:41 +02:00
Kaj SchittecatandClaude Opus 5.5 94baf4deac touch: beta_96 - release notes, language store v27, Blackjack on the App Store page
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
beta_96
2026-10-17 15:22:25 +02:00
Kaj SchittecatandClaude Opus 5.5 d900bb83aa fonts: bidi and zero-width marks stay invisible with the '*' fallback
#679 ends every font chain in a '*' placeholder. LVGL itself only gives
<0x20, F8FF and 200C zero width, so LRM/RLM (common in Arabic and Hebrew
messages), ZWSP, ZWJ, word joiner, the embeddings, isolates and the BOM would
each have drawn a '*'. They now resolve to an empty glyph with no advance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:22:25 +02:00
Kaj Schittecat e43c06b09a Merge PR #681: Blackjack 1.0 in the Store 2026-10-17 15:17:16 +02:00
Kaj Schittecat 39cbbea6b7 Merge PR #679: one '*' placeholder for missing glyphs, hide skin tones (#673) 2026-10-17 15:17:16 +02:00
Kaj Schittecat 6a17f2a836 Merge PR #676: lock screen PIN, the keyboard's Sym/Alt layer stays live (#675) 2026-10-17 15:17:16 +02:00
Kaj Schittecat d89185367d Merge PR #630: Touch UI design calls (P4 one-row bar, chat clock, Device page, Bluetooth at setup)
# Conflicts:
#	src/ui-touch/UITask.cpp
2026-10-17 15:17:16 +02:00
Kaj Schittecat 1e72667b97 Merge PR #680: Web page Up/Down scroll the text on keypad boards (#677) 2026-10-17 15:16:56 +02:00
Kaj SchittecatandClaude Opus 5.5 aa5de751a5 touch: chats list ticks, M9 header layout code, contact popup titles, lock wallpaper veil
- #670: the chats list kept one tick after a DM was delivered. Its change
  signature never included the delivery state, so the rebuild was skipped;
  a delivery now bumps a generation it mixes in (and marks threads dirty).
- #672: on the M9 the keyboard layout code (EN, BG) sat on top of the GPS
  glyph in the chat header. It now has its own slot left of the clock, the
  GPS glyph moves left of it and the title leaves room for both.
- #668: with Large Text a long node name wrapped in the contact popup and its
  second line ran under the buttons. The title gets a fixed one- or two-line
  box (two when the name needs it) and the card uses most of a 320 px screen
  (up to 300 wide). The scroll check also counts the nickname line now.
- #652: a custom lock wallpaper was veiled with the theme background at
  150/255, milky on Day and cloudy on Night. It gets a lighter black veil and
  light text whatever the theme, like a phone lock screen.
- [HIST] boot line: segments and records loaded, for field reports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:15:24 +02:00
Kaj SchittecatandClaude Opus 5.5 9eda9b0f26 apps: Store lists up to 40 apps, canvases fit the big screens, button:bg
- The catalog parse stopped at 16 rows and the catalog has 16, so a 17th app
  (Blackjack, #681) was silently never listed; installed apps had the same
  cap. Both are 40 now, and the catalog buffer grows from 8 KB to 24 KB so
  the JSON is not cut off. PSRAM only.
- wada.ui.canvas raised a Lua error above 480 px, which killed apps that size
  a canvas from on_open(w, h) on the T-Display P4 (body ~575 tall), Tanmatsu
  and CrowPanel 5 (800 wide) (Discord). Sides are now clamped to the screen's
  long side instead.
- button:bg(fill [, border]) colours a button (or boxes a label), so apps no
  longer fake coloured buttons from panels that keys cannot focus (Discord).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:15:18 +02:00
Kaj SchittecatandClaude Opus 5.5 5198813f99 usb files: Lua apps can be dropped into the apps folder
/meshcomod/apps on the card and /apps internally now take top-level .lua and
.json files, so an app can be side-loaded without pulling the card (Discord).
Everything else there stays read-only: the folder itself, subfolders (<id>.d
data), app save files (.sav, .wgt), hidden names and 8.3 aliases. A change
from the page invalidates the cached app listing, so the drawer and the Store
pick the new app up the next time they open. Host tests cover the policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:54:47 +02:00
Kaj SchittecatandClaude Opus 5.5 fcb392afd0 touch: chat history kept saving at the 24-segment cap; open chats under a locked screen stay unread
History: at the segment table cap a new segment waits for the oldest to age
out of the RAM ring, but after a reboot the ring only holds what was loaded
(per-chat caps thin segments without emptying them), so nothing was ever
evicted and every new message stayed RAM-only until the next reboot lost it
(Discord, "messages are going away after Oct 13th"). segBuildJob now merges
the adjacent pair with the fewest live records into the older file (the
absorbed file is unlinked after the merged one lands; the loader's
monotonic-seq filter covers a crash in between), and retires the oldest
segment when no pair fits. A flush with records still pending no longer
reports "everything durable": it logs [HIST] flush stuck and retries.

Read state: refreshChatDetail marked the open chat read on every refresh, so
messages arriving under a dark or locked screen were cleared at once and the
lock screen's unread cards stayed empty (Discord). Only mark read while the
chat is really in view; wake, unlock and the glance closing re-run the check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:54:42 +02:00
Kaj SchittecatandClaude Opus 5.5 8daf59bdd7 doc: DOC_APPS_AUDIT capture tour for every Store app
Launches each catalog app (kAuditStore, generated by gen-radio-audit-apps.py
into the gitignored doc_radio_apps.h) and captures store_<id> for the
website's App Store page. Music gets two bench tracks and a play tap first.
Capture builds only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:54:31 +02:00
Kaj SchittecatandClaude Opus 5.5 2986354f3c site: Join the community (Discord) button next to Install
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 10:38:17 +02:00
Kaj SchittecatandClaude Opus 5.5 8109bbf43a site: App Store page listing every Store app, with the SDK and how to submit
apps.html is generated from deploy/apps/apps.json (the catalog the devices
read) plus the site-only write-ups in deploy/site/apps-info.json, by
scripts/build/gen-apps-page.py, which deploy-site.sh now runs on every
deploy. Linked from the home page (Apps button + resource card), the SDK
guide and the sitemap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:17:59 +02:00
halflive-743 bc32153c69 apps: add Blackjack 1.0 to the Store catalog 2026-10-16 22:06:13 -06:00
Michael A. CojocariandCopilot 7f29bccf76 docs: M9 Web page Up/Down reading (#677)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-16 21:02:59 -04:00
Michael A. CojocariandCopilot 3470c308d9 Web page: Up/Down scroll the text on keypad boards (#677)
Links were the page body's only focus targets, so spatial nav jumped from
a link to the next one however far down, or straight to the toolbar, and
the text in between could not be read on the M9 (or with a d-pad).

Up/Down on the Web page now move to the next link already on screen, else
scroll the body a page (handing focus to a link coming on screen when the
focused one scrolls off); only at the end of the page does focus leave for
the address row or toolbar. navMoveDir reports when the page took the press
so the M9 and Attaky "focus did not move" fallbacks don't scroll twice.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-16 20:23:34 -04:00
Michael A. CojocariandCopilot 77f6a04543 fix(ui): one '*' placeholder for missing glyphs, hide skin tones (#673)
Missing characters drew as '*' in labels that went through
copyUtf8ReplacingMissingGlyphs() and as LVGL's empty box everywhere else.
Every text chain (g_font_12/14/16 incl. the Tanmatsu accent slots, the
Pager map font, the glance body) now ends in a font that draws the base
Montserrat '*' for any codepoint nothing else has. It is flagged
is_placeholder, which LVGL still draws, so Constellation's name filter
keeps dropping undrawable characters.

Skin-tone modifiers U+1F3FB-1F3FF have no baked image; map them to the
invisible zero glyph (as U+FE0F is), so a toned emoji shows its base.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-16 19:52:47 -04:00
Michael A. CojocariandClaude Opus 5.5 9aa590f0c1 fix(touch): the keyboard's Sym/Alt layer stays live while a PIN is typed on the lock screen (#675)
Locked, the T-Deck loop switched the keyboard modifiers off, and the PIN
screen opens over the lock screen, still locked, so a PIN was typed with
Sym off. Sym+mic ('0') sent nothing, and Sym+W..O sent the letter under
the digit, which a PIN accepts, so the PIN silently came out wrong.
Setting the PIN in Settings worked because the device isn't locked there.

Now the modifiers stay on while the device is locked, lit and has a PIN
(the first key typed on the lock screen opens the PIN screen and counts).
The Pager-style keyboards (Pager, T-Deck Pro, Max) had the same rule for
a tapped Alt, cleared every tick while locked; the same exception
applies there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Us6CjkLFga9GkFJmmr3rrq
2026-10-15 14:55:28 -04:00
Michael A. CojocariandCopilot ea4c791270 i18n: regenerate the V4 table for the Device page strings
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:52 -04:00
Michael A. CojocariandCopilot 896c8e7030 Settings: the group is 'Display & lock', so 'Hardware' only names the Device page's card
docs.html follows: the group's name, Theme under it, and Run setup again
and Reboot on the Device page rather than General.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:25 -04:00
Michael A. CojocariandCopilot b9ff27de8c site: Settings > About is now Settings > Device
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:25 -04:00
Michael A. CojocariandCopilot e83c483a0f i18n: rows for the Settings > Device and keyboard protocol strings
Hardware, the setup wizard Bluetooth hint, Radio:/Keyboard: and the four
keyboard protocol states in all 14 languages, taken from #631 so they
ship with the code that uses them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:25 -04:00
Michael A. CojocariandCopilot a913b1331e Settings: one 'Device' page; keyboard protocol switch on Keyboard page
The settings group that held Display/Theme/Lock is now 'Hardware', so
'Device' only names the page that was About. Run setup again and Reboot
move from General to an untitled card on that page. The older keyboard
protocol switch is also on the Keyboard page instead of a note pointing
elsewhere.

Refs #416

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:14 -04:00
Michael A. CojocariandCopilot ec5e08038b P4 Bluetooth: the status-bar glyph shows when Bluetooth runs; setup applies only a flipped switch
- The round one-row bar hid the Bluetooth glyph outright, but the esp-hosted
  P4 build does run Bluetooth on the C6. The glyph now follows
  hasBleCapability() && isBleEnabled() as on every other board (so never on
  the ESP-AT build), with a slot in statusBarPackRound between Wi-Fi and GPS.
- The one-row repack signature includes the Bluetooth and GPS glyphs, so
  either appearing re-packs the row.
- Setup's Bluetooth switch shows Bluetooth as it is when step 3 opens, and
  Finish applies it only if the user flipped it. A switch left alone no
  longer tries to start a Bluetooth that could not start at boot, which
  showed the P4 its 'not enough memory' alert on first boot (#612).
- tdisplay_p4/main/main.cpp: drop the stale 'keep BLE gated OFF' comment.

Refs #416

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:14 -04:00
Michael A. CojocariandClaude Opus 5.5 6f2783c8c9 P4 landscape Settings: two real columns, Device row full width
The wide landing wrapped groups two to a row, so each row was as tall as
its taller group: Device (one row) sat beside Mesh with a gap under it,
Connections beside the Device group, and System alone at the bottom.

In two-column mode the untitled group holding the Device row now spans
both columns at the top, and the remaining groups stack in two column
containers, split in order at the point that makes the taller column
shortest. Value-slot width is tracked per row since the spanning row is
wider.

Unchanged.
(from 7d6875a)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XERzMfBu6rw4behJzs9Hmw
2026-10-15 14:15:14 -04:00
Michael A. CojocariandCopilot 43c80a1b0f fix(touch): chat header keeps the clock and battery at the bar's normal height
The taller chat bar centred them on its full height, so opening a chat
dropped them below where they sit on every other screen. The round P4 packs
them on the one-row bar's line; the double-bar boards lift them by half the
extra height (the Pager's bar does not grow, so it is unchanged).

Unchanged.
(from 5f9f5ee)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:14 -04:00
Michael A. CojocariandCopilot d4a8a09310 P4: one-row status bar
The round-cornered T-Display P4 drops its two-row bar for one row: the
title on the left, then the clock beside the icons on the right (battery,
signal, Wi-Fi, GPS, the DND moon), every glyph's ink on one bottom line.
No Bluetooth glyph (wadamesh does not drive the P4's Bluetooth) and no
battery %. The stacked chat header only shows while a chat is open.

Split out of 4844a9b (Touch UI follow-ups 4) and rebased onto beta_92,
whose GPS glyph joins the packed row.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-15 14:15:14 -04:00
Michael A. CojocariandClaude Opus 5.5 3e8bf7c51d fix(touch): first-boot setup keeps Bluetooth on and shows a switch for it (#416)
Since beb85bd a fresh install forced Bluetooth off and persisted it when
the setup wizard opened, and nothing on screen said so: the device was
invisible to the MeshCore app until the user found the control-center
toggle. A format + clean install hits exactly that path, which fits the
T-Deck Plus report (stock MeshCore, always advertising, paired fine).

Setup no longer forces Bluetooth off; it stays as it booted (on by
default, as with stock MeshCore). Step 3 "Wi-Fi & Bluetooth" gets a
Bluetooth switch, on for a first boot and showing the live state on
"Run setup again". Finish applies only a change, via the same
enableBle()/disableBle() path as the control center, and shows the usual
failure text if the heap guard refuses a cold start. Skip leaves
Bluetooth on.

The step's paragraph is shorter, so the switch row still fits above the
buttons on 240 px-tall panels. The new string is translated in all 14
languages; i18n_builtin.h regenerated.

(cherry picked from commit 700355a23c465faa2df3b2ec5d46f06dbb8d7873)

Translations are in the i18n PR.
(from 3e2b8b5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zE15egJdCZ9nRBZmg1YUq
2026-10-15 14:15:14 -04:00
Michael A. CojocariandClaude Opus 5.5 b4c6c20900 feat(tanmatsu): report the LoRa chip, so Device names a radio on every build (#596)
Every PlatformIO touch build and both T-Display P4 radio builds define
RADIO_CLASS, which the Device page already reads. The Tanmatsu has none:
its SX1262/SX1268 sits behind the ESP32-C6 and is reached through
TanmatsuLoraRadio. That bridge now asks the coprocessor once at init
(lora_get_status, before RX polling starts) and exposes chipName(), and
deviceRadioName() uses it, falling back to "SX126x" if the C6 did not
answer.

(cherry picked from commit 94056e7eb7baf136d0f17ffa04e7e48cbe9ac712)

Unchanged.
(from 53c1cd9)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zE15egJdCZ9nRBZmg1YUq
2026-10-15 14:15:14 -04:00
Michael A. CojocariandClaude Opus 5.5 07c92b2af8 feat(touch): Device shows the radio; info pages scroll by keypad, close with X (#596)
- The Device page lists the radio this build drives ("Radio: SX1262"),
  from RADIO_CLASS with the "Custom" prefix dropped. The Device card's
  second line shows it too on boards without the T-Deck keyboard, which
  is what tells the T-LoRa Pager's SX1262 and LR1121 builds apart.
- System Information and Memory detail close with a compact X instead
  of a "Close" button.
- Their text now scrolls from the keyboard: the X is the only focus
  stop, so Up/Down and the Pager's wheel found nothing to move to and
  the text was unreachable off-touch. A shared navInfoModalScroll()
  scrolls the body instead, from navMoveDir (trackball / d-pad / arrow
  keys) and the Pager encoder; the M9's own special case now uses it.
  Focus stays on the X at either edge.

"Radio:" translated in all 14 languages; i18n_builtin.h regenerated.

(cherry picked from commit 4b99579b4e58aa78d165204502c14263559c563e)

Translations are in the i18n PR.
(from e56c6ea)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zE15egJdCZ9nRBZmg1YUq
2026-10-15 14:15:14 -04:00
Michael A. CojocariandClaude Opus 5.5 671213771b feat(touch): Device section at the top of Settings, About merged in (#596)
Settings opens with a Device card that names the hardware on a second
line ("LilyGo T-Deck · newer keyboard"), so a wrongly detected or set
variant is visible before anyone opens a page. It replaces About, which
moves from the bottom of the list; its content is unchanged and now sits
under a new hardware block:

- Model, and on the T-Deck the keyboard the protocol probe settled on,
  or "set manually" when the override is on (new
  tdeckKeyboardDetectedMode() getter).
- The T-Deck "Older keyboard protocol" switch, moved here from the
  Keyboard page, which keeps a one-line pointer to it. Flipping it
  updates the card and the page in place.

The update-available dot moves to the Device card, and the "Diagnostics
are on the About page" hint now points at Device.

New strings are translated in all 14 languages; the moved switch's label
and note were English-only in 12 and are now translated too. The old
About rows stay for firmware that still asks for them. i18n_builtin.h
regenerated. The site docs now say Settings > Device.

Not included: a T-Deck Pro touchscreen override (V1.0 and V1.1 are
separate builds, so it cannot change at runtime; the card shows which
build is installed) and an inaccurate-RTC flag (new clock behaviour,
better as its own ticket).

Fixes #596

(cherry picked from commit 726905ea607dea496f5e74e90e7b13068552007e)

Rebased onto beta_92's card-based Settings: the hardware readout and the switch are a Hardware card on the Device page. Its translations are in the i18n PR.
(from ddcff4e)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zE15egJdCZ9nRBZmg1YUq
2026-10-15 14:15:14 -04:00
Kaj SchittecatandClaude Opus 5.5 b85eef6fec touch: beta_95, MeshCore 1.18 via meshcomod v1.18.0.1
About (Build) and the boot log name the meshcomod release the core is:
"on meshcomod v1.18.0.1". release.sh reads it from the pinned core's own
examples/companion_radio/MyMesh.h, keeps the in-tree defaults in step and checks
every staged image carries it. Language store v26 (this build's new texts),
release notes for beta_95.

Bench (T-Deck, 1.18): device and self info, 404-contact sync, the companion CLI
(ver, board, get name/radio/tx/freq, unknown command), 4 packets received and a
zero-hop advert sent in 90 s, correct device time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
beta_95
2026-10-15 18:07:34 +02:00
Kaj SchittecatandClaude Opus 5.5 ef0b27f1e0 core: MeshCore 1.18 (core-v1.18.0 = meshcomod 8aba438f), V4 language table deflated
Pins move from core-v1.17.4 to core-v1.18.0, cut from the main meshcomod
companion-v1.18.0.1 was released from. The companion changes are ported from
meshcomod's rebase into wadamesh's own MyMesh:

- onCLICommandRecv: a contact's remote CLI command runs when the user granted
  that contact remote CLI, and lands in the chat as a CLI message otherwise.
- CMD_RUN_CLI_COMMAND (66) / RESP_CODE_CLI_REPLY (29) and the local companion CLI
  (name, pin, Wi-Fi, radio, af/dutycycle, rxgain, tx, rxdelay, path.hash.mode,
  multi.acks, board, ver), also reachable from the serial CLI. Settings without a
  prefs field answer "unsupported". NodePrefs layout unchanged.
- TXT_TYPE_CLI_COMMAND is accepted for sending; sendCommandData (and our queue-
  preserving wrapper) carry the text type.
- Channel data is delivered to the app (onChannelDataRecv), unsolicited responses
  (pushed telemetry) reach it as PUSH_CODE_BINARY_RESPONSE, and raw-data sends
  decode multi-byte-hash paths.

Clock: 1.18 seeds an unsynced ESP32 clock at 1 Mar 2026, so ClockFloorRTC's
MIN_VALID_EPOCH follows it (a set equal to the seed must stay invalid).
Pager LR1121: the AGC reset re-applies the boosted-gain setting (new core arg).
IDF builds exclude the new CommonRadioPrefs.cpp (needs <target.h>/radio_driver).

The 2 MB Heltec V4 went to 100.0% with the CLI. Its built-in language table is now
one raw-deflated blob per language (895 KB -> 312 KB), inflated into PSRAM by the
S3 ROM on first use (~10 ms, ~75 KB for the active language): 91.7% flash. Checked
on a T-Deck forced onto the table (nl, hu, el) and by the post-link key check.

Builds: all 15 S3 touch envs, Tanmatsu (3,237,024 B), T-Display P4 SX1262 + LR2021.
T-Deck boots and runs on 1.18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 17:50:32 +02:00
Kaj SchittecatandClaude Opus 5.5 d3a9cf1453 touch: radio tools redesign, Music app, Store update badge, triage fixes
Spectrum: stat tiles (peak, floor, our channel, busy), plot and waterfall drawn
at screen size (the lv_chart and zoomed waterfall were the page's render cost),
dark-to-yellow waterfall, peak hold, our-channel marker, Band/Channel and
Live/1 min/10 min chips. RF Monitor 1.4 (tiles, filled chart, typed feed, packet
detail card; the old type table did not match MeshCore payload types) and
Airtime 1.6 (big figure, tiles, duty line, rx/tx split).

Lua SDK: ui.panel, bold labels and a size-24 figure font, colors.warn/border,
app.on_audio (fires with the screen off), read-only wada.sd.list and sd: audio on
the SD_MMC boards (P4, Tanmatsu, Wio L2), caps panel/audio_events/epaper, a
"music" icon and an "audio" Store requirement. button:set() no longer writes
label fields into the button object (heap corruption, every earlier firmware).
The SDK page's input table described events the firmware never sent.

Music 1.0 (Store app): plays MP3/WAV from the card's Music folder, shuffle,
repeat, keeps going through the list with the screen off. Verified on the
T-Display P4 end to end.

Store: the update check also fetches the app catalog and badges the Store tile
with the number of installed apps that have a newer version. Baked Lua apps are
raw-deflated and inflated by the S3 ROM (14.6 KB back on the V4); the V4 language
table keeps only texts of apps it can run.

Fixes: the SD-card notice no longer fires when the card mounts fine (#667); the
Control Center clock keeps time while open (#666); M9 keyboard brightness (#664);
the battery widget's number no longer sits on a ring too small for it (Discord);
M9 shortcuts doc follows #669's composer order. New texts in all 14 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 17:07:11 +02:00
Kaj Schittecat 3b0af92044 Merge pull request #665 from Ender436: T-Deck Max audio (chimes, custom sounds and Lua audio through the ES8311) 2026-10-15 15:28:35 +02:00
Kaj Schittecat 833fac8943 Merge pull request #669 from oumike: the composer puts the text box next to Quick Reply, Emoji (and the M9's #) beside Send 2026-10-15 15:17:45 +02:00
Michael A. CojocariandClaude Opus 5.5 d3202fe7fe feat(touch): the composer puts the text box next to Quick Reply, with Emoji (and the M9's #) beside Send
Non-touch M9: Quick Reply | text | Emoji | # | Send. Touch boards: Quick
Reply | text | Emoji | Send. Emoji and # align off Send's slot so they
follow the text box's new width on a rotation; the P4's landscape row
matches. The M9's arrow keys walk the new order: RIGHT from the end of
the text goes to Emoji, then #, then Send; LEFT walks back # → Emoji →
text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Us6CjkLFga9GkFJmmr3rrq
2026-10-15 09:06:21 -04:00
Ender436 3166e4a654 t-deck max audio fix
Notification chimes, custom WAV notification sounds and Lua wada.audio
playback through the ES8311 codec + NS4150B amp, mirroring LilyGo's
examples/ES8311/playWAV bring-up. I2S DOUT is GPIO40, not the header
name's 17 (measured in GlomarGadaffi/tdeck-max-phone#34); the XL9555
amp enable (line 6) is bracketed around playback and the shared-speaker
mux (line 10) held to the ES8311. Reuses the pager's Es8311Codec driver
and enables CAP_SOUND/CAP_SOUND_FILES/CAP_AUDIO_STREAM for the Max.

Signed-off-by: Ender436 <68835715+Ender436@users.noreply.github.com>
2026-10-14 11:37:08 -06:00
Kaj SchittecatandClaude Opus 5.5 75ec6759dd test: the M9 keyboard test follows #628's one-read-per-poll driver and checks its 70 ms repeat filter
#662's test queued three keys and read them all after one poll; #628 (for #625,
keys typing twice) reads one key per poll and drops the same key again within
70 ms. The test now polls per key and also checks that a repeat inside 70 ms is
dropped and one after it is a new press. Host tests: 18 pass, 2 skips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
beta_94
2026-10-14 10:34:12 +02:00
Kaj SchittecatandClaude Opus 5.5 179577ef10 beta_94 notes: CrowPanel 5.0, hashtag links, #628's fixes, the Radio widget line
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:33:33 +02:00
Kaj SchittecatandClaude Opus 5.5 0692775ba5 Merge follow-ups: the confirm X stays on touch boards (#628), link bubbles skip a full-screen layout (#580)
#628 dropped the close X from actions-only confirms on every CAP_KEYPAD_NAV board,
which includes the V4, the T-Deck and the touch-only boards that take a Bluetooth
keyboard. Now only a board without touch drops it; touch boards keep main's X,
skipped by keypad focus.

#580's chatCreateLinkLabel called lv_obj_update_layout on the message label to read
its height, laying out the whole screen for every link bubble as it scrolled in.
The caller already measured the wrapped text; it passes that height in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:17:57 +02:00
Kaj Schittecat 507511fab6 Merge PR #628 (oumike): Touch UI follow-ups 5a: quick fixes (#603, #605, #614, #617, #620, #625, #627, M9, Tanmatsu, Wio)
# Conflicts:
#	src/ui-touch/UITask.cpp
2026-10-14 10:17:19 +02:00