171 Commits

Author SHA1 Message Date
DeFiDude 02597f90e9 v1.9.1: input bypass, QR sharing v1.9.1 2026-05-08 14:49:03 -06:00
DeFiDude a7f88f9702 chore: trim stale gitignore entries 2026-05-08 14:48:25 -06:00
DeFiDude 3ee3cf727b license: adopt AGPLv3 2026-05-08 14:48:25 -06:00
dude.eth e7190b4126 Merge pull request #52 from drkhsh/feat/qr-share
ui: QR sharing overlay + Share My QR header on Contacts tab
2026-05-08 14:46:42 -06:00
dude.eth dde109464a Merge pull request #51 from drkhsh/fix/lvgl-input-bypass
ui: bypass LVGL frame throttle on input activity
2026-05-08 14:44:11 -06:00
drkhsh d9c92abf6c ui: QR sharing overlay + Share My QR header on Contacts tab
Adds an lxma://<hash>:<pubkey> QR overlay reachable from Settings and
from a new header row at the top of the Contacts tab. Including the
public key lets Columba/Sideband skip the PENDING_IDENTITY round-trip.

Contacts list stays visible even with no saved contacts so the header
row is always reachable; the empty-state floats above it.
2026-05-05 21:54:05 +02:00
drkhsh a9ec7f9d1e ui: bypass LVGL frame throttle on input activity
Input events otherwise wait up to a full 33ms frame interval before
LVGL renders, which is noticeable when the loop body is loaded.
When the input poll reports activity, run lv_timer_handler()
immediately and let the next idle frame fall back to the 30 FPS cadence.
2026-05-05 20:50:24 +02:00
DeFiDude 00782336f3 fix msg status, home button(s), active msg improvement 2026-05-04 13:14:13 -06:00
DeFiDude f93ba6bfc8 v1.9.1-beta: peer age, flash persistence, msgpack log clamp v1.9.1-beta 2026-05-04 02:15:27 -06:00
DeFiDude e87cef3fb3 ui: fix stale peer age display 2026-05-04 02:11:30 -06:00
DeFiDude c4e5610408 Harden flash config persistence 2026-05-04 01:08:17 -06:00
DeFiDude 149bb08d1a build: clamp MsgPack debug log level 2026-05-03 21:13:47 -06:00
DeFiDude 93643b5442 v1.9.0: lvgl redesign, async transport, hardened storage v1.9.0 2026-05-03 21:04:59 -06:00
dude.eth bc4d0beeac Merge pull request #43 from drkhsh/fix/boot-backlight
Boot: bring backlight up after first boot-screen frame
2026-05-03 21:00:26 -06:00
DeFiDude 4ffa9f6184 Port reconnect backoff to selected profile 2026-05-03 20:57:56 -06:00
DeFiDude 4402c010e9 ratdeck: lvgl redesign, async transport, hardened storage 2026-05-03 20:48:57 -06:00
drkhsh 2ba43fd0ba Boot: bring backlight up after first boot-screen frame
037af2a left the backlight at 0 in Display::begin() to avoid exposing an
unpainted framebuffer, but powerMgr.setBrightness() at step 24 only runs
at the end of boot, so the whole boot sequence rendered onto a dark panel.

