mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-31 01:08:14 +00:00
feat(companion): widen Locator targeting beyond favourites/live-share
Locator's person target now resolves any known contact's position, not just an active live [LOC] share: locatorDistance() falls back to the contact's last-advertised gps_lat/gps_lon when there's no current live share, so a rarely-updating but stationary node (a repeater, or someone who shared a fix once) still works as a target. LocatorScreen's target picker is widened to match (favourites always offered, plus every other contact with a currently resolvable position), and shows a compact age tag for non-live entries so staleness is visible. Also adds a quick "Set Locator target" action directly from Nearby Nodes' and Waypoints' own popup menus (UITask::setLocatorTarget()), so picking a target doesn't require a detour through Tools > Locator. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2264,12 +2264,19 @@ bool UITask::locatorDistance(float& dist_m, float& radius_m) const {
|
||||
if (!_node_prefs || !_node_prefs->locator_has_target) return false;
|
||||
int32_t tlat, tlon;
|
||||
if (_node_prefs->locator_target_kind == 1) {
|
||||
// Live contact: follow the latest [LOC] position. No recent share → no
|
||||
// distance to evaluate (engine waits rather than using a stale fix).
|
||||
// Live contact: prefer the latest [LOC] position. With no active share —
|
||||
// not everyone keeps live-sharing on — fall back to their last-advertised
|
||||
// position, so a rarely-updating but stationary node (a repeater, or a
|
||||
// contact who simply shared a fix once) still works as a target.
|
||||
const LiveTrackStore::Entry* e =
|
||||
_livetrack.activeByKey(_node_prefs->locator_key, (uint32_t)rtc_clock.getCurrentTime());
|
||||
if (!e) return false;
|
||||
tlat = e->lat_1e6; tlon = e->lon_1e6;
|
||||
if (e) {
|
||||
tlat = e->lat_1e6; tlon = e->lon_1e6;
|
||||
} else {
|
||||
ContactInfo* c = the_mesh.lookupContactByPubKey(_node_prefs->locator_key, NodePrefs::FAVOURITE_PREFIX_LEN);
|
||||
if (!c || (c->gps_lat == 0 && c->gps_lon == 0)) return false;
|
||||
tlat = c->gps_lat; tlon = c->gps_lon;
|
||||
}
|
||||
} else {
|
||||
tlat = _node_prefs->locator_lat_1e6; tlon = _node_prefs->locator_lon_1e6;
|
||||
}
|
||||
@@ -2314,6 +2321,19 @@ void UITask::fireLocator(bool arrived) {
|
||||
playMelody(arrived ? "locarr:d=8,o=6,b=140:c,e,g" : "loclv:d=8,o=6,b=140:g,e,c");
|
||||
}
|
||||
|
||||
void UITask::setLocatorTarget(uint8_t kind, const uint8_t* key, int32_t lat, int32_t lon, const char* name) {
|
||||
if (!_node_prefs) return;
|
||||
_node_prefs->locator_target_kind = kind;
|
||||
if (kind == 1) memcpy(_node_prefs->locator_key, key, NodePrefs::FAVOURITE_PREFIX_LEN);
|
||||
_node_prefs->locator_lat_1e6 = lat;
|
||||
_node_prefs->locator_lon_1e6 = lon;
|
||||
snprintf(_node_prefs->locator_label, sizeof(_node_prefs->locator_label), "%s", name);
|
||||
_node_prefs->locator_has_target = 1;
|
||||
the_mesh.savePrefs();
|
||||
resetLocator();
|
||||
showAlert("Locator target set", 1200);
|
||||
}
|
||||
|
||||
// Homing beeper: while armed with a target and inside the radius, emit a short
|
||||
// tick whose interval shrinks linearly with distance — slow at the edge, rapid
|
||||
// near the centre. Polls distance a few times a second; silent outside the
|
||||
|
||||
Reference in New Issue
Block a user