fix(mesh): don't mark our own channel post as unread

An app-originated channel send (mirrored into the on-device history)
bumped that channel's unread badge whenever the device's own UI
wasn't already showing that exact channel -- unlike an on-device
compose, which sidesteps this by forcing itself into that channel's
view right before sending. Adds an explicit own_message flag through
addChannelMsg (MessageHistory -> AbstractUITask -> UITask ->
MessagesScreen) so an own post is never counted unread regardless of
what's on screen when it's sent.

Found the same bug in MyMeshBot.h's three auto-reply-into-channel call
sites (Remote Bot's own reply showing as unread on itself) and fixed
those with the same mechanism.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-08-30 20:26:57 +02:00
co-authored by Claude Sonnet 5
parent bdd2ed379d
commit ba3c3cc91f
7 changed files with 29 additions and 13 deletions
@@ -101,8 +101,15 @@ public:
// path/path_len_packed: the hop path this incoming post actually took (from
// the received mesh::Packet), or nullptr/0 when not known (e.g. this is our
// own outgoing post, before any relay echo has arrived).
// own_message: this is our own post (e.g. mirrored from an app-originated
// send) -- never counted unread, regardless of `viewing`. An on-device
// compose already forces `viewing` true itself (it's necessarily looking at
// the channel it just sent to), so this only matters for a send the device's
// own UI wasn't necessarily showing at the time -- otherwise our own sent
// message could bump the very badge it's supposed to leave alone.
int addChannelMsg(uint8_t ch_idx, const char* text, bool viewing, uint32_t timestamp = 0,
const uint8_t* path = nullptr, uint8_t path_len_packed = 0) {
const uint8_t* path = nullptr, uint8_t path_len_packed = 0,
bool own_message = false) {
// Guard against bogus channel indices (e.g. findChannelIdx() returned -1
// and was cast to uint8_t → 255). Storing such an entry would burn a ring
// slot for a message that no visible channel can ever surface.
@@ -135,7 +142,7 @@ public:
if (path && path_len_packed) capturePath(_hist[pos].path_len, _hist[pos].path, path, path_len_packed);
else _hist[pos].path_len = 0;
if (!viewing && _ch_unread[ch_idx] < 99) _ch_unread[ch_idx]++;
if (!viewing && !own_message && _ch_unread[ch_idx] < 99) _ch_unread[ch_idx]++;
return pos;
}
@@ -735,9 +735,10 @@ public:
// (a phase-machine fact the store can't see) and returns the ring position so
// the outgoing path can attach a relay seq to that exact entry.
int addChannelMsg(uint8_t ch_idx, const char* text, uint32_t timestamp = 0,
const uint8_t* path = nullptr, uint8_t path_len = 0) {
const uint8_t* path = nullptr, uint8_t path_len = 0,
bool own_message = false) {
bool viewing = (_phase == CHANNEL_HIST && _sel_channel_idx == (int)ch_idx);
int pos = _history.addChannelMsg(ch_idx, text, viewing, timestamp, path, path_len);
int pos = _history.addChannelMsg(ch_idx, text, viewing, timestamp, path, path_len, own_message);
// Ring entries are numbered newest-first (0 == newest), so a new insert
// shifts every older message's index up by one. If the user has scrolled
// up to an older message (_hist_sel > 0), re-point the selection at that
+2 -2
View File
@@ -1767,9 +1767,9 @@ int UITask::getRecentDMContacts(uint8_t out[][NodePrefs::FAVOURITE_PREFIX_LEN],
}
int UITask::addChannelMsg(uint8_t channel_idx, const char* text, uint32_t timestamp,
const uint8_t* path, uint8_t path_len) {
const uint8_t* path, uint8_t path_len, bool own_message) {
_last_notif_ch_idx = (int)channel_idx;
return ((MessagesScreen*)messages_screen)->addChannelMsg(channel_idx, text, timestamp, path, path_len);
return ((MessagesScreen*)messages_screen)->addChannelMsg(channel_idx, text, timestamp, path, path_len, own_message);
}
void UITask::armChannelRelay(int pos, uint32_t seq) {
+2 -1
View File
@@ -386,7 +386,8 @@ public:
bool isMelodyPlaying();
void showAlert(const char* text, int duration_millis);
int addChannelMsg(uint8_t channel_idx, const char* text, uint32_t timestamp = 0,
const uint8_t* path = nullptr, uint8_t path_len = 0) override;
const uint8_t* path = nullptr, uint8_t path_len = 0,
bool own_message = false) override;
void armChannelRelay(int pos, uint32_t seq) override;
void addDMMsg(const uint8_t* pub_key, bool outgoing, const char* text, uint32_t sender_timestamp = 0,
uint32_t ack_tag = 0, uint32_t ack_deadline_ms = 0, uint8_t resends = 0,