Commit Graph
4122 Commits
Author SHA1 Message Date
JakubandClaude Opus 5.5 708fde7225 feat(ui-lvgl): WiFi icon in the status bar
Shown while WiFi is switched on (Settings > WiFi), bright when connected
(live tiles, map download, update), dim otherwise. The switch is read
from NVS once and cached. The status icon signature buffer grew so
changes to the last icons aren't missed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 23:16:47 +02:00
JakubandClaude Opus 5.5 eb201bc4fd feat(ui-lvgl): favourites as a Home card, left of the main page
The six slots with unread badges on a card of their own (swiped to,
no clock), redrawn when messages arrive; the Favourites tile and screen
are gone, showFavourites() opens the card. The page dots sit at the
bottom on every card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 23:10:50 +02:00
JakubandClaude Opus 5.5 fe92ac1153 feat(ui-lvgl): tap-to-wake switch, the side button no longer wakes
Settings > Display & power > WAKE > Tap to wake (NVS, on by default):
off, only the top WAKE button turns the screen on. The side USER button
doesn't wake the screen any more (a press in a pocket); held, it still
mutes / unmutes with the screen off. Roadmap: buttons corrected (WAKE is
the top one), USER to open the main menu page later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 23:06:46 +02:00
JakubandClaude Opus 5.5 44fea2fa6a feat(ui-lvgl): splash text in the MeshCore wordmark's lettering
"solo", our version, upstream's and the build date (as digits) are drawn
in the wordmark's letters, the missing ones (l, v, d, digits, '.', '-')
made to match; a line with any other character falls back to Noto.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:58:53 +02:00
JakubandClaude Opus 5.5 c7c150da58 fix(ui-lvgl): map download popup fits the screen
A progress bar and one line of counts while downloading (the zoom row
hides, it can't change then), failures on one line, the source as
"opentopomap.org", only the WiFi network's name (set up in Settings >
WiFi). The debug line (IP, RSSI, heap) is gone. Roadmap: mentions
highlight added, four items ticked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:54:13 +02:00
JakubandClaude Opus 5.5 6f141a62f2 feat(ui-lvgl): even status icons, relay count badge, clearer path popup, edge scrollbars
- Status bar icons come from ui_icons_14: FontAwesome refitted to one
  size by fonts/status_icons.py (falls back to ui_font_12 for the
  battery level text), the charging bolt in a tight cell.
- Own channel posts show the repeater count as a small badge, as L1,
  instead of a check and a number.
- Message path popup: a stronger connector, roles on the right
  (sender / hop N / you), our post's repeaters fanned out under us,
  long paths scroll.
- Scrollbars everywhere are thin and hug the edge, clear of the content.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:47:23 +02:00
JakubandClaude Opus 5.5 7a34f68369 feat(ui-lvgl): live map tiles kept apart, under a size limit
Tiles fetched while browsing online go to /sdcard/maps-live with an
index of arrival order; past the limit (Settings > Storage, 16 MB-1 GB,
default 64 MB) the oldest are deleted a few per loop. Storage shows
their count and size and can delete them all. Downloaded maps are never
touched. Roadmap: live tiles done, second batch of user items added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:25:02 +02:00
JakubandClaude Opus 5.5 f849ee0b00 fix(wio-tracker-l2): USB power detection works - charge bolt, Power row, GPS hint
- The AW35615 USB-C controller (FUSB302-style registers, ID 0x91) only
  reports VBUSOK with its measure block on; POWER resets to bandgap only,
  so isExternalPowered() was always false. Board init turns it on
- Status bar shows a charge bolt on the cable, Diagnostics > Live has a
  Power row, the GPS screen notes that charging disturbs GPS, and the
  low-battery warning is skipped on USB as intended
