mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-14 15:16:40 +00:00
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:
@@ -95,9 +95,12 @@ public:
|
|||||||
// that instead of assuming a valid position. path/path_len (packed
|
// that instead of assuming a valid position. path/path_len (packed
|
||||||
// (hash_size-1)<<6|hop_count, same as mesh::Packet::path_len) is the hop
|
// (hash_size-1)<<6|hop_count, same as mesh::Packet::path_len) is the hop
|
||||||
// route this incoming post actually took -- nullptr/0 when not known (e.g.
|
// route this incoming post actually took -- nullptr/0 when not known (e.g.
|
||||||
// this is our own outgoing post).
|
// this is our own outgoing post). own_message: our own post (e.g. mirrored
|
||||||
|
// from an app-originated send) -- never counted unread, unlike a genuinely
|
||||||
|
// incoming post the device's own UI doesn't happen to be showing right now.
|
||||||
virtual int addChannelMsg(uint8_t channel_idx, const char* text, uint32_t timestamp = 0,
|
virtual int addChannelMsg(uint8_t channel_idx, const char* text, uint32_t timestamp = 0,
|
||||||
const uint8_t* path = nullptr, uint8_t path_len = 0) { return -1; }
|
const uint8_t* path = nullptr, uint8_t path_len = 0,
|
||||||
|
bool own_message = false) { return -1; }
|
||||||
// Arms the "relayed into mesh" tracker (a heard repeater rebroadcast) on the
|
// Arms the "relayed into mesh" tracker (a heard repeater rebroadcast) on the
|
||||||
// entry at ring position pos, e.g. right after addChannelMsg for a channel
|
// entry at ring position pos, e.g. right after addChannelMsg for a channel
|
||||||
// send this device just originated. seq: MyMesh::lastChannelRelaySeq().
|
// send this device just originated. seq: MyMesh::lastChannelRelaySeq().
|
||||||
|
|||||||
@@ -2033,7 +2033,11 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||||||
int tlen = len - i;
|
int tlen = len - i;
|
||||||
if (tlen > MAX_TEXT_LEN) tlen = MAX_TEXT_LEN;
|
if (tlen > MAX_TEXT_LEN) tlen = MAX_TEXT_LEN;
|
||||||
snprintf(entry, sizeof(entry), "Me: %.*s", tlen, text);
|
snprintf(entry, sizeof(entry), "Me: %.*s", tlen, text);
|
||||||
int pos = _ui->addChannelMsg(channel_idx, entry, msg_timestamp);
|
// own_message=true: this is our own post, so it must never bump the
|
||||||
|
// channel's unread badge even though the device's own UI isn't
|
||||||
|
// necessarily showing this channel right now (unlike an on-device
|
||||||
|
// compose, which is always looking at the channel it just sent to).
|
||||||
|
int pos = _ui->addChannelMsg(channel_idx, entry, msg_timestamp, nullptr, 0, true);
|
||||||
// Same "relayed into mesh" marker an on-device channel send arms (see
|
// Same "relayed into mesh" marker an on-device channel send arms (see
|
||||||
// MessagesScreen::afterSend): sendGroupMessage above already went
|
// MessagesScreen::afterSend): sendGroupMessage above already went
|
||||||
// through sendFloodScoped(GroupChannel&, ...), which calls
|
// through sendFloodScoped(GroupChannel&, ...), which calls
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ void MyMesh::tryBotReplyChannel(uint8_t channel_idx, const char* text, uint8_t h
|
|||||||
if (_ui) {
|
if (_ui) {
|
||||||
char with_sender[240]; // node_name(32) + ": "(2) + expanded(200) + margin
|
char with_sender[240]; // node_name(32) + ": "(2) + expanded(200) + margin
|
||||||
snprintf(with_sender, sizeof(with_sender), "%s: %s", _prefs.node_name, expanded);
|
snprintf(with_sender, sizeof(with_sender), "%s: %s", _prefs.node_name, expanded);
|
||||||
_ui->addChannelMsg(channel_idx, with_sender);
|
_ui->addChannelMsg(channel_idx, with_sender, 0, nullptr, 0, true); // own_message: our own bot reply, never unread
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -499,7 +499,7 @@ bool MyMesh::tryBotChannelCommand(uint8_t channel_idx, const char* text, uint8_t
|
|||||||
if (_ui) {
|
if (_ui) {
|
||||||
char with_sender[240];
|
char with_sender[240];
|
||||||
snprintf(with_sender, sizeof(with_sender), "%s: %s", _prefs.node_name, out);
|
snprintf(with_sender, sizeof(with_sender), "%s: %s", _prefs.node_name, out);
|
||||||
_ui->addChannelMsg(channel_idx, with_sender);
|
_ui->addChannelMsg(channel_idx, with_sender, 0, nullptr, 0, true); // own_message: our own bot reply, never unread
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (_locfix_requested) startLocFix(LOCFIX_DEST_CHANNEL, nullptr, channel_idx);
|
if (_locfix_requested) startLocFix(LOCFIX_DEST_CHANNEL, nullptr, channel_idx);
|
||||||
@@ -658,7 +658,7 @@ void MyMesh::sendLocFixResult(const char* msg) {
|
|||||||
if (_ui) {
|
if (_ui) {
|
||||||
char with_sender[240];
|
char with_sender[240];
|
||||||
snprintf(with_sender, sizeof(with_sender), "%s: %s", _prefs.node_name, msg);
|
snprintf(with_sender, sizeof(with_sender), "%s: %s", _prefs.node_name, msg);
|
||||||
_ui->addChannelMsg(_loc_fix.channel_idx, with_sender);
|
_ui->addChannelMsg(_loc_fix.channel_idx, with_sender, 0, nullptr, 0, true); // own_message: our own bot reply, never unread
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,8 +101,15 @@ public:
|
|||||||
// path/path_len_packed: the hop path this incoming post actually took (from
|
// 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
|
// 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 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,
|
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
|
// 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
|
// 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.
|
// 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);
|
if (path && path_len_packed) capturePath(_hist[pos].path_len, _hist[pos].path, path, path_len_packed);
|
||||||
else _hist[pos].path_len = 0;
|
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;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -735,9 +735,10 @@ public:
|
|||||||
// (a phase-machine fact the store can't see) and returns the ring position so
|
// (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.
|
// 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,
|
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);
|
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
|
// 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
|
// 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
|
// up to an older message (_hist_sel > 0), re-point the selection at that
|
||||||
|
|||||||
@@ -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,
|
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;
|
_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) {
|
void UITask::armChannelRelay(int pos, uint32_t seq) {
|
||||||
|
|||||||
@@ -386,7 +386,8 @@ public:
|
|||||||
bool isMelodyPlaying();
|
bool isMelodyPlaying();
|
||||||
void showAlert(const char* text, int duration_millis);
|
void showAlert(const char* text, int duration_millis);
|
||||||
int addChannelMsg(uint8_t channel_idx, const char* text, uint32_t timestamp = 0,
|
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 armChannelRelay(int pos, uint32_t seq) override;
|
||||||
void addDMMsg(const uint8_t* pub_key, bool outgoing, const char* text, uint32_t sender_timestamp = 0,
|
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,
|
uint32_t ack_tag = 0, uint32_t ack_deadline_ms = 0, uint8_t resends = 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user