From 43d989821a5eb98f3a90cd60ba04eac81a458905 Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Sun, 31 May 2026 16:23:07 +0200 Subject: [PATCH] fix(ui/channels): unread badge no longer outlives evicted history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The channel history is a single ring shared by all channels (was 32 entries), while unread counts live in a separate per-channel array. Once 32 messages had accumulated across channels, the oldest entry was evicted on each new message — but the matching _ch_unread[] counter was left untouched. The Messages badge then claimed unread messages the ring could no longer surface, so a channel showed "N unread" but opened empty. (The companion app stores its own copy over the protocol, which is why the phone could still read them.) Two changes: - addChannelMsg() now decrements _ch_unread[evicted.ch_idx] when an entry is pushed out of the ring, keeping the badge consistent with what is actually displayable. - CH_HIST_MAX raised 32 → 96 (~14 KB RAM) so eviction is far less frequent under normal multi-channel traffic. Co-Authored-By: Claude Opus 4.8 --- examples/companion_radio/ui-new/QuickMsgScreen.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/companion_radio/ui-new/QuickMsgScreen.h b/examples/companion_radio/ui-new/QuickMsgScreen.h index 3475c302..b4e6750d 100644 --- a/examples/companion_radio/ui-new/QuickMsgScreen.h +++ b/examples/companion_radio/ui-new/QuickMsgScreen.h @@ -36,7 +36,11 @@ class QuickMsgScreen : public UIScreen { FullscreenMsgView _fs; int _unread_at_entry; // _ch_unread value when entering CHANNEL_HIST int _viewing_max_seen; // highest _hist_sel reached in current session - static const int CH_HIST_MAX = 32; + // Shared ring for all channels combined. Sized to comfortably exceed + // typical inter-visit accumulation; addChannelMsg() decrements the + // matching _ch_unread when an entry is evicted so the badge can't claim + // unread messages that no longer exist in the ring. + static const int CH_HIST_MAX = 96; // KEYBOARD KeyboardWidget _kb; @@ -422,6 +426,12 @@ public: _hist_count++; } else { pos = _hist_head; + // Evicting the oldest entry — drop its share of the unread counter so + // the badge can't claim a message the ring no longer holds. + uint8_t evicted = _hist[pos].ch_idx; + if (evicted < MAX_GROUP_CHANNELS && _ch_unread[evicted] > 0) { + _ch_unread[evicted]--; + } _hist_head = (_hist_head + 1) % CH_HIST_MAX; } _hist[pos].ch_idx = ch_idx;