- Roadmap: USB detection closed; GPS indoors still worse than the L1
  even on battery, left open for later

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:12:05 +02:00
JakubandClaude Opus 5.5 70921cd865 feat(ui-lvgl): GPS screen - sky plot, signal per satellite, fix details
- Home > GPS and Settings > System > GPS details: satellites on a sky plot
  (filled = used in the fix, colour = C/N0), a bar per satellite with its
  dB-Hz, fix state with time to first fix, DOPs, position, altitude, speed,
  UTC and per-constellation counts; a Turn on button while GPS is off
- helpers/sensors/GpsSky.h parses GSV / GSA / GGA / RMC from any talker,
  fed from MicroNMEALocationProvider behind -D GPS_SKYVIEW (L2 and the
  sim only; L1 unchanged); the sim feeds it made-up NMEA
- Roadmap: GPS indoors diagnosed with it - on the USB cable the L76K
  tracks satellites but never decodes navigation data; on battery it
  gets UTC within seconds and a fix

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 21:50:48 +02:00
JakubandClaude Opus 5.5 690df304d7 fix(ui-lvgl): no watchdog reset during tile downloads, map download rides out a busy server
- Tile fetch and OTA tasks run at idle priority: HTTPClient's read loop
  only yields with delay(0), which at priority 1 starved IDLE0 until the
  task watchdog reset the device (decoded from the core dump)
- A failed tile is retried once; failures in a row pause 5 s ... 60 s on
  the same tile, and the download gives up only after ~5 min of nothing
- The source's last zoom level (OpenTopoMap 17, else 19, or line 3 of
  source.txt) caps the download range and live tiles; past it the map
  magnifies the parent tile
- OpenTopoMap's "no tile" picture is never saved, and copies saved by
  earlier builds are dropped when read
- The placeholder check only runs on a fresh area and for pictures with
  content: plain sea / empty land tiles are genuinely identical

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:46:36 +02:00
JakubandClaude Opus 5.5 277c0cddf1 feat(ui-lvgl): roadmap stage 3 - message history on SD, Storage screen, saved trails
- Message history archived per conversation on the SD card (HIST_ARCHIVE):
  restored on boot, Older/Newer paging in threads, kept count selectable
- Settings > System > Storage: card and flash usage, breakdown by maps,
  messages, trails and other, kept-per-chat setting, delete history;
  reads the mounted volume and warns when the FAT partition is much
  smaller than the card
- Saved trails on the card: every Save is a new file, Load opens a list
  with load (framed on the map), GPX export and delete
- Diagnostics: GPS data rows, last start reason, last crash summary
- Messages restored before the clock is set show their date instead of 0s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:17:08 +02:00
JakubandClaude Opus 5.5 4f5357031f feat(l2): Arduino 3.x as the published env, limits sized for the PSRAM, stage 7 findings
- Wio_Tracker_L2_companion_solo_lvgl now builds on Arduino-ESP32 3.3.12
  (pioarduino); the 2.0.17 build stays as _solo_lvgl_arduino2 (not published)
- Per-board limits (defaults unchanged, L1 byte-for-byte the same):
  TRAIL_CAPACITY, WAYPOINT_CAPACITY, HIST_CH_MAX / HIST_DM_MAX, NEARBY_MAX;
  the L2 sets 4096 / 64 / 256 / 128 / 64 (in PSRAM with UiCore; internal
  heap 154 KB free after). ui-lvgl: 32 trail segments, contact list 256,
  rooms 32, 50 bubbles per conversation, pickers 128, WiFi scan 20
- Map trail drawing drops points under 2 px apart
- "Nearby" is "Nodes"; advert options "Zero hop" / "Flood"
- Roadmap stage 7: LVGL on other displays -- e-ink stays ui-new, an OLED
  spike after this roadmap, Cardputer as a colour candidate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:51:08 +02:00
JakubandClaude Opus 5.5 b99ca6b4ce fix(ui-lvgl): unlock fades away on release, channel names shown as named
- Unlocking fades the lock screen out while the screen underneath drifts
  into place; the slider unlocks on letting go at the end and springs back
  when let go earlier
