Commit Graph

3514 Commits

Author SHA1 Message Date
ripplebiz
999e20a4c2 Merge pull request #1687 from IoTThinks/MCdev-PowerSaving-for-all-esp32-repeaters-202602
Added PowerSaving for all ESP32-based repeaters
2026-06-04 13:31:51 +10:00
Jakub
2e7416d7ed docs(tools): note imperial min-dist levels follow the Units setting
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:50:55 +02:00
Jakub
d0d20989a0 feat(units): imperial min-distance gate + imperial map grid
Follow the global Units preference in the two remaining Trail distance
spots that were still metric-only:

- Min dist gate: the index is now a unit-agnostic level (0=finest..3).
  Metric stays 5/10/25/100 m; imperial uses round 15/30/75/300 ft (applied
  as their metre equivalents in the sampling gate).
- Map scale grid: imperial mode uses round ft/mi steps (10 ft … 100 mi)
  instead of metric steps with a converted label. Step storage moved to
  float metres so sub-metre imperial steps keep their geometry; labels come
  from a parallel table so the scale bar reads an exact round value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:50:42 +02:00
Jakub
9ae0828fcb docs: document global Units setting + Trail Readout toggle
Add the Settings › System "Units" (Metric/Imperial) row and update the
Trail action-menu entry from the old four-way km/h·mph·min/km·min/mi
"Units" cycle to a Speed/Pace "Readout" toggle within the global system.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:45:47 +02:00
Jakub
359b5fccd7 feat(units): global metric/imperial setting for all distance displays
Add a single "Units" choice (Settings › System: Metric / Imperial) that
governs every distance and speed shown in Tools — Nearby Nodes, the Trail
views, and the navigate-to-point screen.

- NodePrefs: units_imperial (global) + trail_show_pace (Trail readout mode),
  schema bumped 0xC0DE0005 → 0006. The old combined trail_units_idx is kept
  for file-layout stability but no longer drives anything; upgraders default
  to metric + speed.
- geo::fmtDist gains an imperial mode (ft below ~1000 ft, then miles).
- NavView / Nearby / Trail (waypoint list, Summary distance, List deltas,
  map scale-bar label) all format through the global preference.
- Trail's action-menu "Units" row becomes a Speed/Pace readout toggle; the
  km-vs-mi unit now follows the global setting instead of being one of four
  combined options.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:44:56 +02:00
Jakub
7c25aa1ad4 refactor(trail): route gpsHasFix through ownPos/currentLocation
The last stray getLocationProvider/isValid duplicate (with its own
ENV_INCLUDE_GPS guard). Fold it into ownPos so every GPS lookup in the
nav screens goes through UITask::currentLocation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:16:28 +02:00
Jakub
1d0c655111 refactor(nearby): drop geo:: forwarding wrappers, call geo:: directly
The static haversineKm/bearingDeg/bearingCardinal/fmtDist members were
thin pass-throughs to GeoUtils. Remove them and qualify the call sites
with geo:: so there's no parallel local API to keep in sync.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:15:36 +02:00
Jakub
a5d55a38b9 refactor(ui): share Bresenham line + midpoint circle in GfxUtils.h
drawLine was duplicated verbatim in TrailScreen and CompassScreen, and
drawCircle lived only in CompassScreen. Lift both into a gfx:: namespace
header so the map and compass share one copy of each 1-px primitive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:13:44 +02:00
Jakub
55d164c074 refactor(nav): single GPS-position accessor + reset COG window after a gap
UITask::currentLocation() becomes the one place that reads the
LocationProvider fix. TrailScreen::ownPos, CompassScreen::gpsValid and
NearbyScreen::refresh now delegate to it instead of each duplicating the
getLocationProvider/isValid dance (and the ENV_INCLUDE_GPS guard).