Set PWM 128 right after the first lvBootScreen.setProgress(), once LVGL
has flushed the boot screen. powerMgr at step 24 still overrides with the
user's configured brightness.
2026-05-04 00:37:39 +02:00
DeFiDude 19c589583d v1.8.4-beta2: prerelease build v1.8.4-beta2 2026-05-01 16:44:32 -06:00
DeFiDude db0070eabd AutoInterface: notify_link_change on SLAAC privacy-address rotation 2026-05-01 16:39:42 -06:00
dude.eth 07abaaf3c3 Merge pull request #40 from drkhsh/fix/full-address-display
Settings: show full LXMF address and identity hash
2026-04-29 02:45:13 -06:00
dude.eth ef22ad63ad Merge pull request #37 from drkhsh/fix/littlefs-label-fallback
FlashStore: fall back to "spiffs" partition label for M5Launcher
2026-04-29 02:45:07 -06:00
dude.eth 1c15d1e604 Merge pull request #36 from drkhsh/feat/delivery-status-checkmarks
Delivery status checkmarks
2026-04-29 02:45:01 -06:00
dude.eth e1c3423e3a Merge pull request #35 from drkhsh/fix/message-bubble-time-clipping
Fix message timestamps clipping out of bubble
2026-04-29 02:44:55 -06:00
dude.eth 372f40512d Merge pull request #34 from drkhsh/fix/wake-click-and-longpress-blank
Fix wake-click and long-press blanking from subscreens
2026-04-29 02:44:48 -06:00
DeFiDude 19017bfe2e Add 41.7 kHz in dev mode, closes issue #29 2026-04-27 14:53:45 -06:00
drkhsh 423b56c1d8 Settings: show full LXMF address and identity hash
Both the LXMF Addr and Identity readonly entries truncated to the
first 16 hex chars, which made it impossible to type or read the
real address into another client (Sideband, Columba, etc) for adding
ratdeck as a contact. Drop the substring(0, 16) calls and show the
full 32-char hex. Wraps inside the row at the existing font; legible
and copyable.
2026-04-27 20:23:28 +02:00
drkhsh 3d38d7cde4 FlashStore: fall back to "spiffs" partition label
bmorcelli/Launcher labels its user-app data partition "spiffs"; ours
is "littlefs". Subtype is identical in both layouts, so try littlefs
first and fall back to spiffs to coexist with Launcher installs.
2026-04-27 19:54:19 +02:00
drkhsh 17f012b777 Distinguish sent vs delivered with check-mark indicators
Previously a single ASCII glyph collapsed SENT and DELIVERED. Wire
PacketReceipt delivery callbacks through to sideband-style single
and double checks.

LXMFManager tracks outstanding receipts (opportunistic + link
single-packet) by hash. On delivery: persist DELIVERED and fire
_statusCb. On 60s timeout: drop the entry, leave at SENT — lack
of proof over LoRa isn't proof of failure. Resource transfers stay
at SENT; microReticulum's Transport skips receipts for resource
packets and Link::start_resource_transfer exposes no concluded
callback to hook.

LvMessageView renders the glyph via applyStatusGlyph (Montserrat 12):
REFRESH for in-flight, single OK for SENT, double OK for DELIVERED,
WARNING for FAILED. Status callback matches by timestamp (~1s
tolerance) so DELIVERED lands on the right bubble after later
messages have already moved past QUEUED.
2026-04-27 19:44:38 +02:00
drkhsh edbb67c0c8 LvMessageView: reserve bubble pad-bottom for timestamp row
The timestamp label was positioned via lv_obj_align_to below the
message box, but the bubble container's LV_SIZE_CONTENT height was
driven entirely by the box, so the time rendered below the bubble's
allocated row in the flex scroll — visibly hanging into the gap.

