feat(companion): live location sharing via [LOC] messages

Share and track positions over the mesh through chat messages, separate
from (and parallel to) the 0-hop auto-advert.

Receive / tracking:
- geo::parseLocShare + [LOC] tag (sibling to [WAY]); LiveTrackStore (16
  slots, DM=pubkey/verified, channel=name/best-effort, 20-min expiry).
- MyMesh parses [LOC] on DM + channel receive → UITask live-track table.
- NearbyScreen overlays shares onto contacts (fresher pin) and lists
  non-contact senders; markers (*=DM, ~=chan) + "Loc:" age/verified line.

Send:
- Map menu "Share my pos" (one-shot) → Messages recipient picker.
- New Tools > Live Share tool: Receive (Track loc) + Send (Auto, Target,
  Move/Min gap/Heartbeat, Share now). Target chosen via the Messages
  picker (channel/DM). Movement-gated auto-send engine in UITask loop.

Map / navigation:
- Trail map shows tracked contacts as ◆ markers (ICON_MAP_CONTACT).
- Home "Map" page: mini-map preview + status line; ENTER opens the tool,
  Cancel returns Home.

Prefs: track_shared_loc + loc_share_* (NodePrefs schema 0xC0DE0012).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MarekZegare4
2026-06-22 10:13:09 +02:00
co-authored by Claude Opus 4.8
parent 29deaaad44
commit d78e74d4cd
14 changed files with 816 additions and 21 deletions
@@ -63,5 +63,11 @@ public:
virtual void notify(UIEventType t = UIEventType::none) = 0;
virtual void addChannelMsg(uint8_t channel_idx, const char* text) {}
virtual void addDMMsg(const uint8_t* pub_key, bool outgoing, const char* text, uint32_t sender_timestamp = 0) {}
// A node shared its current position via a [LOC] message. pub_key is the
// sender's key prefix for a verified DM share, or null for a channel share
// (keyed by name, best-effort). Default no-op so UI variants opt in.
virtual void onSharedLocation(const uint8_t* pub_key, const char* name,
int32_t lat_1e6, int32_t lon_1e6,
uint32_t ts, bool verified) {}
virtual void loop() = 0;
};