- Channel names no longer get a "# " prefix (thread title, channel popup,
  live share targets) -- "#" marks a hashtag channel; favourite contacts in
  the live share list are starred instead

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:18:43 +02:00
JakubandClaude Opus 5.5 3fd204489e feat(ui-lvgl): roadmap stage 6 - light motion, unified style, accent picker, splash
- Anim.h: screens emerge from the middle (background cover fades, content
  drifts 6 px), Home pages slide, popups and toasts rise and fade in
- Theme.h: accent rules (fill = primary action, dim fill = selected, text =
  names/counts/modes), theme layer over the default theme, radius tokens,
  accent colour picker (Settings > Display & power > LOOK, NVS mc_ui)
- Splash with the Solo and upstream versions
- Status icons in equal cells, L1-style relay marks, path window with a hop
  diagram, tile download popup fits the screen (WiFi only in Settings)
- Perf: uncompressed fonts, two 120-line PSRAM buffers (~48 -> ~33 ms per
  transition frame); UI_PERF_TEST harness

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 13:06:22 +02:00
JakubandClaude Opus 5.5 5124587b26 feat(ui-lvgl): roadmap stage 5 - screen PIN, live map tiles, OTA from GitHub releases
- Screen PIN (Settings > Display & power > Security): 4-8 digits in NVS,
  keypad on the lock card after every wake and on boot, 5 misses -> 30 s pause
- Live map tiles: missing tiles at the current zoom are fetched over the saved
  WiFi, written to the card and drawn; WiFi drops 30 s after leaving the map;
  "Live tiles" switch in Map tools
- Firmware update (Settings > System): checks the fork's latest release,
  streams the -ota.bin into the spare app slot over TLS verified with the
  Arduino 3.x CA bundle, checks image magic/chip id, restarts
- Release workflow publishes *_solo_lvgl envs (merged image + -ota.bin)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:52:53 +02:00
JakubandClaude Opus 5.5 9e50470a51 fix(wio-tracker-l2): keep the last good battery reading when the ADC read fails
A failed ADS1115 read returned 0 mV, so the status bar showed 0 % (and the
low-battery shutdown could see an empty battery) until a reboot. Retry once,
then keep the last good value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:14:58 +02:00
JakubandClaude Opus 5.5 087bac89b4 feat(ui-lvgl): roadmap stage 4 - tools grouped by context, Settings in L1 order, full status icons
- Map tools hold trail, live share and arrival alert, with their options
  (schema page "Map options") behind one button; back returns to the map
- Nearby gets an advert button: send now (nearby / everyone) + auto-advert
- Home page 3: Repeater, Admin (list of repeaters and room servers),
  Diagnostics
- Settings: display, sound, radio (Bluetooth, WiFi), system, keyboard,
  contacts & messages; units moved to Display & power
- Status bar: Bluetooth, GPS, alarm, mute, then auto-advert, trail, live
  share, repeater, arrival alert in the accent colour
- Fonts: key and route glyphs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:14:58 +02:00
JakubandClaude Opus 5.5 331a4e64c4 feat(l2): Arduino-ESP32 3.3.12 / IDF 5.5 env, NimBLE and new I2S driver ports, large UI buffers in PSRAM
- New env Wio_Tracker_L2_companion_solo_lvgl_v3 on pioarduino 55.03.312-1;
  the 2.0.17 env stays until the new one passes the hardware checklist
- SerialBLEInterface: NimBLE variant (PIN pairing through encrypted,
  authenticated characteristic properties; setAccessPermissions is a no-op)