Add pad_bottom=14 to the bubble so its outer height includes the
timestamp row, and anchor the box at TOP_LEFT/TOP_RIGHT (was
LEFT_MID/RIGHT_MID) so the layout stacks cleanly: box on top,
timestamp tucked under it inside the bubble's bbox.
2026-04-27 12:26:27 +02:00
DeFiDude 37b536ea7f v1.8.4-beta: prerelease build
Mark prerelease tags (containing '-') as GitHub Pre-release.
v1.8.4-beta
2026-04-26 23:54:53 -06:00
drkhsh 429a578cfd Long-press blanks screen unless actively browsing a list
Contacts/Messages/Nodes screens consumed long-press as soon as they
loaded, which surfaced delete/menu dialogs instead of blanking the
display. Gate per-screen long-press consumption on _focusActive so the
delete affordance only fires after the user has navigated into the
list with up/down/enter. From the resting tab view, long-press falls
through to main.cpp and powers the screen off — same behaviour as the
home screen.
2026-04-26 23:08:42 +02:00
drkhsh e258644671 InputManager: suppress wake-click as enter event
Trackball click already wakes the screen and is the documented way to
revive the device. Firing it as an enter event after release means the
wake also confirms whatever was focused at the time. Gate short-click
emit on _clickFromScreenOn (already captured at click-down for the
long-press case) so the press only does its wake job when the screen
was off.
2026-04-26 21:53:14 +02:00
dude.eth bb11a38e2e Merge pull request #32 from drkhsh/feat/power-management
Power: manual screen-off + pocket-carry input gating
2026-04-25 21:17:13 -06:00
dude.eth 7896d3bfe6 Merge pull request #31 from drkhsh/fix/announce-name-and-aspect
AnnounceManager: stop doubling peers and dropping name characters
2026-04-25 21:16:04 -06:00
dude.eth 2b39f72292 Merge pull request #30 from drkhsh/fix/dir-path-trailing-slash
Fix contacts and conversations vanishing on reboot
2026-04-25 21:03:04 -06:00
DeFiDude f9ef856a6f Add AutoInterface support (IPv6 LAN auto-discovery via microReticulum AutoInterface) 2026-04-25 20:39:18 -06:00
drkhsh ef08510511 Suppress trackball nav events while screen is off
Trackball deltas crossing the nav threshold previously fired
up/down/left/right key events AND set _strongActivity=true, which
woke the screen from SCREEN_OFF on any pocket/backpack jostle and
also accumulated phantom navigation in the UI behind the dark screen.

