Conflict in web/CMakeLists.txt: main's WADA_HOST_BOARD=m9 flavour and the
WADA_SIM_PAGER option both kept, one after the other.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cmake -DWADA_HOST_BOARD=m9 compiles the M9's key path (HAS_M9_KEYBOARD: the
d-pad, the function keys, the Back ladder, the chat message walk) into the
host app on the web board, so M9 navigation runs headless with
--size 320x240 instead of only on a device. The rest stays the web board
(its caps, no SD). platform/WebM9Keyboard.cpp feeds the host keys in as the
controller's bytes.
Scripts: `key NAME [COUNT]` takes a raw byte (`key 0x81` = MSG) and a count
(several keys queued before one render, as on a busy device). The demo
backend takes WADA_DEMO_CHATTER_MS / WADA_DEMO_CHATTER_BURST so messages
arrive at known times.
UITask gates that named the board where they meant its keyboard now name
HAS_M9_KEYBOARD (keyboard backlight level, map pan, nav always on), the nav
globals and CAP_KEYPAD_NAV also take the host flavour, the M9 loop's
lock-screen service sits behind CAP_LOCK_SCREEN and the CardKB drain steps
aside for the M9 keys. Unchanged on every device build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The host build laid out as the Pager: 480x222, no touch, keyboard and rotary
encoder as the only input, with the UI's own TLORA_PAGER branches compiled in,
so the Pager's screens can be reviewed and scripted without flashing.
- web/sim_pager/: keyboard/encoder bridge, stubs for the codec, I2S, haptics,
IMU, charger and gauge, README and a tour script. Environment switches fake
the hardware states: WADA_SIM_CHARGING, WADA_SIM_CHARGE_HOT,
WADA_SIM_CARE_HOLD, WADA_SIM_SOC (+ _DROP), WADA_SIM_USE_MA,
WADA_SIM_FACEDOWN, WADA_SIM_PICKUP, WADA_SIM_BAG.
- Script commands for the Pager: holdkey (accent picker; holdkey space to
lock; holdkey shift / fn for the modifier shortcuts).
- device_caps.h: a WADA_SIM_PAGER caps block. Off by default; the normal web
and host builds are unchanged.
- Host fixes it needed: INT_MAX include for glibc, SD.begin(ss, SPIClass&) in
the SD shim, panelSleep() on WebDisplay.
- Host SPIFFS lists a directory the way SPIFFS does: every file, with its
folder in the name ("/lock/a.jpg"). The host keeps such files in real
folders, and readdir() handed the folder back as an entry, which the file
manager showed as a 0 B file (/lock, /msgs). Affects the host builds only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josh <8422439+MrYoshii@users.noreply.github.com>
Work in progress, handed to the web-mobile branch:
- the canvas size is the board's resolution, picked at boot from the window
(WebDisplay runtime size, host --size WxH); a phone held upright gets a
480-wide portrait canvas on the large-screen portrait layouts; turning
the phone restarts the UI in the other layout (data kept)
- the phone's own keyboard: a hidden textarea opened inside the tap's
gesture, its edits forwarded as UTF-8 text + Backspace/Enter through the
CardKB path (cardKbUiKey passes BLE_KEY_TEXT through); CAP_NATIVE_KEYBOARD
keeps the UI's own keys down; the screen slides above the keyboard
- viewport/safe-area/overscroll, web app manifest, More menu (Reset too),
bar stays on one row, chooser notes for iOS and the http/https copies,
a mixed-content ws:// failure explains the http copy
- web/scripts/mobile-tour.mjs (iPhone 14, Pixel 7)
Known open: the mobile tour's UTF-8 storage check fails (the bubble shows
the text; the stored history does not match the needle; on desktop,
Playwright's insertText of a non-ASCII char sends no keydown and is lost).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Location: the web board has CAP_GPS 1. web/platform/WebLocation.* is its
SensorManager + LocationProvider, fed by navigator.geolocation (page shell,
only while the UI's GPS is on, the prompt deferred to a tap) or WADA_GPS on
the host, so the GPS switch, status, map centring, distances and
wada.sys.gps (with speed/course) work unchanged. The position reaches a
connected node (CMD_SET_ADVERT_LATLON, displaced by the Location privacy
radius) only while the node's advert-location setting is "share"; the demo
moves its cast to the visitor's location.
Map tiles: wadaHttpRequest serves the firmware's default tile server only:
a synchronous emscripten_fetch from the tile_fetch pthread to the
same-origin tiles/ path (serve.py proxies it; nginx location for the site),
plain HTTP natively. WiFi reports connected while the browser is online.
Fixes the static-init order of the host VFS (the UI's own tiles LittleFS
copied an empty impl).
Polish: Lua apps that need the board's own radio carry "radio": "own" in the
catalog (baked under CAP_RADIO_TOOLS, greyed in the Store); mouse wheel and
trackpad scrolling; Settings > Wi-Fi / Bluetooth explain the page bar
(CAP_WIFI_SETUP / CAP_BT_SETUP); no Download mode (CAP_USB_FLASH); no
receiver settings on Settings > GPS (CAP_GPS_RECEIVER).
Tests: webtest checks the map centres on Playwright's Ghent location and
shows tiles; nodetest checks the location privacy rule against the mock node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backend selection moves into the shared boot: a WadaBackendChoice
(web/mesh/BackendSelect.h) that host_main.cpp fills from --serial / --tcp /
--read-only and web_main.cpp from the page (Module.wadaBackend, with its own
data dir), and board.cpp creates the backend from it. The demo position is
only set for the demo. The companion link reports its state through
g_wada_link_hook (web_main.cpp passes it to Module.wadaLink). The browser
transports' JS joins the Emscripten link as --pre-js. WEB_BUILD.md keeps both
phases' sections. build.sh: "$0" relative to the caller's directory no longer
breaks smoke / serve / webtest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
board.cpp owns the board globals and src/main.cpp's setup()/loop() order;
host_main.cpp keeps only the SDL window, event pump and scripted tour, so the
browser front end reuses the boot unchanged. WebDisplay tracks the changed
rectangle for the canvas upload.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CompanionBackend speaks the companion frame protocol (stock MeshCore 1.17/1.18,
wadamesh extras handled) over a CompanionTransport: USB serial and TCP natively
(--serial / --tcp), Web Serial, Web Bluetooth and WebSocket in the browser (JS
glue in web/mesh/js, framing in C++). The stand-in gains the node-only events
(self info, raw RX, login, CLI, regions, contact removal) and computes the RX
log, advert routes, repeats heard and message route info from the node's raw
RX pushes, as the device does. Demo stays the default.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
web/build.sh shots runs the phase-1 tour headless on a fresh data dir
(onboarding, Home, Chats, a conversation, send, Contacts, Settings,
Device, Apps, the Snake Lua app) and writes web/docs/*.png; smoke runs
the same tour for an exit status only.
device_caps.h gains CAP_RADIO_TOOLS and CAP_SCREEN_MIRROR (default 1,
so every board keeps its tiles) and lets a board block preset
CAP_WEB_BROWSER; the web board turns all three off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The touch UI (src/ui-touch, unmodified apart from WADA_WEB board guards)
builds for macOS with CMake and runs in an SDL2 window: a compat layer
for the Arduino/ESP-IDF/FreeRTOS surface, a MyMesh stand-in with a
MeshBackend interface (DemoBackend now), and the web board's SDL
display/touch/keyboard drivers. WEB_BUILD.md follows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>