pushCogFix now restarts the course-over-ground ring when the gap since the
previous fix exceeds 15 s: after losing GPS for a while, a window spanning
the stale old fixes would compute a bogus "teleport" heading. The
last-good heading is kept for display continuity.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:12:15 +02:00
Jakub
bd364ccfd1 docs(tools): note map always shows live position + waypoints
Clarify in both the Map view row and the Waypoints section that the
current GPS position and all waypoints are drawn continuously, so the Map
view is useful standalone without an active trail recording.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:04:38 +02:00
Jakub
459c2c3b12 feat(nav/map): show two label characters beside a waypoint marker
One character was too ambiguous to tell adjacent waypoints apart on the
map. Draw the first two characters of the label (falling back to one when
the label is a single char) in both the normal and degenerate map paths,
and widen the right-edge fit guard to the rendered text width.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:04:11 +02:00
Jakub
3ec578aad3 fix(nav/map): label the waypoint in the degenerate single-point case
When the map collapses to one coordinate (e.g. a single waypoint with no
trail and no GPS fix yet), the degenerate branch drew the waypoint marker
but never its label — so it appeared as a bare diamond. Draw the first
character of the waypoint's label beside the centred marker, matching the
normal map path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 23:56:53 +02:00
Jakub
eb4175c4c4 feat(nav): map shows live position + waypoints without recording
The Trail Map is now useful as a plain "you are here + waypoints" view even
when no trail is being recorded:

- The bounding box folds in the live GPS fix (via ownPos) alongside the
  trail and waypoints, so the current position is always in frame.
- The current-position marker is drawn at the live fix when available
  (falling back to the last recorded trail point otherwise), instead of
  only at the trail's end — so it shows with an empty trail too.
- Empty-everything message is now "No GPS / no trail" and only appears when
  there is genuinely nothing to show (no trail, no waypoints, no fix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 23:54:48 +02:00
Jakub
96cca4773c docs(tools): document waypoints, navigation and the Compass
- Trail action-menu table gains Mark here / Waypoints / Clear waypoints.
- New Waypoints section: dropping (Mark here + label), independence from
  the trail (/waypoints, survives reboot/Reset), map marker, the always-
  present Trail-start row, the two-bearing nav view, and rename/delete.
- New Compass section: heads-up course-over-ground (no magnetometer),
  rotating card, movement-only heading, GPS-fix gating.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 23:51:15 +02:00
Jakub
32ffcb18a3 feat(nav): "Clear waypoints" action in Trail menu
Adds a bulk clear for saved waypoints (Trail → Hold Enter → Clear
waypoints), shown only when at least one waypoint exists. Independent of
the trail — Reset trail still leaves waypoints intact; this is the
explicit way to wipe them all instead of deleting one by one.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 23:49:26 +02:00
Jakub
288a6195da feat(ui/compass): draw the ring as a circle, not a square
Replace the bounding-box stand-in with a midpoint-circle ring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 16:54:30 +02:00
Jakub
98ccf13336 feat(nav): heads-up compass + always-available Trail-start waypoint
Compass: switch to a heads-up card. The direction of travel is now the
fixed "up" index at the top and the compass card rotates underneath it —
a North needle plus N/E/S/W letters placed at screen angle (bearing - cog),
so North spins as you turn rather than the arrow pointing at your course.

Trail waypoints: the nav list now always starts with a synthetic
"Trail start" row whenever a trail exists, so you can navigate back to
where you began without having marked it. The "Waypoints" action appears
when there are saved waypoints OR a trail to backtrack to. Rename/Delete
apply only to saved waypoints; the start row is navigate-only. List/nav
indexing goes through rowTarget()/wpIndex() helpers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 16:51:40 +02:00
Jakub
3110b59f93 fix(ui/tools): scroll the Tools list
The Tools menu rendered all items from listStart() with no scroll, so the
6th entry (Compass) fell off the bottom on the OLED's short panel and was
unreachable. Add a scroll offset that keeps the selection in view, with
the usual ^/v indicators.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:14:28 +02:00
Jakub
e354b78b46 fix(nav): ping result never appeared after Send
startPingForKey() set the "RTT: ..." line but didn't rebuild the ping
menu, and updatePingMenuState only rebuilt on a string-count change it
computed after the mutation — so the menu stayed at a lone "Send" row and
nothing visibly happened after pressing Send, whether or not a reply came.

- Rebuild the menu right after starting the ping so "RTT: ..." shows at
  once; on send failure show "RTT: send fail" instead of a blank.
- Sync the menu against its actual row count (_ping_menu._count) as result
  lines populate, so RTT/SNR rows appear when the reply lands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:11:03 +02:00
Jakub
8bf050ddb4 feat(nav): standalone Compass in Tools
Tools › Compass shows the device's course over ground (from the GPS COG
ring — no magnetometer) as a rotating arrow in a ring with a north tick,
plus a large degrees + cardinal readout. "No GPS fix" without a fix;
"move to set heading" when stationary (course undefined). Reuses
UITask::currentCourse, so it works without recording a trail.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:07:53 +02:00
Jakub
ed984e437b feat(nav): node detail Options menu (Navigate/Ping); ping rows no longer blank
Two fixes from on-device testing:

