fix(companion): arm the "Relayed by" tracker for bot-originated channel posts

Remote Bot's channel trigger reply, channel command reply, and !gps fix
result all mirrored their send into the on-device history with
addOwnChannelMsg() but never called armChannelRelay() afterward, unlike
the app's CMD_SEND_CHANNEL_TXT_MSG send which already did both -- so a
bot's own channel posts never showed which repeaters echoed them back,
while everything else did.

Factor the always-together pair (mirror into history, then arm relay
tracking from the send sendGroupMessage's sendFloodScoped already
tracked) into MyMesh::mirrorOwnChannelMsg(), and route all four call
sites through it instead of pairing the two calls by hand -- the bot
bug was exactly a dropped second call, so a new call site can no longer
add the first half without the second.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-09-09 16:22:04 +02:00
co-authored by Claude Sonnet 5
parent 42afd180f9
commit 6e0e981048
3 changed files with 24 additions and 16 deletions
+5 -13
View File
@@ -2039,19 +2039,11 @@ void MyMesh::handleCmdFrame(size_t len) {
// 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).
if (_ui) {
int tlen = len - i;
if (tlen > MAX_TEXT_LEN) tlen = MAX_TEXT_LEN;
int pos = _ui->addOwnChannelMsg(channel_idx, text, tlen, msg_timestamp);
// Same "relayed into mesh" marker an on-device channel send arms (see
// MessagesScreen::afterSend): sendGroupMessage above already went
// through sendFloodScoped(GroupChannel&, ...), which calls
// trackRelaySend() unconditionally, so lastChannelRelaySeq() is
// already the seq for the send that was just made -- this just
// attaches it to the matching history entry.
if (pos >= 0) _ui->armChannelRelay(pos, lastChannelRelaySeq());
}
// channel it just sent to). mirrorOwnChannelMsg also arms the
// "Relayed by" tracker on the new entry -- see its own comment.
int tlen = len - i;
if (tlen > MAX_TEXT_LEN) tlen = MAX_TEXT_LEN;
mirrorOwnChannelMsg(channel_idx, text, tlen, msg_timestamp);
#endif
} else {
writeErrFrame(ERR_CODE_NOT_FOUND); // bad channel_idx
+16
View File
@@ -228,6 +228,22 @@ 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; }
// Mirror a channel post this device just originated (sendGroupMessage
// already succeeded) into the on-device history AND arm its "Relayed by"
// tracker in one call -- every caller (CMD_SEND_CHANNEL_TXT_MSG, the three
// Remote Bot reply/command/locfix paths) needs both, always in this order,
// and a caller that adds the history entry without arming the tracker
// right after (an easy line to forget) silently never shows repeater
// confirmations for that message. sendGroupMessage's sendFloodScoped(
// GroupChannel&, ...) already calls trackRelaySend() unconditionally, so
// lastChannelRelaySeq() is already the seq for the send just made.
int mirrorOwnChannelMsg(uint8_t channel_idx, const char* text, int text_len = -1, uint32_t timestamp = 0) {
if (!_ui) return -1;
int pos = _ui->addOwnChannelMsg(channel_idx, text, text_len, timestamp);
if (pos >= 0) _ui->armChannelRelay(pos, lastChannelRelaySeq());
return pos;
}
private:
// DataStoreHost methods
+3 -3
View File
@@ -199,7 +199,7 @@ void MyMesh::tryBotReplyChannel(uint8_t channel_idx, const char* text, uint8_t h
_bot_last_ch_reply_ms = millis();
_bot_reply_count++;
#ifdef DISPLAY_CLASS
if (_ui) _ui->addOwnChannelMsg(channel_idx, expanded);
mirrorOwnChannelMsg(channel_idx, expanded);
#endif
}
}
@@ -492,7 +492,7 @@ bool MyMesh::tryBotChannelCommand(uint8_t channel_idx, const char* text, uint8_t
_bot_last_ch_reply_ms = millis();
_bot_reply_count++;
#ifdef DISPLAY_CLASS
if (_ui) _ui->addOwnChannelMsg(channel_idx, out);
mirrorOwnChannelMsg(channel_idx, out);
#endif
if (_locfix_requested) startLocFix(LOCFIX_DEST_CHANNEL, nullptr, channel_idx);
applyPendingBotActions();
@@ -647,7 +647,7 @@ void MyMesh::sendLocFixResult(const char* msg) {
_bot_last_ch_reply_ms = millis();
_bot_reply_count++;
#ifdef DISPLAY_CLASS
if (_ui) _ui->addOwnChannelMsg(_loc_fix.channel_idx, msg);
mirrorOwnChannelMsg(_loc_fix.channel_idx, msg);
#endif
}
} else { // LOCFIX_DEST_CONTACT -- DM or room, both go through sendMessage