Found during adversarial review of #445 (mobile hamburger unread badge). Pre-existing behavior, affects three surfaces: the document-title count, the room-list badges, and (since #445) the hamburger badge.
Behavior
mark_all_rooms_as_read() (ui/src/components/app/document_title.rs) fires on every visible→hidden visibilitychange and marks every room read up to its latest message. Rationale in the code: "the user had the chance to see anything already in state."
That premise is desktop-title-centric. On mobile, switching apps fires visible→hidden, and rooms other than the current one were never on screen — yet their unread state is wiped. Scenario:
- User is deep in room A on mobile; a message lands in room B → hamburger badge / rail badge show 1.
- User switches to another app (visibilitychange → hidden) → all rooms marked read.
- User returns → badges gone, though the room-B message was never seen.
So the unread indicators only hold within a single uninterrupted foreground session. On desktop the same wipe zeroes rail badges for rooms whose messages were arguably never "seen" either (a rail badge count is not the message).
Options
- Only mark the current room read on hide (other rooms keep unread until actually opened). Changes title semantics: the hidden-tab "(N)" would then show total accumulated unread, not just new-since-hide — arguably more useful, but a deliberate change.
- Keep mark-all on desktop, restrict to current-room-only on touch/mobile (no reliable signal; user-agent sniffing is ugly).
- Keep as-is and accept the reset (status quo).
Needs a product call since it changes long-standing title behavior. cc @sanity
[AI-assisted - Claude]
Found during adversarial review of #445 (mobile hamburger unread badge). Pre-existing behavior, affects three surfaces: the document-title count, the room-list badges, and (since #445) the hamburger badge.
Behavior
mark_all_rooms_as_read()(ui/src/components/app/document_title.rs) fires on every visible→hiddenvisibilitychangeand marks every room read up to its latest message. Rationale in the code: "the user had the chance to see anything already in state."That premise is desktop-title-centric. On mobile, switching apps fires visible→hidden, and rooms other than the current one were never on screen — yet their unread state is wiped. Scenario:
So the unread indicators only hold within a single uninterrupted foreground session. On desktop the same wipe zeroes rail badges for rooms whose messages were arguably never "seen" either (a rail badge count is not the message).
Options
Needs a product call since it changes long-standing title behavior. cc @sanity
[AI-assisted - Claude]