From 1f47fc56cdf1398c85b144faf21937ad04e4c46e Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Thu, 15 Oct 2026 18:41:18 +0200 Subject: [PATCH] fix(route): a stored route longer than the editor's 7 hops can't be saved cut short Co-Authored-By: Claude Opus 5.5 --- examples/companion_radio/ui-core/PathEditor.h | 11 +++++++++-- examples/companion_radio/ui-lvgl/RouteScreen.h | 2 +- examples/companion_radio/ui-new/NearbyScreen.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/companion_radio/ui-core/PathEditor.h b/examples/companion_radio/ui-core/PathEditor.h index 85ea4c0e..846fedfe 100644 --- a/examples/companion_radio/ui-core/PathEditor.h +++ b/examples/companion_radio/ui-core/PathEditor.h @@ -62,9 +62,11 @@ public: _links = 0; _stored = c->out_path_len != OUT_PATH_UNKNOWN; _pinned = _stored && (c->flags & CONTACT_FLAG_ROUTE_PINNED) != 0; + _too_long = false; if (_stored) { uint8_t size = (c->out_path_len >> 6) + 1; uint8_t cnt = c->out_path_len & 63; + _too_long = cnt > MAX_HOPS; for (uint8_t i = 0; i < cnt && _n < MAX_HOPS; i++) loadHash(&c->out_path[i * size], size); } _edited = false; @@ -247,10 +249,13 @@ public: // The list as the contact's stored route; an empty list stores "direct" // (no repeaters, sent straight to the node). False when the hops share no // usable width. - bool canSave() const { return saveWidth() > 0; } + // A stored route longer than MAX_HOPS loads only its first hops; saving it + // would cut it short, so it can't be saved until its hops are all removed. + bool tooLong() const { return _too_long; } + bool canSave() const { return !_too_long && saveWidth() > 0; } bool save() { uint8_t w = saveWidth(); - if (w == 0) return false; + if (w == 0 || _too_long) return false; uint8_t path[MAX_HOPS * 3]; for (int i = 0; i < _n; i++) memcpy(&path[i * w], _hops[i].key, w); if (!the_mesh.setContactPath(_target_key, path, w, (uint8_t)_n, _pinned)) return false; @@ -271,6 +276,7 @@ private: void changed() { _edited = true; + if (_n == 0) _too_long = false; // emptied: what's saved now is the user's own list invalidate(); } @@ -369,6 +375,7 @@ private: State _state = IDLE; Fail _fail = FAIL_NONE; bool _stored = false; + bool _too_long = false; // the stored route has more hops than the list holds bool _pinned = false; bool _edited = false; bool _probe = false; diff --git a/examples/companion_radio/ui-lvgl/RouteScreen.h b/examples/companion_radio/ui-lvgl/RouteScreen.h index 9fde1db9..cde12540 100644 --- a/examples/companion_radio/ui-lvgl/RouteScreen.h +++ b/examples/companion_radio/ui-lvgl/RouteScreen.h @@ -294,7 +294,7 @@ void UITask::routeAct(uint8_t act) { routeKeep(); break; case routeview::RT_SAVE: - if (!R.save()) { showToast("Can't save this route"); break; } + if (!R.save()) { showToast(R.tooLong() ? "Too long to edit - remove all hops first" : "Can't save this route"); break; } showToast(R.count() ? (R.pinned() ? "Route saved and kept" : "Route saved") : "Saved: direct to the node"); routeRebuild(); break; diff --git a/examples/companion_radio/ui-new/NearbyScreen.h b/examples/companion_radio/ui-new/NearbyScreen.h index bff7333a..e47b5acd 100644 --- a/examples/companion_radio/ui-new/NearbyScreen.h +++ b/examples/companion_radio/ui-new/NearbyScreen.h @@ -216,7 +216,7 @@ public: break; case R_TO_NODE: r.setToNode(!r.toNode()); break; case R_SAVE: - if (!r.save()) _task->showAlert("Can't save", 1000); + if (!r.save()) _task->showAlert(r.tooLong() ? "Too long to edit" : "Can't save", 1000); else _task->showAlert(r.count() ? "Path saved" : "Saved: direct", 1000); break; case R_KEEP: toggleKeep(); break;