Commit Graph
146 Commits
Author SHA1 Message Date
Kaj SchittecatandClaude Opus 4.8 30083efdd7 touch: beta_12 — GPS hotfix (enlarge GPS UART RX buffer)
The GPS NMEA UART used Arduino's default 256-byte RX ring (~66 ms of slack at
38400 baud). On the busy touch UI a single long LVGL/map frame stalls the loop
past that window, dropping bytes and corrupting NMEA ephemeris subframes — each
loss costs the receiver ~30 s, turning a ~1-minute fix into several minutes or,
with frequent stalls, never acquiring. Confirmed on-device: peak UART backlog
hit 448 B at idle, well past the 256 B default. Bump the ring to 4096 B (~1 s of
slack) before the core opens Serial1 in sensors.begin(). App-side (no core
re-tag); gated to ENV_INCLUDE_GPS so both touch boards get it. A -DGPS_BUF_DEBUG
backlog probe is included (compiled out of releases).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 08:49:00 +02:00
Kaj SchittecatandClaude Opus 4.8 d22390aeb8 flasher: point manifest at immutable per-tag bin, not latest/
The web-flasher manifest referenced https://firmware.wadamesh.com/latest/<board>-merged.bin
— a stable filename cached 4h (Cache-Control max-age=14400) and overwritten in place each
release. version.json (max-age=300) advertised the new tag within minutes, but the latest/
bin could keep serving the PREVIOUS beta's bytes per-POP for up to 4h, so a user flashing
right after a release could install the old version (reported: flashed beta_11, device showed
beta_10). Point the manifest at the immutable releases/TOUCH/<tag>/ bin instead — that URL is
never overwritten so its cache is always correct, and the 5-min manifest TTL propagates the
new path fast.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 20:10:44 +02:00
Kaj Schittecat 3130a1198e chore: refresh Mesh America catalog for beta_11 beta_11 2026-06-22 19:17:00 +02:00
Kaj SchittecatandClaude Opus 4.8 1f755ec3b8 touch: beta_11 — bindable keyboard navigation, crash-report prompt, map zoom buttons, app-drawer-as-home; publish Tanmatsu port source
Headline: full keyboard navigation (on by default) — WASDZ spatial focus move, S select,
Q back, per-tab hotkeys (E/R/T/U/I) shown on the icons, plus scroll up/down (F/C). Every
key is remappable in Settings -> Keyboard. Foundation for keyboard-first devices like the
Tanmatsu T-Pager (no touchscreen) and a reliable keyboard workflow on the T-Deck today.
Also: #27 receive/flood reboot fix, on-boot crash-report prompt, map zoom +/- buttons (#26),
route-replay wide overview, 'App drawer as home' option. The in-progress Tanmatsu (ESP32-P4)
port source is now public. Mesh America catalog + release.sh kept from main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 19:10:40 +02:00
Kaj SchittecatandClaude Opus 4.8 c931df6054 touch: beta_10 — trackball D-pad mode, microSD tile-cache fill, Battery group
- T-Deck: trackball mouse/D-pad navigation toggle (Settings -> Keyboard).
- Map (#20): microSD-tile mode now caches Wi-Fi-fetched tiles onto the SD card so
  the offline library fills in + grows instead of going blank past its edge.
- Power: PR #19 idle power-save (Dan Vybiral / @Vybo) relocated into a new
  'Battery' group under Settings -> System, alongside a button that opens the
  battery / power-history screen.
- TouchCfg v10 (ui_scale, tb_keypad, sleep_idle). Mesh America catalog -> beta_10.

Curated touch overlay onto main (the WIP Tanmatsu ESP32-P4 build system stays on
the tanmatsu-port branch). Co-Authored-By: Dan Vybiral <dan.vybiral@greencode.cz>

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
beta_10
2026-06-22 00:08:13 +02:00
Dan Vybiral 11b31e1cdd touch: idle power-save — loop-throttle + downclock when parked (#19)
Opt-in Idle power-save for the T-Deck: when parked (screen off, on battery, no
companion client, Wi-Fi+BLE off, mesh idle) the main loop is throttled with
vTaskDelay so the FreeRTOS idle task can halt the CPU between ticks, on top of the
existing 80 MHz screen-off downclock — without ever stopping mesh RX. Default OFF
(Settings -> Lock, persisted TouchCfg v8 sleep_idle); status-bar moon indicator +
idle stats. Heltec V4 compiles (gate never passes there). A plain scheduler throttle
rather than esp_light_sleep_start(), which trips INT_WDT in this build.

Co-authored-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-21 22:39:59 +02:00
Kaj SchittecatandClaude Opus 4.8 c16b5230a6 release: auto-refresh + push the Mesh America catalog each beta
release.sh now regenerates deploy/meshamerica-catalog.json for the tag and, when
run on main, commits + pushes that one file so apps.meshamerica.com (the flasher
Cascadia Mesh uses) always points at the newest immutable bins instead of going
stale on the previous beta. Idempotent (no-op when already current); non-fatal if
the push fails; also mirrors the catalog into the VPS publish tree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 22:27:28 +02:00
Kaj SchittecatandClaude Opus 4.8 f5362b1cb3 deploy: add Mesh America Configurator provider catalog
Catalog JSON (Mesh America provider schema) + a reusable generator so the two
wadamesh touch boards appear in the Mesh America Device Configurator
(apps.meshamerica.com — the flasher Cascadia Mesh uses). Points at the immutable
per-tag bins on firmware.wadamesh.com (HTTPS + CORS). Served live over
raw.githubusercontent.com.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 22:20:29 +02:00
Kaj SchittecatandClaude Opus 4.8 7a63ffe86c touch: beta_9 — crash/Wi-Fi reliability, crash-report export, room fixes, app-drawer icon size
- Stability: Wi-Fi auto-reconnect; corrupt chat-history quarantine (fixes reboot-on-
  receive / inaccessible messages); draw-buffer + flush NULL-guards (boot-panic).
- Crash-report export to SD/SPIFFS (Settings -> About).
- Map: reload purges on-disk tiles offline + visible zoom band; corrupt-tile self-heal
  on load; z15 dedup-key overflow fixed.
- Contacts: favourites always listed (#17).
- Chat: room message send-time (#26) + sender labels; QR share uses the official
  meshcore://contact/add format (#16); unread badge capped at 99+.
- App drawer: icon-size setting (Compact/Large) + smoother scrolling.
- ~5 KB internal DRAM reclaimed (backup arrays + msg_idx -> PSRAM).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
beta_9
2026-06-20 15:16:04 +02:00
Kaj SchittecatandClaude Opus 4.8 2aa8f59410 touch: beta_8 — Ack reply, map visibility toggles + auto-refresh, RAM trim
- Chat: quick replies insert at the cursor (no longer replace typed text);
  long-press 'Ack' drops a signal-strength + route reply into the composer
  (@mentions the sender on channels); fixed the action-menu overflowing the screen.
- Map: +/- zoom glyph; per-line on-map visibility toggles (coords / tile xyz /
  contacts); microSD-tiles regrouped under a heading; auto-refresh follow button
  with on/off toast; close-X overlap fix when scrolled.
- Perf: ~18.9 KB internal DRAM reclaimed (6 scratch buffers -> on-demand PSRAM).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
beta_8
2026-06-19 14:36:46 +02:00
Kaj SchittecatandClaude Opus 4.8 c8b451f14f release: beta_7 notes — credit contributors prominently (Vybo #12, Ruben Laban #15, marcelverdult #13)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 12:32:03 +02:00
Kaj SchittecatandClaude Opus 4.8 9e567e1789 touch: beta_7 — app-drawer fit + visible scroll, Snake touch steering & icon
- App drawer: size tiles to fit so the bottom row's labels aren't clipped, and
  show a persistent scrollbar when the grid overflows (discoverable scroll).
- Snake: steer via the hardware swipe detector (works on the V4 cap-touch and
  the T-Deck), stop touch/swipe leaking to the screen behind the overlay, and
  gate the status bar while playing.
- Snake app-drawer icon drawn from shapes — the U+1F40D emoji isn't in the baked
  colour-emoji set, so it rendered as a tofu box.
- Add beta_7 release notes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
beta_7
2026-06-18 12:21:49 +02:00
Kaj Schittecat bbcafa3088 Merge PR #12 (Vybo): status-bar tools, battery history, map night mode, image viewer, Snake
# Conflicts:
#	src/ui-touch/UITask.cpp
2026-06-18 11:04:08 +02:00
Kaj Schittecat b3af35666b Merge PR #15 (tun0): fix inaccurate unread badges + split history persistence
- closeChatPanel marks-read + flags dirty immediately (no stale badge)
- post-load reconciliation clears phantom unread for evicted threads
- split thread-meta (200ms flush) vs message-ring (lazy 2s) persistence
- ring 96 -> 500
2026-06-18 10:58:08 +02:00
Kaj SchittecatandClaude Opus 4.8 eca5281f22 touch: post-beta_6 batch — BLE PIN, wallpaper-from-files, storage & memory fixes
- BLE: user-settable 6-digit pairing code (Settings -> Bluetooth), MyMesh::setBLEPin.
- Lock wallpaper: pick via the file manager (fast, any folder) + 'Set as wallpaper'
  in the image viewer; downscaling JPEG decoder accepts images > 1024 px and keeps
  the held buffer small; clear message for progressive JPEGs.
- Map tiles: validate JPEG magic before caching + re-fetch bad cached tiles
  (fixes black quadrants).
- Channel @reply: quick-reply now appends at the cursor instead of wiping the
  mention.
- Audio: heap pre-flight before i2s_driver_install (fixes the esp_timer NO_MEM
  abort when toggling sound under BLE+Wi-Fi memory pressure).
- App drawer: squircle tiles. Log hygiene: CORE_DEBUG_LEVEL 1->0 (mute benign
  vfs/Preferences spam off the USB-CDC companion stream).
- Core bump to core-v1.16.4 (drops the 4-byte chat-payload trailer, issue #13).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 10:57:50 +02:00
Ruben LabanandClaude Sonnet 4.6 3a70a8ab0f touch: fix legacy history migration when ring size grew
loadLegacyHistoryFromStorage() tried to read MAX_UI_MESSAGES (now 500)
records from a file that only contained 96 (old ring size). It read the
thread metadata fine — populating unread counts — then hit EOF on the
messages and returned false. The reconciliation pass that resets phantom
unread counts never ran, so the first boot after the ring bump showed
high unread counters against empty channels.

Fix: derive the actual slot count from the remaining file size and only
read that many message records, zero-filling the rest. The phantom-badge
reconciliation in loadHistoryFromStorage() then clears any thread whose
messages were already evicted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:45:30 +02:00
Ruben LabanandClaude Sonnet 4.6 2894776a11 touch: split history save into threads+msgs files; bump ring to 500
Thread metadata (~4 KB, contains unread counts) and the message ring
(now ~115 KB at 500 slots) are now persisted to separate files
(/ui_threads_v1.bin and /ui_msgs_v1.bin).

Thread metadata flushes on the original 200 ms delay so unread counts
survive a hard reset. The message ring flushes lazily every 2 s,
batching burst arrivals into a single write instead of hammering SPIFFS
on every message — reducing flash wear and WdtHeavyGuard exposure as
the ring grows.

MAX_UI_MESSAGES 96 → 500 (PSRAM cost: 26 KB → 133 KB, well within
budget). Ring overflow within a session is now extremely unlikely on
LoRa; the cross-session phantom-badge fix (post-load reconciliation)
from the previous commit handles the remaining edge case.

Migration: on first boot the loader falls back to the legacy combined
file (/ui_chat_history_v1.bin), then schedules writes of the new split
files. Old file is left in place and ignored on subsequent boots.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:31:33 +02:00
Ruben LabanandClaude Sonnet 4.6 88a9d386f1 touch: reset phantom unread on load when ring has no messages for thread
The display ring is a fixed-size cache independent of the per-thread
unread counter. After a reboot the ring may not contain the messages
that were counted as unread (they were evicted before the save), leaving
a non-zero badge on a thread that opens to an empty chat.

Fix: after loading history, zero the unread counter for any thread whose
messages are absent from the ring. The unread counter and the ring are
independent — the ring is a display buffer only — so opening the thread
via the first fix (markThreadRead on close) handles the mid-session case;
this one-shot check handles the cross-reboot case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 09:05:36 +02:00
Ruben Laban a6647dcf55 Revert "touch: fix phantom unread badge when ring evicts channel messages"
This reverts commit 28879f55c4.
2026-06-18 09:04:37 +02:00
Ruben LabanandClaude Sonnet 4.6 28879f55c4 touch: fix phantom unread badge when ring evicts channel messages
The 96-slot message ring can overflow when there is sustained traffic
across many threads. When ring wraparound silently overwrites a channel's
messages, thread.unread stays non-zero but getThreadMessageIndexes
returns 0 — producing a badge with a count but an empty chat on open.
The same phantom persists across reboots because unread is saved to
disk independently of the ring contents.

Fix has three parts:

1. counted_as_unread per UIMessage (RAM-only): set true when a message
   is the reason a thread's unread counter was incremented. Cleared when
   the thread is marked read, so future evictions of those slots don't
   double-decrement.

2. Eviction hook in appendMessage: before overwriting a ring slot,
   decrement its thread's unread if the slot was counted_as_unread.
   Keeps the counter in sync as the ring wraps.

3. Post-load reconciliation in loadHistoryFromStorage: after restoring
   thread+message state from disk, any thread whose persisted unread
   count exceeds its actual incoming messages in the ring gets clamped
   (or reset to 0 if the ring has nothing for it). Also reconstructs
   the counted_as_unread flags so evictions after boot are tracked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 08:34:37 +02:00
Ruben LabanandClaude Sonnet 4.6 d16c833171 touch: fix stale unread badge on per-channel/DM inbox rows
Two related causes:

1. Messages arriving while a chat is open increment unread (appendMessage
   always passes mark_unread=true). closeChatPanel never called
   markThreadRead, so those in-session messages left a phantom badge in
   the inbox after the user closed the chat.

2. Neither threadSelectCb (open) nor closeChatPanel (close) set
   dirty_threads, so the inbox list could lag up to 4 s (the periodic
   refreshThreadsFromMesh tick) before reflecting a cleared count.

Fix: call markThreadRead on the active thread in closeChatPanel and set
dirty_threads so the inbox rebuilds immediately on return.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 08:19:32 +02:00
Dan Vybiral 031cb03bd4 battery chart on V4 (SPIFFS fallback); telemetry log under /meshcomod/telemetry
Battery log/chart now compile on both builds: a small FS selector prefers the SD
card when present (T-Deck, /meshcomod/battery.log) and falls back to internal
SPIFFS (/battery.log) otherwise, so the 24h chart + battery tap work on the
Heltec V4 (no SD slot) too. The 5-min logger and the battery tap-wiring are no
longer gated behind HAS_TDECK_GT911.

Telemetry per-node logs + poll.cfg move from /telemetry to /meshcomod/telemetry
to sit with the other app files. Telemetry logging/window/auto-poll stay
T-Deck-only (V4 keeps the request/reply toast).

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 14:59:30 +02:00
Dan Vybiral 5ec9176906 file browser: fix stale image when viewing several in a row
s_fm_img_dsc is a reused static, so LVGL's image cache (keyed on the src pointer)
returned the previous image's decoded geometry/data — the 'half old, half new'
render. Invalidate the cache entry when building the dsc and on close.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 14:42:50 +02:00
Dan Vybiral ed9cf619ec map: invert status bar + tab bar chrome under night mode
On the map tab the immersive chrome forces black text/icons for legibility over
the light tiles. With night mode on the tiles are dark, so flip the status-bar
text and the bottom tab-bar icons to off-white instead. Only affects the map tab;
re-applied immediately when night mode is toggled.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 14:32:18 +02:00
Dan Vybiral 460b82f9bc file browser: view PNG and BMP images, not just JPEG
The viewer already routed image taps to fmOpenImage but only ran the JPEG
decoder and bailed on PNG with a stale 'not supported' note. Sniff the magic
bytes and route PNG -> decodePngToRgb565 (lodepng, already used for map tiles)
and BMP -> a small 16/24-bpp reader (so screenshots saved by the status-bar hold
are viewable). fmIsImage now also accepts .bmp.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 14:30:36 +02:00
Dan Vybiral 0a4d8d5b2f map: live zoom-level readout above the zoom slider
A 'zoom <level>' chip, centred above the slider, appears with it and updates
live while dragging so the target level is visible before release.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 14:23:21 +02:00
Dan Vybiral e72a1b1bd5 map: real magnifier glyph on the zoom button
Add a one-glyph FontAwesome font (zoom_font.c, U+F002 magnifying-glass, 16 px bpp4,
generated with lv_font_conv from fa-solid-900.ttf) and splice it into the g_font_16
fallback chain alongside person_font. The map zoom button now shows a magnifier
(TOUCH_SYM_ZOOM) instead of the borrowed + glyph.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 13:56:37 +02:00
Dan Vybiral 30fe6fbd6f map/telemetry/battery/snake: visibility, zoom slider, night mode, screenshot
Battery chart: stats line spans the full width so the CPU MHz figure no longer
wraps; the CPU series + chip now use the RF-monitor noise-floor grey (0x4A5256).

Telemetry: the window no longer auto-requests on open — it shows history and a
Request button (async refresh glyph, left of the gear) sends a poll. Legend text
recoloured to the axis-note grey instead of near-black.

Map: the + / - overlay buttons are replaced by a single zoom button that toggles
a full-width zoom slider along the bottom of the map (tap again to hide); the
chosen level is persisted across reboots and wins over the first-open auto-snap.
New 'Night mode (invert)' toggle in Map options inverts tile colours at render
time only (cache untouched), persisted.

Snake: pause/resume button next to the close X.

Status bar: hold for 3 s to capture a full-screen screenshot to
/screenshots/<time>.bmp on the SD card (16-bit BMP — fastest viewable format;
the hold suppresses the control-center tap).

Prefs: cfg v5 adds map_night + map_zoom.
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 13:47:38 +02:00
Dan Vybiral 5e8dd55847 battery chart: make the window scrollable; lay the bottom block out top-down
The card was a fixed 246 px — taller than the screen — and not scrollable, so its
bottom-anchored estimate/stats/points labels were clipped and overlapped (the
narrower text width also let the estimate wrap onto the stats line). Switch the
card to content height with a max-height cap + vertical scrolling, and place the
chart, the three text lines and the CPU/trash buttons with a running y so they
stack cleanly and the window scrolls when it doesn't fit.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 13:19:39 +02:00
Dan Vybiral 26ae08101c telemetry/battery: data-visibility toggles + telemetry settings panel
Battery chart: a CPU chip beside the trash button shows/hides the CPU-MHz
series; the secondary axis, series and bottom-line CPU figure are dropped when
hidden and the chart redraws immediately.

Telemetry window: a gear opens a settings panel spawned on top with checkboxes
for the battery / temperature / humidity series (the chart underneath redraws
live as they toggle), a manual auto-poll interval field (minutes, 0 = off,
replacing the cycling button) and the clear-history button. The main window now
holds only the reading, chart and time-range inputs; its layout was reworked so
the chart clears the wrapped reading line and the time-range fields no longer
overlap their labels.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 13:05:07 +02:00
Dan Vybiral aa89572631 chore: gitignore custom build outputs and local notes
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 13:05:07 +02:00
Dan Vybiral ff5818f7f7 battery chart: stack bottom text clear of the trash button; dim the CPU line
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 12:48:14 +02:00
Dan Vybiral be7fb32f23 battery chart: estimated life left (d/h/m) from the discharge slope, skipping charge
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 12:43:02 +02:00
Dan Vybiral 17981029a7 telemetry: per-node window with battery/temp/humidity chart, auto-poll, clear
- Manual telemetry opens a per-node window immediately (request-in-progress),
  then updates to the reading on reply or "last request failed" on timeout — the
  window shows history either way (issue: see history even on failure).
- Chart from /telemetry/<id>.log: battery V (left) + temperature/humidity (right),
  RF-monitor-style axis ticks + grid, point markers.
- Display window chosen with two fields (now-X h .. now-Y h ago); "Show" reloads.
- Auto-poll per node (toggle + 1/5/15/30/120 min), persisted to /telemetry/poll.cfg;
  due nodes are polled from UITask::loop — emits the async spinner, logs the reply,
  does NOT open the window.
- Clear-history buttons (with confirmation) on both the telemetry and battery windows.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 11:51:04 +02:00
Dan Vybiral 9bc9822111 telemetry: log each reply (battery/temp/humidity) to /telemetry/<id>.log per node
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 11:38:19 +02:00
Dan Vybiral 799a3754d0 battery chart: clamp charging spikes to top; RF-monitor-style axis ticks + grid
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 11:35:06 +02:00
Dan Vybiral c9e3de15d4 status bar: park the async spinner left of the clock so it never overlaps it
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 10:27:34 +02:00
Dan Vybiral be1c72fbb1 status bar: SD LED also covers file-manager reads + cross-volume copies
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 10:21:55 +02:00
Dan Vybiral b478851a21 status bar: async-request spinner (telemetry/admin/ping/trace/range/sightline)
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 10:18:42 +02:00
Dan Vybiral 8ce6baf786 battery chart: blue series, calibrated range, visible points, per-point value labels
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 10:14:08 +02:00
Dan Vybiral b82f4a2363 apps: floor the drawer tile height so a full grid scrolls instead of shrinking
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 10:04:16 +02:00
Dan Vybiral 6e62d35328 contacts: add "Show on map" to the action sheet (centre the map on the node)
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:45 +02:00
Dan Vybiral fe8925f91d apps: Snake review fixes — trackball, New-game gate, full field, tab-bar lock
- trackball now steers Snake (UITask routes motion via SnakeGame::isOpen()/steer()
  and hides the soft cursor on that page).
- a "New game" button gates the start so it doesn't move on open; tap restarts
  after a game over.
- slower tick (220 -> 300 ms).
- playfield fills the unoccupied screen (dynamic cols x rows at kCellPx instead of
  a small fixed square).
- the tab bar is hard-locked while Snake is open so a stray swipe/tap can't slip
  through to the app switcher (e.g. into the map).

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:44 +02:00
Dan Vybiral 7463530f63 ui: review fixes — contacts sort, battery chart, close buttons, clock centring
- contacts: the "?" (unknown last-heard) sink-to-end now mirrors formatAgeBadge's
  exact condition (also future/garbage/>400-day timestamps, not just ==0), using
  the clock captured before the sort. Fixes "no change in behaviour".
- battery chart: add a universal close X (addCloseXBadge); lighter grid + time
  (vertical) division lines; axis notes (V left, MHz right, time on X); point
  dots so a single/sparse sample renders; second ORANGE CPU line on a secondary
  Y axis. battery.log gains a CPU-MHz column (5th field); pre-upgrade 4-col lines
  read as a CPU gap.
- telemetry window: add the same universal close X.
- hide device name: park the clock CENTRED on every screen (not just Home),
  clear of the left-zone title (chat / Files / map credit) and the right icons.

Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:44 +02:00
Dan Vybiral d7151dbbf8 apps: extract Snake into a self-contained SnakeGame class (own files)
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:44 +02:00
Dan Vybiral dd67336fdb apps: add a Snake game (canvas + swipe to steer)
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:43 +02:00
Dan Vybiral 13b240062a telemetry: show the response in a dismissible window instead of a toast
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:04 +02:00
Dan Vybiral 9ddb08ba93 status bar: tap battery for a 24h history chart, logged to SD every 5 min
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:03 +02:00
Dan Vybiral 373be3e546 settings: option to hide the device name and park the clock left
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:03 +02:00
Dan Vybiral d2e776afe9 status bar: fix charging-shift offsets to match the SD-LED layout
Signed-off-by: Dan Vybiral <dan.vybiral@greencode.cz>
2026-06-17 09:54:03 +02:00