diff --git a/examples/companion_radio/AbstractUITask.h b/examples/companion_radio/AbstractUITask.h index d6d0b7a4..469b85d6 100644 --- a/examples/companion_radio/AbstractUITask.h +++ b/examples/companion_radio/AbstractUITask.h @@ -51,6 +51,7 @@ public: // Mark a channel as read when BLE companion app syncs a message virtual void markChannelReadFromBLE(uint8_t channel_idx) {} + virtual void markAllChannelsRead() {} // Companion builds: zero all unread on app connect // Repeater admin callbacks (from MyMesh) virtual void onAdminLoginResult(bool success, uint8_t permissions, uint32_t server_time) {} diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 90ca2c2d..31bbb371 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1477,6 +1477,11 @@ void MyMesh::handleCmdFrame(size_t len) { MESH_DEBUG_PRINTLN("App %s connected", app_name); _iter_started = false; // stop any left-over ContactsIterator + +#if defined(BLE_PIN_CODE) || defined(MECK_WIFI_COMPANION) + // Companion builds: mark all channels/DMs as read on app connect + if (_ui) _ui->markAllChannelsRead(); +#endif int i = 0; out_frame[i++] = RESP_CODE_SELF_INFO; out_frame[i++] = ADV_TYPE_CHAT; // what this node Advert identifies as (maybe node's pronouns too?? :-) diff --git a/examples/companion_radio/ui-new/ChannelScreen.h b/examples/companion_radio/ui-new/ChannelScreen.h index 125958a1..6158f652 100644 --- a/examples/companion_radio/ui-new/ChannelScreen.h +++ b/examples/companion_radio/ui-new/ChannelScreen.h @@ -336,6 +336,11 @@ public: } } + // Mark all channels + DMs as read (companion app connected) + void markAllRead() { + memset(_unread, 0, sizeof(_unread)); + } + // Get unread count for a specific channel int getUnreadForChannel(uint8_t channel_idx) const { int slot = (channel_idx == 0xFF) ? MAX_GROUP_CHANNELS : channel_idx; diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 8ca80cf6..f609a602 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1451,15 +1451,17 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i ((ChannelScreen *) channel_screen)->addMessage(channel_idx, path_len, from_name, text, path, snr); } - // If user is currently viewing this channel, mark it as read immediately - // (they can see the message arrive in real-time) - if (isOnChannelScreen() && - ((ChannelScreen *) channel_screen)->getViewChannelIdx() == channel_idx) { + // If user is currently viewing this channel on the device, or companion + // app is connected (they'll see it there), mark as read immediately + if ((isOnChannelScreen() && + ((ChannelScreen *) channel_screen)->getViewChannelIdx() == channel_idx) || + hasConnection()) { ((ChannelScreen *) channel_screen)->markChannelRead(channel_idx); } // Per-contact DM unread tracking: find contact index by name - if (channel_idx == 0xFF && _dmUnread) { + // Skip increment when companion app is connected (user sees DMs there) + if (channel_idx == 0xFF && _dmUnread && !hasConnection()) { uint32_t numContacts = the_mesh.getNumContacts(); ContactInfo contact; for (uint32_t ci = 0; ci < numContacts; ci++) { @@ -2797,6 +2799,14 @@ void UITask::markChannelReadFromBLE(uint8_t channel_idx) { _next_refresh = millis() + 200; } +void UITask::markAllChannelsRead() { + ((ChannelScreen *) channel_screen)->markAllRead(); + if (_dmUnread) { + memset(_dmUnread, 0, MAX_CONTACTS * sizeof(uint8_t)); + } + _next_refresh = millis() + 200; +} + bool UITask::hasDMUnread(int contactIdx) const { if (!_dmUnread || contactIdx < 0 || contactIdx >= MAX_CONTACTS) return false; return _dmUnread[contactIdx] > 0; diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index bcb7a809..ea240436 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -301,6 +301,8 @@ public: // Mark channel as read when BLE companion app syncs messages void markChannelReadFromBLE(uint8_t channel_idx) override; + // Mark all channels + DMs as read (companion app connected) + void markAllChannelsRead() override; // Repeater admin callbacks void onAdminLoginResult(bool success, uint8_t permissions, uint32_t server_time) override;