feat(companion): shared named-scope list, per-channel/repeater popup pickers

Replace the single device-wide Scope text field with a small named list
(wildcard "*" fixed first, plus a movable default): each channel picks one
scope of its own (matching the app's per-channel region picker, surfaced in
the channel-history title), and the repeater's Extra scopes multi-selects
from the same list instead of comma-typed names. Both pickers are popups
(PopupMenu gains addCheckItem()/a fillable-square checkbox glyph) over the
existing screen rather than a full-screen takeover.

Also fixes a stray-bits bug where a pre-existing prefs file's own sentinel
tail could read into the new repeat_extra_scope_mask/ch_scope_idx fields and
silently reappear as a real pick later once the scope list grew into that
range.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-09-12 00:05:40 +02:00
co-authored by Claude Sonnet 5
parent 7533c70ee2
commit 89c02eea27
13 changed files with 592 additions and 90 deletions
+10
View File
@@ -4,6 +4,7 @@
#include <helpers/ContactInfo.h>
#include <helpers/ChannelDetails.h>
#include "NodePrefs.h"
#include "ScopeList.h"
class DataStoreHost {
public:
@@ -45,6 +46,15 @@ public:
// deleted slot is simply absent from the file, not written as empty).
bool loadChannels(DataStoreHost* host);
void saveChannels(DataStoreHost* host);
// /scopes1: the shared named-scope list (see ScopeList.h). `prefs` is only
// read, for a one-time migration of a pre-existing single
// default_scope_name/key into list entry 1 -- the file is authoritative
// once it exists. Returns true if the file existed or the migration ran
// (i.e. `list` reflects real prior configuration); false only means a
// genuinely fresh, unconfigured device (list left at its default: empty,
// default_idx 0 == "*").
bool loadScopeList(ScopeList& list, const NodePrefs& prefs);
void saveScopeList(const ScopeList& list);
void migrateToSecondaryFS();
uint8_t getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]);
bool putBlobByKey(const uint8_t key[], int key_len, const uint8_t src_buf[], uint8_t len);