- buzzer: i2s_std driver on IDF 5 (legacy driver kept for 2.0.17)
- ESPNOWRadio: IDF 5 callback signatures
- ui-lvgl: psramBuf() for trail drawing, tile cache, map marks, list rows,
  keyboard maps and message metadata; internal heap back to 2.0.17 level

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:14:58 +02:00
JakubandClaude Opus 5.5 ba4d01aa77 feat(ui-lvgl): roadmap stage 1 - keyboard close key, all bot placeholders, WAKE/USER button roles with hold-to-mute, WiFi switch, shorter descriptions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 01:23:54 +02:00
JakubandClaude Opus 5.5 f790631e03 refactor(ui-new,ui-lvgl): L1 sound mode and battery display through the Core, consistent admin toasts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 01:00:31 +02:00
JakubandClaude Opus 5.5 f502d2c619 refactor(ui-lvgl,ui-new): shared segmented and text field widgets, favourites through contactctl, one age formatter
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 00:55:36 +02:00
JakubandClaude Opus 5.5 d588193d0d feat(ui-core,ui-lvgl): message placeholders and quick messages in the Core, L2 quick messages, advert, Bluetooth toggle, read all, node waypoint/pin
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 00:46:34 +02:00
JakubandClaude Opus 5.5 938dfefba6 feat(ui-core,ui-lvgl): sound in the Core, L2 speaker via ES8311, Sound settings, melody editor
- genericBuzzer I2S path (BUZZER_I2S): an audio task synthesises the notes
  with eased edges and keeps the DMA queue fed with silence between sounds;
  ES8311 setup; amp powered through the board only around sounds
- ui-core/SoundControl.h (mode, volume, built-in sounds, melody model),
  SoundNotifier moved to the Core, chanctl::melody, schema Sound page
- L2: notifications, alarm / timer ring, locator sounds, Settings > Sound,
  melody editor with the playing note lit, per-chat sound, mute icon
- noteIndex() on every buzzer backend; scrolling popups past screen height

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 00:27:52 +02:00
JakubandClaude Opus 5.5 2624ab0548 feat(ui-core,ui-lvgl): repeater control in the Core, L2 repeater mode
Min SNR now defaults to off on a fresh device (was 0 dB without a prefs file).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:33:11 +02:00
JakubandClaude Opus 5.5 6f5fc07cd0 feat(ui-core,ui-lvgl): user presets and battery level in the Core, L2 my presets, scopes, battery display, clock seconds
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:21:38 +02:00
JakubandClaude Opus 5.5 63db1e2e07 feat(ui-core,ui-lvgl): diagnostics rows in the Core, L2 diagnostics, auto-advert setting, compass
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:01:42 +02:00
JakubandClaude Opus 5.5 8663d50412 feat(ui-core,ui-lvgl): favourites pinning in the Core, L2 node name, reboot, lock screen, favourites dial, 12-hour clock
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:51:00 +02:00
JakubandClaude Opus 5.5 6d82da877e feat(ui-core,ui-lvgl): room sessions and contact helpers in the Core, L2 rooms, conversation options, message actions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:27:32 +02:00
JakubandClaude Opus 5.5 1c8206a510 feat(ui-core,ui-lvgl): bot settings table in the Core, L2 bot screen
BotConfig (tabs, rows, the NodePrefs field behind each, reply placeholders)
moves into ui-core; ui-new's Tools > Bot renders it. L2: Home > Bot with
switches, list pickers, text popups with placeholder buttons, quiet hours.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:09:02 +02:00
JakubandClaude Opus 5.5 e2399b5e0d feat(ui-core,ui-lvgl): remote admin session in the Core, L2 admin screen
AdminSession (login with saved password, CLI round trips, timeouts, field
table, typed values) moves into ui-core; UiCore offers login answers and
CLI replies to it first. ui-new's Tools > Admin becomes a view over it.
L2: node detail > Admin with tabs and per-field popups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:59:00 +02:00
JakubandClaude Opus 5.5 79fd5a50fb feat(ui-core,ui-lvgl): channel management in the Core, L2 channel screens
ChannelControl (add Public/Hashtag/Private, rename, delete, notif/fav/scope)
and Favourites slots move into ui-core; ui-new uses them. Contact / channel
pref cleanup moves from ui-new's UITask into UiCore so it runs on every
frontend (L2 had none). L2: channel options popup (hold a row or the gear
in a channel) and the Add / Edit channel form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:42:44 +02:00
JakubandClaude Opus 5.5 84d8a4df2a feat(ui-lvgl): navigation map, clock tools, settings pages, radio
- Home > Map is the navigation map: waypoints (list, add at GPS / by
  coordinates / long-press spot), live shares, trail recording + tools
  (save, load, GPX export, track back), live share controls, target bar
  with ETA; the nodes map opens from Nearby.
