diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 09b621d2..22f581a6 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -296,6 +296,13 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no rd(_prefs.page_order, sizeof(_prefs.page_order)); rd(&_prefs.joystick_rotation, sizeof(_prefs.joystick_rotation)); rd(&_prefs.eink_full_refresh_every, sizeof(_prefs.eink_full_refresh_every)); + rd(&_prefs.page_order_set, sizeof(_prefs.page_order_set)); + // Migration: pre-magic firmware wrote page_order without a flag. If we see a plausible + // first entry from such a save, accept it once — savePrefs will then persist the magic. + if (_prefs.page_order_set != NodePrefs::PAGE_ORDER_MAGIC + && _prefs.page_order[0] >= 1 && _prefs.page_order[0] <= 11) { + _prefs.page_order_set = NodePrefs::PAGE_ORDER_MAGIC; + } file.close(); } @@ -376,6 +383,7 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_ file.write((uint8_t *)_prefs.page_order, sizeof(_prefs.page_order)); file.write((uint8_t *)&_prefs.joystick_rotation, sizeof(_prefs.joystick_rotation)); file.write((uint8_t *)&_prefs.eink_full_refresh_every, sizeof(_prefs.eink_full_refresh_every)); + file.write((uint8_t *)&_prefs.page_order_set, sizeof(_prefs.page_order_set)); file.close(); } diff --git a/examples/companion_radio/NodePrefs.h b/examples/companion_radio/NodePrefs.h index e51a2ee4..d3a2328c 100644 --- a/examples/companion_radio/NodePrefs.h +++ b/examples/companion_radio/NodePrefs.h @@ -82,10 +82,13 @@ struct NodePrefs { // persisted to file uint8_t use_lemon_font; // 0=default Adafruit font, 1=Lemon font (Unicode, pixel-accurate wrap) uint8_t display_rotation; // 0-3; only used on e-ink displays // Home screen page order: each byte = bit-index+1 (see HP_* bit positions + 9=Settings, 10=Messages). - // 0 = end of list (also uninitialized legacy). hasCustomOrder iff page_order[0] in 1..11. + // 0 = end of list. Validity gated by page_order_set magic (see below) — not by entry value range, + // so a junk byte in 1..11 cannot trigger custom-order mode. uint8_t page_order[11]; uint8_t joystick_rotation; // 0-3 steps CW; independent of display_rotation uint8_t eink_full_refresh_every; // index into {0,5,10,20,30}: full refresh every N partials (0=off) + uint8_t page_order_set; // 0xA5 = page_order is user-configured; anything else = use default + static const uint8_t PAGE_ORDER_MAGIC = 0xA5; // Bitmasks for home_pages_mask (bit=1 → page visible; 0 field = all visible). static const uint16_t HP_CLOCK = 1 << 0; diff --git a/examples/companion_radio/ui-new/QuickMsgScreen.h b/examples/companion_radio/ui-new/QuickMsgScreen.h index cde19441..75d216d5 100644 --- a/examples/companion_radio/ui-new/QuickMsgScreen.h +++ b/examples/companion_radio/ui-new/QuickMsgScreen.h @@ -1185,10 +1185,17 @@ public: if (res == KeyboardWidget::CANCELLED) { _phase = MSG_PICK; } else if (res == KeyboardWidget::DONE) { - int min_len = _reply_mode ? (int)strlen(_reply_prefix) : 0; - if (_kb.len > min_len) { + int prefix_len = _reply_mode ? (int)strlen(_reply_prefix) : 0; + if (_kb.len > prefix_len) { + // Expand only the body — prefix "@[nick] " is preserved verbatim, so a nick + // that happens to contain a placeholder token isn't substituted. char expanded[KB_MAX_LEN + 1]; - expandMsg(_kb.buf, expanded, sizeof(expanded)); + if (prefix_len > 0) { + memcpy(expanded, _kb.buf, prefix_len); + expandMsg(_kb.buf + prefix_len, expanded + prefix_len, sizeof(expanded) - prefix_len); + } else { + expandMsg(_kb.buf, expanded, sizeof(expanded)); + } bool ok = sendText(expanded); afterSend(ok, expanded); } diff --git a/examples/companion_radio/ui-new/SettingsScreen.h b/examples/companion_radio/ui-new/SettingsScreen.h index 454e10c3..f5591a3a 100644 --- a/examples/companion_radio/ui-new/SettingsScreen.h +++ b/examples/companion_radio/ui-new/SettingsScreen.h @@ -218,7 +218,7 @@ class SettingsScreen : public UIScreen { // Returns 1-based position of item in page_order, or 0 if no custom order / not found. int homePagePosition(int item, const NodePrefs* p) const { - if (!p || p->page_order[0] < 1 || p->page_order[0] > 11) return 0; + if (!p || p->page_order_set != NodePrefs::PAGE_ORDER_MAGIC) return 0; int bit = homePageBitIndex(item); if (bit < 0) return 0; for (int i = 0; i < 11; i++) { @@ -233,7 +233,7 @@ class SettingsScreen : public UIScreen { // Also repairs a partially-initialised order where CLOCK (bit 0, stored as 1) is absent. void ensurePageOrderInit(NodePrefs* p) const { if (!p) return; - if (p->page_order[0] >= 1 && p->page_order[0] <= 11) { + if (p->page_order_set == NodePrefs::PAGE_ORDER_MAGIC) { // Order was previously set — verify CLOCK is present to guard against partial/corrupted data. for (int i = 0; i < 11; i++) { uint8_t v = p->page_order[i]; @@ -261,6 +261,7 @@ class SettingsScreen : public UIScreen { p->page_order[j++] = 10 + 1; // MESSAGES (QUICK_MSG) p->page_order[j++] = 8 + 1; // SHUTDOWN while (j < 11) p->page_order[j++] = 0; + p->page_order_set = NodePrefs::PAGE_ORDER_MAGIC; } // Swaps item's page_order slot with its neighbour in the given direction (-1=earlier, +1=later). diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 4b94d859..d7712efa 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -203,7 +203,7 @@ class HomeScreen : public UIScreen { // Returns count; out[] receives HomePage enum values. int buildVisibleOrder(int* out) const { int n = 0; - bool custom = _node_prefs && _node_prefs->page_order[0] >= 1 && _node_prefs->page_order[0] <= 11; + bool custom = _node_prefs && _node_prefs->page_order_set == NodePrefs::PAGE_ORDER_MAGIC; if (custom) { for (int i = 0; i < 11; i++) { uint8_t v = _node_prefs->page_order[i];