- Node navigation was bound to a bare Enter in the detail view, which was
  undiscoverable. Hold Enter now opens an Options popup (Navigate / Ping),
  consistent with the rest of the UI. Navigate opens the shared NavView;
  Ping runs the ping and shows its result.

- The ping popup always carried three result rows (RTT / SNR out / SNR
  back) even before a ping, so the user could scroll onto blank rows. The
  menu is now rebuilt to contain only "Send" plus the result lines that are
  actually populated, growing in place as the reply arrives.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:00:16 +02:00
Liam Cottle
cb73a4a156 Merge pull request #2022 from weebl2000/adjust-max-framesize
Increase MAX_FRAME_SIZE by 4 bytes
2026-06-03 19:58:01 +12:00
Kevin Le
aeca6f3f3f Added "override" to getIRQGpio() for ESP32Board.h 2026-06-03 14:10:28 +07:00
Jakub
e578525a95 fix(nav): drop nav view when target contact disappears; cap label entry
Review fixes:
- NearbyScreen: when the periodic detail refresh can't find the selected
  contact any more, clear _nav as well as _detail so the nav view and the
  input handler don't disagree about state.
- TrailScreen: bound the label keyboard to WAYPOINT_LABEL_LEN-1 (11) chars
  for both Mark-here and Rename, so the user can't type more than the stored
  label holds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:36:41 +02:00
Jakub
6ca1c766ef feat(nav): navigate to a node from Nearby
Phase 6. In a node's detail view, Enter (when the ping popup is closed)
opens the shared NavView targeting that node's last-known advert position
— same To/Hdg/distance screen used by waypoints. Nodes with no position
report "No node GPS". This turns Nearby from a static snapshot into a
"walk toward this person" view and folds in the old compass-to-contact idea.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:32:32 +02:00
Jakub
6f7647481a feat(nav): draw waypoints on the trail map
Phase 5b. The Map view now overlays saved waypoints as a hollow-diamond
marker with the label's first character beside it. The bounding box folds
in every waypoint so off-track ones stay in frame, and the map renders
even when the trail is empty but waypoints exist. project() generalised to
projectLL(lat, lon) so the same projection draws track points and waypoints.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:30:16 +02:00
Jakub
99bfcb1bd7 feat(nav): waypoints in Trail — mark, list, navigate
Phase 5a. Trail → Hold Enter gains two rows:
- "Mark here": captures the current GPS fix and opens the keyboard for a
  short label (empty → auto "WP<n>"); saved to the persistent table.
- "Waypoints" (shown when any exist): a list of saved waypoints with live
  distance. Enter opens the shared NavView (To/Hdg/distance); Hold Enter
  offers Rename / Delete.