- Map: smooth panning (no decode during a drag, idle read-ahead, cached
  coarser stand-ins), overzoom limited to 2 levels, resumable downloads,
  map credit behind a "©" and in Settings > About; target ring and trail
  computed in double.
- Home in swipeable pages; Clock (alarm, timer, stopwatch, ring card).
- Settings rendered from the Core schema (display & power with a
  brightness slider, messages & contacts, trail / live share / alerts),
  GPS switch, Radio screen; low-battery shutdown.
- WioTrackerL2Display: honour the 0-4 brightness level.
- docs: L2 hardware checklist, ui-core notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:20:42 +02:00
JakubandClaude Opus 5.5 1cc6a61747 feat(ui-core): waypoints, navigation helpers, settings schema, radio control
Shared by ui-new (L1) and ui-lvgl (L2) so both firmwares have the same core
features:
- WaypointModel (/waypoints, UTF-8-safe labels, [WAY] share text),
  EtaTracker, GpsAverager, TrackBack; TrailEngine save/load/reset actions;
  UiCore::setGpsEnabled / applyGpsInterval.
- Locator target kind 2: a channel live share followed by sender name
  (LiveTrackStore::activeByName).
- SettingsSchema: pages (navigation, display & power, messages & contacts),
  value tables over 1/2/4-byte NodePrefs fields, side effects via UiCore.
- RadioControl: apply params / TX power / APC and the preset list; ui-new's
  Settings > Radio now goes through it.
- NodePrefs::display_brightness_pct (sentinel 0xC0DE002F, size unchanged)
  for frontends with a brightness slider.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 19:20:42 +02:00
JakubandClaude Opus 5.5 0fa7966280 feat(ui-lvgl): on-device map download over WiFi
The map's download button fetches the visible area (overview levels up to
a chosen zoom) into /sdcard/maps from OpenTopoMap or maps/source.txt,
skipping tiles already on the card and rejecting placeholder answers.
Settings > WiFi stores the network in NVS (with scan); WiFi is on only
while a download runs. HTTP runs on a worker task on core 0; the popup
shows link, internal heap and the last TLS/HTTP error.

Internal RAM was the blocker (~13 KB free with WiFi + Bluedroid): the L2
LVGL env now allocates the_mesh in PSRAM (MESH_IN_PSRAM, static RAM
210 -> 87 KB) and mbedTLS allocates from PSRAM. Confirmed on hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 11:26:44 +02:00
JakubandClaude Opus 5.5 64321bf12b feat(ui-lvgl): offline raster map from the microSD
Map screen (Home > Map): Web-Mercator tiles from /maps/{z}/{x}/{y}.png on
the card (Meshtastic MUI layout; per-column TPK1 .pak also read), drag to
pan, +/- zoom, re-centre/follow GPS, Nearby nodes with a position as
markers opening node detail. Tiles decode one per loop pass into a
12-slot RGB565 cache in PSRAM. map/TileProvider.h is the swap point for a
later vector renderer: the screen only calls renderTile(). The tile set's
credit line comes from maps/attribution.txt.

