From b57e000496d2e05eeeea6fe067b34ee528c685c2 Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Sun, 19 Apr 2026 20:41:06 +1000 Subject: [PATCH] =?UTF-8?q?fix:=20remove=20BLE=20sync=20marking=20channels?= =?UTF-8?q?=20as=20read=20(regression=20from=20Feb).=20The=20markChannelRe?= =?UTF-8?q?adFromBLE()=20calls=20in=20the=20CMD=5FSYNC=5FNEXT=5FMESSAGE=20?= =?UTF-8?q?handler=20were=20marking=20channels=20and=20DMs=20as=20read=20t?= =?UTF-8?q?he=20moment=20the=20BLE=20companion=20app=20synced=20them=20fro?= =?UTF-8?q?m=20the=20offline=20queue.=20Since=20the=20app=20drains=20the?= =?UTF-8?q?=20entire=20queue=20automatically=20on=20connect,=20this=20had?= =?UTF-8?q?=20the=20effect=20of=20clearing=20all=20unread=20indicators=20o?= =?UTF-8?q?n=20the=20device=20as=20soon=20as=20BLE=20connected=20=E2=80=94?= =?UTF-8?q?=20before=20the=20user=20had=20actually=20read=20anything=20in?= =?UTF-8?q?=20either=20the=20app=20or=20on=20the=20device.=20The=20MeshCor?= =?UTF-8?q?e=20BLE=20protocol=20has=20no=20"user=20opened=20this=20channel?= =?UTF-8?q?"=20command=20from=20the=20app=20side;=20CMD=5FSYNC=5FNEXT=5FME?= =?UTF-8?q?SSAGE=20is=20an=20automatic=20bulk=20pull,=20so=20"synced=20to?= =?UTF-8?q?=20app"=20=E2=89=A0=20"read=20by=20user."=20Removed=20the=20cha?= =?UTF-8?q?nnel=20and=20DM=20mark-read=20calls=20so=20unread=20counts=20on?= =?UTF-8?q?ly=20clear=20when=20the=20user=20navigates=20to=20that=20channe?= =?UTF-8?q?l=20on=20the=20device=20itself.=20The=20msgRead()=20progress=20?= =?UTF-8?q?counter=20(syncing=20X=20messages)=20is=20unaffected.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/companion_radio/MyMesh.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index ef0542cb..8cd1cd3c 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1772,23 +1772,12 @@ void MyMesh::handleCmdFrame(size_t len) { #ifdef DISPLAY_CLASS if (_ui) { _ui->msgRead(offline_queue_len); - - // Mark channel as read when BLE companion app syncs the message. - // Frame layout V3: [resp_code][snr][res1][res2][channel_idx][path_len]... - // Frame layout V1: [resp_code][channel_idx][path_len]... - bool is_v3_ch = (out_frame[0] == RESP_CODE_CHANNEL_MSG_RECV_V3); - bool is_old_ch = (out_frame[0] == RESP_CODE_CHANNEL_MSG_RECV); - if (is_v3_ch || is_old_ch) { - uint8_t ch_idx = is_v3_ch ? out_frame[4] : out_frame[1]; - _ui->markChannelReadFromBLE(ch_idx); - } - - // Mark DM slot read when companion app syncs a contact (DM/room) message - bool is_v3_dm = (out_frame[0] == RESP_CODE_CONTACT_MSG_RECV_V3); - bool is_old_dm = (out_frame[0] == RESP_CODE_CONTACT_MSG_RECV); - if (is_v3_dm || is_old_dm) { - _ui->markChannelReadFromBLE(0xFF); - } + // Note: we intentionally do NOT mark channels/DMs as read here. + // CMD_SYNC_NEXT_MESSAGE fires during the automatic bulk sync when + // the BLE app connects — "synced to app" ≠ "read by user in app". + // Unread counts only clear when the user navigates to that channel + // on the device itself. The MeshCore BLE protocol has no "mark as + // read" command from the app side, so this is the safest behaviour. } #endif } else {