Gate the nav-event block on isScreenOn(), mirroring the touch
suppression. Click/long-press detection stays unconditional so an
intentional trackball press still wakes the device.
2026-04-26 02:50:55 +02:00
drkhsh 0b6bf5d24b AnnounceManager: filter to lxmf.delivery aspect
The handler had no aspect filter, so it captured every announce from
every aspect of a peer (lxmf.delivery, lxmf.propagation, NomadNet
node, etc.). Each aspect has a different destination hash, so the
same Sideband/Columba peer appeared multiple times in the nodes list
— once with the display name (lxmf.delivery's app_data carries it)
and once or more as raw hex (other aspects had no/different name).

Restrict to lxmf.delivery: that's the only destination we ever route
LXMF messages to. Propagation/NomadNet visibility can come back later
behind an opt-in toggle if needed.

Note: existing saved contacts captured under other aspects will still
appear after this change since they're loaded from disk. They can be
removed manually via the contacts UI.
2026-04-26 02:50:54 +02:00
drkhsh 3d135ceca1 Strip trailing slashes from dir-path constants
PATH_CONTACTS / PATH_MESSAGES / SD_PATH_CONTACTS / SD_PATH_MESSAGES
all ended in '/'. The FATFS layer used by the SD library and LittleFS
won't reliably enumerate when given a path ending in slash — opendir
returns a valid handle but readdir yields nothing. Direct file reads
(SD.open with FILE_READ for a known path) still work, which is why
settings/identity persisted but contacts and conversations vanished
on reboot.

Drop the trailing slash from the constants and add explicit "/" at
all concat sites: saveContact, removeContact, conversationDir,
sdConversationDir, and the migrateTruncatedDirs path builders.
2026-04-26 02:50:54 +02:00
drkhsh ef5d8ea189 Long-press trackball blanks screen; suppress touch wakes when off
Two pocket-carry quality-of-life additions:

1. Long-press (1.2s) trackball click blanks the screen if no LVGL
   screen consumes the long-press. InputManager captures the power
   state at click DOWN (_clickFromScreenOn) and only emits the
   long-press if the screen was already on, so a long-press from
   SCREEN_OFF wakes without immediately re-blanking.

2. Touch events are ignored entirely while screen is off, preventing
   accidental wakes from pressure on the panel in a pocket/bag.
   Trackball click and keyboard keys still wake normally.

InputManager now holds a Power* injected via setPowerMgr() in setup.
2026-04-26 02:50:54 +02:00
drkhsh f4eaf71983 sanitizeName: allow forward slash in display names
Sideband/Columba and other LXMF clients commonly include "/" in display
names (e.g. handle/path conventions). The allowlist in sanitizeName
stripped it, mangling "alice/columba" into "alicecolumba". Saved
contacts get re-sanitized on each load (line 393), so existing names
also lose the slash on next boot.
2026-04-26 02:50:54 +02:00
drkhsh a8da0d8918 Add Power::forceScreenOff() for manual screen-off triggers
New public method that transitions to SCREEN_OFF on demand. A
_justWokeFromOff flag is set in activity() and cleared at the end
of loop() so a single keypress that woke the screen can't immediately
re-blank it via a hotkey/long-press handler running in the same tick.

Pure infrastructure — no UI binding included; consumers can wire it
to whatever input event they want (long-press, hotkey, etc.).
2026-04-26 02:50:54 +02:00
DeFiDude 3393d0afb4 Remove auto-seeded TCP hub default; users opt-in via Settings 2026-04-25 18:41:14 -06:00
DeFiDude 9cb5a4f3db v1.8.3: LXMF Python interop — disable bz2 compression
Python LXMF was sending bz2-compressed Resource transfers that
microReticulum cannot decode on ESP32 (bz2's working memory exceeds
available SRAM). The companion microReticulum commit (290a133)
removes bz2 entirely; this release advertises no-compression-support
in our LXMF announces so Python LXMF disables auto_compress when
sending to Ratdeck destinations.

Also pins lvgl and LovyanGFX minor versions in lib_deps to prevent
future fresh-clone builds from pulling incompatible 1.2.x / 8.4.x.

Thanks to @RFNexus for surfacing the ESP32 bz2 constraint.
v1.8.3
2026-04-24 18:23:35 -06:00
DeFiDude b54ac52666 LXMF announce: advertise no SF_COMPRESSION (don't trigger Python bz2)
encodeAnnounceName now emits msgpack fixarray(3):
  [display_name(bin), stamp_cost=0, supported_functionality=[]]

Empty supported_functionality list = SF_COMPRESSION (=0x00) absent,
so Python LXMF disables auto_compress for our destinations and stops
shipping bz2-compressed Resources we can't decode. Always emit the
3-element form even when the name is empty — Python defaults to
auto_compress=True for legacy <3-element app_data.

Pairs with microReticulum 290a133 which removed bz2 entirely.
2026-04-23 21:41:59 -06:00
DeFiDude 401107995a Pin lvgl and LovyanGFX to ~1.1.16 / ~8.3.4 (block 1.2.x / 8.4.x)
LovyanGFX 1.2.x bundles its own lvgl-compat headers that collide
with lvgl >=8.4 on shared types (lv_area_t, lv_font_t, etc.).
Tilde restricts fresh clones to the 1.1.x and 8.3.x ranges this
build was originally cached against, so `pio run` from a fresh
checkout doesn't randomly break.
2026-04-23 21:41:13 -06:00
DeFiDude be771818f9 Silence vfs_api error spam and rename /ratputer/ SD paths to /ratdeck/
CORE_DEBUG_LEVEL=0 drops Arduino core noise on expected-missing files, LittleFSFileSystem::open_file now actually works so path_table persists across reboots.
2026-04-16 21:54:44 -06:00
DeFiDude b27e5c9f1e Update presets
Updating radio presets now, planned for the website overhaul but doing presets early since users are having troubles.
2026-04-16 13:27:03 -06:00
dude.eth de608c4667 Increase supply chain risk
I simply do not care enough to keep the proper microReticulum commit pinned, started as a joke. Still keeping crypto dependencies internal, though.
2026-04-08 13:38:23 -06:00
DeFiDude e8000538aa Reduce supply chain risk 2026-04-07 15:11:39 -06:00