L2 mounts the card over SDMMC 1-bit (CLK 2, CMD 3, D0 1). LVGL's lodepng
is enabled; note its LVGL patch returns an lv_draw_buf_t*, not pixels.
LVGL pool 2 MB for PNG decoding. Fonts gain map / users icons.

tools/maps/fetch_tiles.py prepares a card for an area (presets for
Poland), requires an explicit tile URL (tile.openstreetmap.org blocks
offline use) and stops on placeholder images. The LVGL sim preloads
web/maps into the L2's /sdcard and puts its GPS on Kraków.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 10:57:46 +02:00
JakubandClaude Opus 5.5 3e5ccd28c7 feat(ui-lvgl): Nearby screen, node detail, scan popup; NearbyModel in the Core
ui-core/NearbyModel.h builds the Nearby list (contacts + live [LOC] shares
+ heard adverts, or discover-scan results) with type filter and sort,
moved verbatim out of ui-new's NearbyScreen, which now inherits it.

ui-lvgl: Home is three tiles (Messages, Nearby, Settings). Nearby lists
known nodes with filter chips and a Dist/Recent toggle; tapping a row opens
node detail (distance/bearing, position, last heard, ID) with Message,
Ping, favourite, Add and two-tap Delete. Scan is a popup over the list
with its own model: nodes in range now, not the known set. Fonts gain the
FontAwesome star for favourites. The LVGL sim page adds an optional
repeater so Scan has something to find.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 00:53:23 +02:00
JakubandClaude Opus 5.5 87fad71af3 feat(ui-lvgl): 320x240 browser simulator, compose field fixes
Simulator: SIM_UI=lvgl variants/sim/build_wasm.sh builds ui-lvgl for the
browser. SimLcdDisplay blits LVGL's RGB565 flush to a 320x240 canvas and
LvglPort.h's sim branch feeds the mouse in as touch; LVGL comes from the
L2 env's libdeps, its objects cached in web/build/obj_lvgl/. web/lvgl.html
runs it beside a ui-new peer on a direct link, with a window.sim API for
headless checks. New hooks: sim_lcd_touch, sim_lcd_button,
sim_test_send_channel_msg.

Compose: the theme's padding left less than one line in the field, so it
scrolled vertically and text jumped; pad it to fit exactly one line. The
cursor is drawn only while FOCUSED, now set while the keyboard is up.
With the keyboard up the screen header hides so the conversation keeps a
message in view; the accent popup stays inside the keyboard, clear of the
field; channel bubbles put the age next to the sender (one line shorter);
the thread scrollbar shows only while scrolling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 00:36:26 +02:00
JakubandClaude Opus 5.5 bf1e6fcaa0 feat(ui-lvgl): European fonts and phone-style keyboard
Fonts: Noto Sans generated with lv_font_conv (ui-lvgl/fonts/generate.sh,
OFL) replaces ASCII-only Montserrat: European Latin (Latin-1, Extended-A/B),
Greek, Cyrillic + supplement, typographic punctuation, currency, LVGL
symbols + globe; 12/14/16/20 px, clock 40 px digits only (RLE, so
LV_USE_FONT_COMPRESSED is on).

Keyboard (ui-lvgl/Keyboard.h): one layout per script (Latin QWERTY,
Cyrillic, Greek) picked by the same keyboard_main/alt_alphabet prefs as
ui-new, globe key to switch, hold a key for its variants in a popup above
it, one-shot shift, symbols page; compose limit counted in UTF-8 bytes.
First Settings screen (Keyboard: Main / Additional).

Long-press variants and UTF-8 case mapping move to ui-core/KeyboardData.h
and are shared with ui-new, whose Hold-Enter accents gain Romanian,
Turkish, Hungarian, Baltic and Icelandic letters (and ș/ț, Ukrainian /
Serbian letters now capitalise).

