diff --git a/meshterm/ui/channels.py b/meshterm/ui/channels.py index 553866f..2e928b3 100644 --- a/meshterm/ui/channels.py +++ b/meshterm/ui/channels.py @@ -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 diff --git a/tests/test_channels.py b/tests/test_channels.py index f114800..afbebf7 100644 --- a/tests/test_channels.py +++ b/tests/test_channels.py @@ -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