All waypoint sub-screens layer over the trail views via _wp_mode and are
dismissed with Cancel. Map overlay comes next (5b).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:28:15 +02:00
Jakub
12e47ea044 feat(nav): shared NavView — two-bearing navigate-to-point render helper
Phase 4. Header-only navview::draw() takes a target (lat, lon, label) plus
the caller's own fix and course-over-ground, and renders distance + two
absolute bearings (To / Hdg). Source-agnostic so Waypoints, Backtrack and
Nearby node nav all reuse it. Not wired in yet (phases 5-6).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:23:59 +02:00
Jakub
b1dfde5fcb feat(nav): WaypointStore — persistent /waypoints table
Phase 3. Fixed 16-entry table of (lat, lon, ts, label[12]) persisted to
/waypoints with a magic+version header (mirrors TrailStore's format).
Unlike the RAM-only trail, waypoints are loaded in UITask::begin() and
rewritten on change via UITask::saveWaypoints(), so they survive reboots.

add/remove/rename/clear operate on the in-RAM table; the screen layer
(phase 5) drives persistence after each edit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:23:11 +02:00
Jakub
11c0b7c4a5 feat(nav): course-over-ground ring in UITask (compass without magnetometer)
Phase 2. A 5-fix GPS ring sampled every ~1 s in UITask::loop, filled
whenever there's a valid fix — independent of trail recording, so the
heading is available to navigation at all times, not only while logging
a trail.

- pushCogFix() rejects gross outliers (a fix implying > 50 m/s since the
  previous one) so a single bad GPS reading can't swing the heading.
- currentCourse(deg) returns the bearing across the window (oldest→newest)
  once the window spans ≥ 6 m of real movement; below that it holds the
  last good heading, and returns false only until the first valid heading
  exists. This is the "two absolute bearings (To / Hdg)" heading source
  for the upcoming nav view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 08:20:59 +02:00
Sefinek
81510e7495 docs: fix remaining rendering issues 2026-06-03 00:38:53 +02:00
Sefinek
4dcd664363 docs: fix remaining rendering issues 2026-06-03 00:32:25 +02:00
Sefinek
4f4699ab61 docs: fix remaining rendering issues 2026-06-03 00:28:09 +02:00
Sefinek
f7bff44572 docs: fix remaining rendering issues 2026-06-03 00:24:01 +02:00
Sefinek
456e14f7a7 docs: add missing periods at sentence endings 2026-06-03 00:15:26 +02:00
Sefinek
15913d580f docs: fix FAQ rendering 2026-06-03 00:14:29 +02:00
Sefinek
3daa6adc83 docs: fix FAQ heading capitalization 2026-06-02 23:57:50 +02:00
Jakub
acec8e94dd refactor(geo): lift bearing/haversine/fmtDist into shared GeoUtils.h
Phase 1 of the navigation feature. The geographic helpers were private
statics in NearbyScreen; move them to a header-inline geo:: namespace so
the upcoming Waypoints / course-over-ground code can reuse them. NearbyScreen
keeps thin forwarders so its call sites are unchanged. No behaviour change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:51:08 +02:00
Jakub
e019afcfc0 docs(features): waypoints + node navigation design (compass via GPS COG) 2026-06-02 23:49:21 +02:00
Sefinek
6b5cf1a9d7 docs: fix FAQ link rendering 2026-06-02 23:48:28 +02:00
Sefinek
1422f02cd3 docs: fix FAQ rendering 2026-06-02 23:35:02 +02:00
Jakub
5b25d1eb32 feat(ui/clock): stacked big-digit clock on portrait e-ink
On a tall portrait e-ink panel the clock and lock screens wasted most of
the vertical space on a small inline "HH:MM". Render HH and MM on two
lines in a new size-4 font (built-in GFX scaled 7×, ~42×56 px) so the
digits roughly double in height and fill the narrow width. Wide panels
(OLED, landscape e-ink) keep the classic single-line size-2 layout.

- New shared drawClockTime() helper used by both the Clock home page and
  the lock screen; returns the y below the time block so the date and
  dashboard rows flow beneath it.
- GxEPDDisplay: size 4 = built-in font × BIG_TEXT_SCALE (7); getCharWidth /
  getLineHeight / setTextSize handle it; fontAscender stays 0 (built-in is
  top-left origin).
- Centre the big digits on their visible glyph width — the built-in font
  advances 6 px per char but the glyph is 5 px wide, so getTextWidth over-
  reports by one trailing column and the digits would sit ~half a column
  left of centre. AM/PM rendered one size larger (size 2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:32:27 +02:00
Sefinek
f9a0f215c4 docs: fix FAQ resource link rendering 2026-06-02 23:31:25 +02:00
Sefinek
e0a6fd12b5 docs: fix FAQ bullet list rendering 2026-06-02 22:34:38 +02:00
Sefinek
4749a61bb4 docs: fix FAQ bullet list rendering 2026-06-02 22:30:42 +02:00
Sefinek
bf39919f15 docs: remove extra FAQ TOC indentation 2026-06-02 22:28:15 +02:00
Jakub
49536cb3a5 Merge remote-tracking branch 'upstream/main' into wio-unified 2026-06-02 22:14:33 +02:00
Sefinek
cc05ae555a docs: fix typos, grammar, and formatting in FAQ and code comments 2026-06-02 22:12:18 +02:00
Sefinek
82560ede55 chore: normalize board JSON line endings 2026-06-02 15:34:00 +02:00
Liam Cottle
add18d6866 Merge pull request #2641 from sefinek/ci/update-github-actions
ci: update GitHub Actions and Python version
2026-06-03 01:26:35 +12:00