feat(ui): channel "relayed into mesh" marker (✓ on repeater echo)

Channels have no recipient ACK, so true delivery can't be shown. Instead reuse
the heard-repeater-echo idea (same as APC's flood feedback) to mark an outgoing
channel message ✓ once a repeater rebroadcast of it is heard — i.e. it was
relayed into the mesh. No echo is NOT a failure (direct/0-hop neighbours never
echo), so unconfirmed sends simply show no marker.

- MyMesh: single-slot relay tracker independent of APC (trackRelaySend on every
  channel flood; hash-match in filterRecvFloodPacket gated on _relay_pending so
  the hot recv path is untouched otherwise; window expiry in loop just drops it).
  lastChannelRelaySeq() hands the seq to the UI.
- AbstractUITask::onChannelRelayed() -> UITask -> QuickMsgScreen::markChannelRelayed().
- ChHistEntry gains relay_status / relay_seq; afterSend arms the marker on the
  exact stored entry; render shows ✓ only on ACK_OK for our own ("Me:") rows.

Verified: GAT562 (SSD1306) and WioTrackerL1Eink (GxEPD) solo builds compile clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
MarekZegare4
2026-06-14 14:18:51 +02:00
co-authored by Claude Sonnet 4.6
parent 219a2bba5c
commit d064a617e0
6 changed files with 94 additions and 4 deletions
+15
View File
@@ -201,6 +201,12 @@ protected:
void apcSampleSnr(float snr);
void apcOnFailure();
void apcTrackFloodSend(const mesh::Packet* pkt);
void trackRelaySend(const mesh::Packet* pkt); // arm the UI relayed-into-mesh tracker
public:
// Seq of the most recently tracked channel send — the UI records it on the
// outgoing history entry so a heard echo (onChannelRelayed) can match it back.
uint32_t lastChannelRelaySeq() const { return _last_relay_seq; }
private:
// DataStoreHost methods
bool onContactLoaded(const ContactInfo& contact) override { return addContact(contact); }
@@ -291,6 +297,15 @@ private:
uint16_t _apc_flood_len; // its payload length — cheap pre-filter before hashing
uint32_t _apc_flood_deadline; // echo-wait deadline for that send
bool _apc_flood_pending; // a tracked flood send is awaiting its echo
// UI "relayed into mesh" tracker for channel sends — independent of APC, single
// slot (only the latest channel send is tracked). Hashing on receive only runs
// while a send is pending, so the hot flood-recv path is untouched otherwise.
uint8_t _relay_hash[MAX_HASH_SIZE];
uint16_t _relay_len;
uint32_t _relay_deadline;
uint32_t _relay_seq; // monotonic id of the pending tracked send
uint32_t _last_relay_seq; // seq of the most recent tracked send (for the UI to record)
bool _relay_pending;
bool send_unscoped; // force un-scoped flood (instead of using send_scope)
char cli_command[80];
uint8_t app_target_ver;