Verified on L2 hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 00:08:15 +02:00
JakubandClaude Opus 5.5 cd926b7e45 feat(ui-lvgl): LVGL 9 skeleton frontend for Wio Tracker L2
New examples/companion_radio/ui-lvgl/ over the shared UI Core (env
Wio_Tracker_L2_companion_solo_lvgl, LVGL 9.2.2, pool in PSRAM):
status bar, home (clock, unread), conversation list (channels + recent
DMs with unread badges), contact picker, conversation view with bubbles,
delivery / relay markers and on-screen keyboard, toasts for Core events,
display auto-off with wake on touch / button. Board glue (LovyanGFX
flush + GT911 touch) isolated in LvglPort.h; design tokens in Theme.h.

UiCore gains the first frontend actions, sendDirectText() and
sendChannelText(), and drives DM auto-resend + unread reconcile from its
own loop (removed from ui-new's loop). MessageHistory exposes newest-first
DM ring iteration and a public contactByPrefix().

Verified on L2 hardware: navigation, send/receive, sleep/wake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:49:42 +02:00
JakubandClaude Opus 5.5 74db0d69a5 refactor(ui-core): UiCore becomes MyMesh's Listener for ui-new
ui-new hands MyMesh the UI Core (UITaskBase::meshListener()). The Core
applies the display filter, labels room posts, files history, keeps DM /
channel / room unread and the queue count, and reports incoming messages
and adverts as MessageArrived / AdvertHeard events. UITask now derives
UITaskBase + UiCoreHost: it answers "is this conversation on screen" and
keeps the selection after an insert, forwards not-yet-extracted parts
(room login / admin, bot device actions, removal cleanup, shutdown), and
turns events into alert / wake / sound, drained at the start and end of
its loop(). Mesh callbacks no longer touch the display or buzzer.

AbstractUITask is split into UITaskBase (lifecycle, link state, helpers)
and the Listener glue ui-orig / ui-tiny keep using unchanged. Screenshot
handler reaches ui_task directly instead of casting the Listener.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:28:58 +02:00
JakubandClaude Opus 5.5 124265b8be refactor(ui-core): move GPS trail sampling into TrailEngine
TrailStore, background sampling, auto-pause and the pre-shutdown
auto-save move from UITask to ui-core/TrailEngine.h. TrailScreen still
drives the store directly. The 512-point store now lives on the heap
with the rest of UiCore (static RAM -8 KB on Wio L1, same total).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:17:03 +02:00
JakubandClaude Opus 5.5 9e5ce72c86 refactor(ui-core): move locator into LocatorEngine
Active target (set/clear/resolve person position), geofence crossing
state machine and proximity beeper move from UITask to
ui-core/LocatorEngine.h, emitting LocatorCrossed / LocatorBeep events.
UiEvent gains a flag and a 24-byte text. tickCore() now runs at the end
of UITask::loop(), where the moved engines used to run, so a fresh GPS
wake re-seeds the locator before it evaluates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:15:18 +02:00
JakubandClaude Opus 5.5 74baaddd0c refactor(ui-core): move live location sharing into LiveShareEngine
Auto-[LOC] session (duration, movement/heartbeat gate, scoped send) and
the peers' LiveTrackStore + expiry move from UITask to
ui-core/LiveShareEngine.h. "Live share ended" becomes a
UiEventType::LiveShareEnded event; UITask keeps thin wrappers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:09:26 +02:00
JakubandClaude Opus 5.5 79a3a47ff1 refactor(ui-core): move position + course over ground into CourseEngine
COG ring sampling (every ~1 s from UiCore::loop), outlier rejection and
currentCourse/currentLocation move from UITask to
ui-core/CourseEngine.h. UITask keeps one-line wrappers; screens unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:07:32 +02:00
JakubandClaude Opus 5.5 311a3484e2 refactor(ui-core): move ping state into PingEngine
Single in-flight ping + last result move from UITask to
ui-core/PingEngine.h; MyMesh's ping callback routes to the engine
instead of casting the Listener back to UITask. UITask keeps thin
wrappers (and the "not supported" alert), NearbyScreen is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:05:39 +02:00
JakubandClaude Opus 5.5 dd826a447e refactor(ui-core): move clock tools into ClockEngine; add Core event queue
Alarm / countdown / ring logic moves from UITask to ui-core/ClockEngine.h
unchanged. New ui-core/UiEvents.h: fixed-size Core -> frontend event
queue; UITask::tickCore() runs UiCore::loop() and reacts to ClockAlert /
ClockRingEnded (wake, alert overlay, melody). ClockToolsScreen API unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:03:57 +02:00
JakubandClaude Opus 5.5 3b7aa28ff9 refactor(ui-core): add UI Core skeleton; move MessageHistory + DM unread into it
New examples/companion_radio/ui-core/ (header-only for now, reached from
ui-new/UITask.cpp by relative include, so no platformio.ini changes):
UiCore facade, MessageHistory (moved verbatim), DmUnreadTable (extracted
from UITask). UITask heap-allocates the Core in begin(); MessagesScreen
binds to core().history. Behaviour unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:00:46 +02:00
JakubandClaude Opus 5.5 2a8d4598d4 refactor: port upstream MyMesh::Listener; MyMesh no longer calls the UI directly
Ports upstream's "Abstract UI overhaul" (PR #3431 + follow-ups) with
identical names/signatures. MyMesh talks to the UI only through
MyMesh::Listener (setListener()); a second block holds Solo extensions
(own-send mirroring, relay echoes, room login/admin replies, [LOC] shares,
contact/channel removal, bot device actions, requestShutdown), all no-op
by default.

AbstractUITask becomes the Listener and carries the glue MyMesh used to
run for the UI (display filter, room-post labels, notifications,
connection polling). BLE PIN randomisation moves to main.cpp as upstream.
Also fixes ui-orig's stale advertReceived event on buzzer boards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:54:40 +02:00
JakubandClaude Opus 5.5 f768e73f9f docs: UI Core + frontends design (draft)
Shared hardware-independent UI Core (engines, models, declarative
settings schema) behind MyMesh's AbstractUITask, with ui-lvgl (rich,
Wio Tracker L2 first) and ui-new (lite, OLED/e-ink/nRF52) as frontends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:22:37 +02:00
JakubandClaude Opus 5.5 221c33ec5f feat(wio-tracker-l2): board layer + ui-new bring-up env
Seeed Wio Tracker L2 (ESP32-S3R8 16MB/8MB PSRAM, SX1262, NV3031B 320x240
QSPI LCD + GT911 touch + LP5814 backlight, TCA9535 expander gating every
rail, ADS1115 battery ADC, AW35615 USB-C, L76K GNSS).

Board layer ported from meshcore-dev/MeshCore PR #3381 (Hacuchino-hash),
kept at the same paths for an easy upstream merge. Differences:
- display: dropped the UIColor theme (not adopted in this fork)
- GpsTap diagnostics wrapper omitted; GNSS reads Serial1 directly
- nv3031b ODR fix dropped: LovyanGFX >= 1.2.30 (now pinned) defines
  Panel_NV3031B::init_cmds itself -- the fix became a duplicate symbol
- MESH_DEBUG_PRINTLN with a non-literal format fixed (broke MESH_DEBUG builds)
- upload_speed 115200: baud is virtual on native USB; skips the switch

solo/wio-tracker-l2 adds Wio_Tracker_L2_companion_solo_bringup: ui-new
zoomed 2x, BOOT button only, no touch -- a hardware smoke test, not a
release target (deliberately not *_solo_dual, so CI doesn't publish it).
The real UI for this board will be a new LVGL frontend.

Verified on hardware: boot, display, radio, GPS, battery, BLE app link.
First boot takes tens of seconds while SPIFFS formats its 3.4 MB partition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:53:18 +02:00