mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-06 20:26:12 +00:00
fix(ui,bot): resolve remaining findings from the 2026-07-26 screen review
- DM/room unread badges could claim messages the ring no longer held
(same class as the channel fix in 6470afaf, not covered by it):
getDMUnread()/getDMUnreadTotal() now clamp to dmHistCountForContact(),
and a new reconcileDMUnread() (called once per loop()) frees any
_dm_unread_table slot whose ring occupancy has dropped to 0, so a
17th sender isn't starved by stale entries. onContactRemoved() now
also clears _dm_unread_table -- the one per-contact table it was
missing.
- Shift didn't capitalise ł/ń/ź/ż (+ĺ/ľ/ň/ž): the Latin Extended-A
case-pairing rule assumed a single parity for the whole block, but it
flips around the unpaired codepoints ĸ/ʼn/Ÿ. Fixed with four
sub-ranges, verified exhaustively over U+0100-U+017F.
- Triple-click could still toggle the buzzer while locked on
PIN_USER_BTN/PIN_USER_BTN_ANA boards (joystick path already guarded
this).
- millis() wraparound: 4 absolute comparisons in UITask.cpp (battery
poll, auto-off, lock-wake, backlight) converted to the existing
(int32_t)(millis()-deadline)>=0 idiom; MyMeshBot.h's DM-throttle
eviction now picks the oldest slot by elapsed time instead of raw
t_ms, which picked the wrong slot right after a rollover.
- Long-press bypassed checkDisplayOn() on all 5 call sites -- neither
woke the display nor extended auto-off, and could deliver
KEY_CONTEXT_MENU to the invisible screen. Moved the gate inside
handleLongPress() itself instead of patching each site.
- CardKB's backspace/printable-insert branches didn't reset t9_cell,
so typing right after a T9 cycle tap could get silently overwritten
by a same-cell re-tap within the T9 timeout.
- buildContactList()'s counts[MAX_CONTACTS] was a 1400 B int array on
the 4 KB loop() stack; values are bounded by DM_HIST_MAX (32), so
now uint8_t.
- ACK table treated ack==0 as a wildcard: isAckPending(0) matched any
free slot, and processAck() with an all-zero ACK matched the first
free slot and returned its stale contact pointer. Both now skip/reject
ack==0, and the matched slot's contact pointer is cleared alongside
its ack hash.
- ensurePageOrderInit() could write one byte past page_order[13] when
migrating a saved order with all 13 slots full and CLOCK last --
guarded on insert_at < PAGE_ORDER_LEN.
Two findings from the same review were resolved as no-op decisions,
not code changes: !buzz over DM ignoring quiet hours is intentional
(the pull exemption is meant to cover the buzzer), and the offline
queue's full-queue drop-newest behaviour is upstream code, left alone.
Build-verified green on WioTrackerL1_companion_solo_dual (RAM 71.1%,
Flash 66.6%) and WioTrackerL1Eink_companion_solo_dual (RAM 73.0%,
Flash 67.9%).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -363,18 +363,20 @@ public:
|
||||
int getChannelUnreadCount() const;
|
||||
int getRoomUnreadCount() const { return _room_unread; }
|
||||
void clearRoomUnread() { _room_unread = 0; }
|
||||
uint8_t getDMUnread(const uint8_t* pub_key) const {
|
||||
for (int i = 0; i < DM_UNREAD_TABLE_SIZE; i++)
|
||||
if (_dm_unread_table[i].count > 0 && memcmp(_dm_unread_table[i].prefix, pub_key, 4) == 0)
|
||||
return _dm_unread_table[i].count;
|
||||
return 0;
|
||||
}
|
||||
// Clamped to the DM ring's actual occupancy for this contact -- defined in
|
||||
// UITask.cpp (needs MessagesScreen to be a complete type). Same self-healing
|
||||
// shape as MessageHistory::chUnread() for channels.
|
||||
uint8_t getDMUnread(const uint8_t* pub_key) const;
|
||||
void clearDMUnread(const uint8_t* pub_key) {
|
||||
for (int i = 0; i < DM_UNREAD_TABLE_SIZE; i++)
|
||||
if (_dm_unread_table[i].count > 0 && memcmp(_dm_unread_table[i].prefix, pub_key, 4) == 0)
|
||||
{ _dm_unread_table[i].count = 0; return; }
|
||||
}
|
||||
void clearAllDMUnread() { memset(_dm_unread_table, 0, sizeof(_dm_unread_table)); }
|
||||
// Frees any table slot whose ring occupancy has dropped to zero (evicted or
|
||||
// deduped-away messages) so a genuinely new sender isn't starved once the
|
||||
// fixed 16-slot table fills with stale entries. Called once per loop().
|
||||
void reconcileDMUnread();
|
||||
bool hasDisplay() const { return _display != NULL; }
|
||||
DisplayDriver* getDisplay() const { return _display; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user