Clearing a channel drops its unread from the global count

Unread is tracked in-memory in ChatService, keyed by conversation. A
cleared channel's key stayed in that map with its count intact, so the
header badge kept counting messages nobody could read anymore. Route
the clear through set_active so the key's unread is popped before the
slot is wiped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Jean-Pierre MartineauandClaude Sonnet 5 committed 2026-07-12 18:05:19 -04:00
1 parent a52dfc7b12
commit adc0e9f04d
2 files changed
+17

No files matched your search

+2
View File
@@ -679,6 +679,8 @@ async def _clear(ctx: "AppContext", device: Device, slot: ChannelSlot) -> bool:
)
if choice != "clear":
return False
ctx.chat.set_active(slot.conversation.key) # drop its unread before the slot goes away
ctx.chat.set_active(None)
await device.set_channel(slot.idx, "", None) # empty name => the slot reads as unused
ctx.ui.note(f"[warn]cleared channel {slot.name}[/warn]")
return True
+15
View File
@@ -508,6 +508,21 @@ async def test_channel_rows_carry_stats_unread_and_lanes(ctx: AppContext) -> Non
assert label.spans[-1].style == "ok" # …and its newest cell reads as live traffic
async def test_clearing_a_channel_reads_off_its_unread(ctx: AppContext) -> None:
"""Clearing a channel drops its unread from the global total, not just the slot."""
from meshterm.ui.channels import _clear
device = await ctx.device()
await device.set_channel(0, "Ops", bytes(range(16)))
slot = (await read_channel_slots(device))[0]
ctx.chat._unread[slot.conversation.key] = 3 # as the service would after three arrivals
assert ctx.chat.unread_total() == 3
ctx.ui = _ScriptedUi(selects=[], texts=[], dialogs=["clear"])
assert await _clear(ctx, device, slot) is True
assert ctx.chat.unread_total() == 0
async def test_show_key_popup_wraps_values_under_header_labels() -> None:
"""The key popup is labelled blocks, not a table, and long values wrap whole."""
from types import SimpleNamespace