Commit Graph
1673 Commits
Author SHA1 Message Date
JakubandClaude Opus 5.5 9e24abcbeb feat(ui-new): a cursor mode that keeps the keyboard in view
The cursor marks the character it stands before instead of pushing the
text apart: underlined while typing, an inverted block while moving it.
The grid stays on screen with the special row turned into the key hints;
Up/Down move a word, Hold-Enter deletes before the cursor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:41:40 +02:00
JakubandClaude Opus 5.5 e09a90b325 fix: messages that arrive while asleep or locked stay unread
A conversation left open under the lock screen or a dark display no longer
counts as read: the counters and the lock screen's tally go up, and on
waking (L2: on unlocking) the conversation reopens on its first unread
under the "New" line, a typed draft kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:41:40 +02:00
JakubandClaude Opus 5.5 92e379e05c fix(ui-new): one '#' on a hashtag channel's favourite tile and slot list
Hashtag channel names already start with '#'; the tiles added another
("##test"). chanctl::bareName() is now the one place that strips it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:41:40 +02:00
JakubandClaude Opus 5.5 9ef7d5d981 fix: no flash writes while typing, and a clock that survives a power loss
Contacts and paths are saved a while after the change and never while the
user is active, so a send no longer stutters on the 53 KB contact rewrite
(a path that came back unchanged isn't written at all). The clock is saved
every 30 minutes and restored no earlier than the firmware's build day.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:41:32 +02:00
JakubandClaude Opus 5.5 aaf35351d7 feat: open a conversation on its first unread message, under a "New" line
Both UIs: a channel, DM or room with unread messages opens on the oldest of
them (MessageHistory::firstUnreadChannel / firstUnreadDm, own messages not
counted), a "New" line above it, so it reads down to the newest. Nothing
unread: the newest, as before.

L1: the first unread is selected and scrolled up top with the line in view;
the channel's unread count now counts down as you read towards the newest.
L2: the page holding it, scrolled to the line; an incoming message scrolls
down only when the list is already at its end. Sim hooks: sim_unread (L1),
sim_open("unread") (L2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 22:20:04 +02:00
JakubandClaude Opus 5.5 38925dde65 fix(l2): a dot per DM send, lists that notice every change, the LED lit only on TX
- A pending DM shows a dot per send, as on the L1. The thread is read from
  the SD archive, which a resend never updated: it does now, and the
  thread's signature and patch state count the attempt.
- Nearby redraws when a node goes live, changes type or the units change;
  the scan popup when a name or the remote SNR arrives.
- The user LED is active high: it was lit all the time and went dark
  while transmitting.
- Sim hooks "dm" and "send" for testing a DM thread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 14:32:54 +02:00
JakubandClaude Opus 5.5 8324d0c6d1 feat(ui-new): message alert setting -- banner, corner envelope or none
Display > Message alert: Normal keeps the sliding banner; Compact shows an
envelope with the unread count beside the battery (in the header line where
there's no status row), blinking for 2 s; Off shows nothing. The blink only
ever brings the next frame earlier, so it no longer holds back the UI's
animations while it runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 14:32:54 +02:00
JakubandClaude Opus 5.5 6c9186dc54 feat: a message's bytes left, counted as it will be sent, on every screen
The limit is what the send leaves of MAX_TEXT_LEN: a channel post carries
"<node name>: ", a direct message resent more than three times keeps two
bytes spare, and placeholders count as they expand (msgtext::limit/sentLen).
Bytes, not characters. The path and packet header sit outside the payload;
static_asserts keep a full message within the radio frame on the longest path.

From 40 bytes left the count shows: on the L2 as a tag on the field's top
edge, on OLED/e-ink at the right of the preview's last line with the text
wrapped short of it. Input stops at the limit; a send still over (a
placeholder grew) is held. Sim hooks to open a compose with text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:58:01 +02:00
JakubandClaude Sonnet 5.5 f396882768 fix(ui-new): the screen redraws when USB power comes or goes
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 21:49:59 +02:00
JakubandClaude Sonnet 5.5 6e13ad59ae feat(ui-new): a bolt beside the battery while USB power is connected
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 18:39:58 +02:00
JakubandClaude Sonnet 5.5 643dc09615 feat(ui-new): alerts as a banner sliding down from the top, a message's for 2 s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:35:45 +02:00
JakubandClaude Sonnet 5.5 ca6c2021d8 feat: the loading mark is three dots mid-screen, whatever the rotation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 22:47:26 +02:00
JakubandClaude Sonnet 5.5 39d29383ac feat(ui-new): the boot splash grows with the panel, as the clock does
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 22:47:26 +02:00
JakubandClaude Sonnet 5.5 cf086678aa fix(ui-lvgl): the USB drive offer waits for the lock screen to go, PIN or not
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 22:47:26 +02:00
JakubandClaude Opus 5.5 b63af9fee1 fix(ui-lvgl): GPS signal chart spans the box from the first bar
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:25:27 +02:00
JakubandClaude Opus 5.5 2a9f900fff fix(ui-new): a Settings change is saved on the way to a screen opened from it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:52:20 +02:00
JakubandClaude Opus 5.5 0460249579 feat(ui-new): Home's panels list "All ..." first, shortcuts after
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:52:20 +02:00
JakubandClaude Opus 5.5 7c568d6153 fix: a leftover /prefs folder (Meshtastic) no longer blocks every settings save
Our /prefs file can't be read from a folder of that name, and the rename
that commits each save can't replace one, so on a device moved over from
Meshtastic without erasing the flash no setting survived a restart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:52:20 +02:00
JakubandClaude Opus 5.5 608c5b7dad fix(ui-new): on/off written On / Off everywhere, as every other value
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:12:27 +02:00
JakubandClaude Opus 5.5 c4217d8632 feat: a channel's scope can follow the default -- Default is the new start value
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:09:22 +02:00
JakubandClaude Opus 5.5 5a92d36509 fix: Bluetooth switched off stays off over a reboot or hibernate
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:09:22 +02:00
JakubandClaude Opus 5.5 50d0d5577b fix(ui-new): a tool opened from Home's Tools page goes back to Home
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:09:22 +02:00
JakubandClaude Opus 5.5 1af8ce1a85 fix(ui-new): on/off as the words ON / OFF -- the pill switch read as a battery
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 14:09:22 +02:00
JakubandClaude Opus 5.5 3326881dc1 feat(eink): screens laid out for the 4.2" -- tiles, Nodes pane, charts, Sky, nav, clock tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:44:11 +02:00
JakubandClaude Opus 5.5 cea102c152 feat(eink): 9px icon set, 5x10 hop digits and roomier bubbles on the 4.2"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:44:11 +02:00
JakubandClaude Opus 5.5 44ccd47a12 feat(ui-lvgl): GPS on three tabs -- Sky, Signal, Details
Each tab a screenful: the sky plot beside the fix; the bars with a fixed
dB-Hz scale and the constellations; and Details with whatever else the
receiver reports (correction, locator, course, DOPs with their rating,
signal averages, NMEA counts). Sim: sim_open("gps").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:22:44 +02:00
JakubandClaude Opus 5.5 ab767e7ae1 feat(ui-lvgl): charts with a value axis, grid and a finger's readout
Chart.h draws Diagnostics > History, the noise sweep and the trail's height
profile: round values up the left, labels along the bottom, a solid fill
(no transparency) and, under a finger, the sample's value and when / where.
Sim: sim_open("histdemo") / ("profdemo") fill them with made-up data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:22:44 +02:00
JakubandClaude Opus 5.5 1f2cb301e6 feat(ui-lvgl): the big clock in the splash's lettering, as on L1
Home and the lock screen draw HH:MM in ui-core/Lettering.h's block digits,
the seconds smaller on the same baseline, leaning smoothly per screen row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 10:22:43 +02:00
JakubandClaude Opus 5.5 1b7402a33e style(ui-lvgl): selected / on in the full accent, no ACCENT_DIM
ACCENT_DIM (the accent mixed toward black) came out brown on selected
tabs, chips, segments and own bubbles. They take the accent with dark
text now, as primary actions and the quick panel tiles do:
styleSelected() sets the fill, the pressed shade and every label under
it. Own bubbles: dark text, age and delivery mark (green or red can't be
read on amber); the melody editor's selected note is outlined, the
sounding one filled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 09:35:46 +02:00
JakubandClaude Opus 5.5 a5956d79ae fix(ui-lvgl): quick panel over a frozen screen; slider not taken by Home's swipe
- Quick panel: the screen under it is frozen and dimmed in one snapshot
  (freeze::early), so the slide redraws an image and the panel; a tap or
  swipe up under it closes it and nothing under it takes a touch. Tiles are
  two pages of four with dots; tiles restyle only when their state changes.
- Home: a touch that starts on the top layer (the quick panel, the status
  bar) is not a page swipe -- a sideways drag of the brightness slider over
  Home ended the drag and turned the page under it.
- Keyboard: OK and hide don't put the cursor back on a field whose keyboard
  is gone.
- BotScreen: adminRowBox -> centerRow (the sim build broke in 3293ac09).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 09:17:32 +02:00
Claude bac4c12467 refactor(ui-lvgl): text-measure counters go with the perf tools
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBrxKyHHxWsmttVkUdBrj
2026-10-05 07:28:15 +00:00
Claude 2ea0ac4416 refactor(ui-lvgl): the perf tools move out of UITask.cpp into PerfTest.h
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBrxKyHHxWsmttVkUdBrj
2026-10-05 07:27:54 +00:00
Claude 8df1abd79b refactor(ui-lvgl): quick-message editor uses navTextEntry (bare mode)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBrxKyHHxWsmttVkUdBrj
2026-10-05 07:26:39 +00:00
Claude 3293ac09e3 refactor(ui-lvgl): centerRow and pillButton helpers; document the shared text-entry popup and bubble row
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBrxKyHHxWsmttVkUdBrj
2026-10-05 07:24:44 +00:00
Claude 84fd5013b5 refactor: shared text-entry popup (ui-lvgl) and chat bubble row (ui-new); GPS search clock keeps a found fix
- ui-lvgl: navTextEntry()/TextEntry replace eight copies of popup + field +
  keyboard wiring; one byte-capped insert callback instead of two.
- ui-new: drawHeadedBubble()/BubbleMark replace the duplicated DM and channel
  bubble drawing in MessagesScreen.
- GpsSky::halt(): stopping the receiver ends an unfinished search but keeps
  the first-fix time; keyboard cursor blink restarts after a key.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBrxKyHHxWsmttVkUdBrj
2026-10-05 07:23:56 +00:00
Claude 997da95ecf fix: GPS search clock stops with the receiver; L2 cursor survives accented keys; lighter, scrolling quick panel
- GPS: stop() resets the sky state so the 'Searching' timer does not run
  while the receiver is off; the status page shows it only when GPS is on.
- L2 keyboard: put the FOCUSED state back after typing a key or picking a
  variant, so the cursor is drawn again after characters like a-ogonek.
- Quick panel: drop the full-screen dim (a blend per frame), so the screen
  below stays interactive; tiles are one sideways-scrolling, snapping row;
  the brightness slider no longer animates and only updates the backlight
  when the value changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBrxKyHHxWsmttVkUdBrj
2026-10-05 07:15:32 +00:00
JakubandClaude Opus 5.5 b5e4845dae feat(ui-lvgl): quick panel from the status bar; L2 fixes from rc1
The quick panel, as a phone's: pulled down from the status bar (or a tap
on it). Bluetooth, WiFi, GPS, sound, trail and live share switch at a
tap; Advert opens the advert popup (moved here from the Nodes header);
Lock locks the screen; a brightness slider. Holding a tile opens its
settings. Lock and sun glyphs added to the fonts.

Fixes from rc1 testing on the L2:
- GPS status icon: none when GPS is off (the module kept its last fix
  valid, so it stayed green); grey on, green with a fix. ensureGps()
  turns GPS on before trusting that stale fix.
- Screen wake: the panel wakes dark, a frame is drawn, then the
  backlight fades in -- no white flash. Off fades out first.
- Power off / flat battery: the chip wakes every 30 s to look for USB
  power and starts when plugged in (it slept with no wake source before,
  until the reset button). Plugged in when switched off: stays off until
  re-plugged.
- Message ages in a conversation refresh every 2 s, as on ui-new; the
  message popup keeps its age, repeaters heard and delivery up to date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:10:06 +02:00
JakubandClaude Opus 5.5 d66f04ba94 fix(ui-lvgl): OTA sees a release as newer than its release candidates
versionNum() read "v2.0-rc1" as plain 2.0, so a device on a release
candidate never offered the release itself (nor a later candidate). A
"-rcN" suffix now orders before the bare version: v2.0-rc1 < v2.0-rc2 <
v2.0 < v2.0.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:26:06 +02:00
JakubandClaude Opus 5.5 c3782cb8e5 feat(prefs): v2.0 settings file -- the struct as it is, behind a CRC
/prefs holds a header (magic, format version, size, CRC-32), the node's
position and NodePrefs as it is in memory, in place of /new_prefs' two
hand-kept field lists and 0xC0DE00xx schema bumps. A new field goes at the
end of the struct; moving one bumps PREFS_VERSION. sanitize() keeps every
value in range.

The first boot after an update from before 2.0 imports only the first
block of the old file, laid out the same in upstream MeshCore and Solo
(name, position, radio, BLE PIN, scope), then deletes it; everything else
starts from the defaults. Contacts, channels, scopes, waypoints and trails
are untouched.

Gone: the page-order and GPS-interval migrations, the unused
trail_interval_idx / trail_units_idx / repeat_extra_scopes; fav_sort_off
and msg_wake_screen_off become fav_sort and msg_wake (on by default).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:12:18 +02:00
JakubandClaude Opus 5.5 9597e1e2a4 feat(ui-lvgl): e-ink graphics in colour on the L2
Node detail: a card with a compass rose and the hop chain over the info;
the bar keeps Message / Admin / Add, Ping and Navigate, the rest goes to a
"More" group under the info (favourite toggled in place, delete by a second
tap). Nodes: an arrow by each distance. A trail's height profile in Map
tools and a saved trail's popup. Diagnostics > History: battery, noise,
SNR and traffic charts. Clock > Calendar: today, the weekend and alarm days.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:26:29 +02:00
JakubandClaude Opus 5.5 99bd41650f feat(ui-new): e-ink graphics on the OLED, a Trail height view
The OLED gets the arrows towards nodes in Nodes and the Path row with its
hop rings in a stored node's detail (its position on one line to make the
room); no compass rose. Trail gets a height-profile view on both. The
Status history, trail profile and calendar come from ui-core. A sim hook
turns on the advert's position for tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:26:29 +02:00
JakubandClaude Opus 5.5 699d6b6ae0 feat(ui-core): status history, trail profile and calendar math, shared
The history of the noise floor, battery, traffic and SNR, a trail's height
profile (with a sampler for trails read point by point off the card) and a
month's calendar, moved out of ui-new so ui-lvgl can draw the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:26:29 +02:00
JakubandClaude Opus 5.5 e16fe2c621 feat(eink): 7 px icons in landscape, a rounded battery
The landscape build's 8x13 digits stand 9 px, so its status, page and
check glyphs and the row-heading map markers come in a 7 px set instead
of 5. The battery outline, in the header and on the Status tile, leaves
its corner pixels out.

The page icons go back to a row of their own under the header: beside
them on the header line only three status icons fitted, and the rest
went missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:39:26 +02:00
JakubandClaude Opus 5.5 3948d65362 fix(eink): no counts of seconds on e-ink
Message ages, the GPS search time and the sky plot changed every second,
and each change is a panel refresh. On e-ink an age under a minute reads
"<1m", the search time counts minutes, and the sky redraws every 15 s
(at once after a key).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:20:14 +02:00
JakubandClaude Opus 5.5 6e6a0fb3ff feat(eink): use the room of tall screens, add e-ink graphics
Tall screens stack the Sky view and the map over their rows, show more
recent chats, give favourite cards the heard age and distance, and put
the trail map under the trail summary. Wide screens put the page icons
on the header line.

E-ink only (Features::IS_EINK):
- a month calendar under the clock and on the portrait lock screen, with
  the alarm's days marked; the lock screen also lists unread messages,
  the alarm and the clock fields
- 8-hour charts in Status: battery, noise and SNR, mesh traffic
- an elevation profile under the trail map, with the climb and the top
- a compass rose and the path's hops on a contact's detail, arrows by
  the distance in Nodes rows and on favourite cards
- an ordered-dither fade under chart lines

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:24:42 +02:00
JakubandClaude Opus 5.5 5c0b79b107 feat(eink): whole message bubbles on tall screens
A screen with room for nine lines or more shows each message bubble
fully wrapped instead of one line. The bubble's height is measured at
the width it is drawn at.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:24:36 +02:00
JakubandClaude Opus 5.5 95295aeec0 fix(ui): a space that overflows ends the wrapped line there
wrapLines carried the overflowing space's word to the next line too
early, so bubbles wrapped short of their width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:24:36 +02:00
JakubandClaude Opus 5.5 0bbf2fa2b3 feat(trail): record altitude in trail points
Each point keeps the GPS altitude in what was padding, so a point stays
16 bytes. The save format goes to version 2; version 1 files still load,
with the altitude unknown. GPX export writes <ele>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:24:36 +02:00
JakubandClaude Opus 5.5 b0e24bb076 feat(eink): landscape and portrait builds, 8x13 font in landscape
The L1 e-ink solo build splits in two, one per screen shape, so each
screen can be laid out for a single shape. Settings > Rotation now only
turns the screen upside down, and the joystick turns with it.

Landscape writes in misc-fixed 8x13 at the panel's own resolution
(EINK_LARGE_FONT); portrait keeps the 6x9. All drawing moves into
EinkGfxDisplay, which the panel driver and the simulator share; the
FreeSans fonts and the CRC32 library go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:24:36 +02:00
JakubandClaude Opus 5.5 3631e0ab85 fix(l2): no Lock clock row in Settings
The Big / Compact lock look is ui-new's; the shared schema row did nothing
on the L2's slide-to-unlock card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 14:23:15 +02:00