Say unread on the tray icon itself, not only in its tooltip - #127
Conversation
The count reached the tray and stopped at the tooltip: the icon was "user-available" whether or not anything was waiting, so a glance at a full chat list saw an idle icon. StatusNotifierItem has no badge, so the count is spoken as a state. The icon takes a themed `mail-unread` while something is unread and the item goes to `NeedsAttention`, which also keeps it visible in a host that hides passive items; both `icon_name` and `attention_icon_name` name it, because a host may honour one and not the other. The category becomes `Communications`, which some hosts require before emphasising an item. The number stays in the tooltip and now rides in its title too, for a host that renders only the first line. `Item::unread` is the one place that reads the count, and reads it as zero while disconnected: a stale number nothing is refreshing is not worth asking to be looked at, and it is what the tooltip already said. Closes #125. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NX17ZrYJmz5SXjLMRn1VXo
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Team Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe Linux tray now derives unread state through a connection-aware helper. It uses themed icons, ChangesLinux tray unread state
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to Linux tray items now visibly distinguish offline, idle, and unread-message states while keeping connection-aware unread counts consistent in icons and tooltips. No current merge-readiness risk remains. Sequence Diagram(s)sequenceDiagram
participant DaemonConnection
participant Item
participant StatusNotifierHost
DaemonConnection->>Item: provide connection and unread state
Item->>Item: normalize unread count
Item->>StatusNotifierHost: provide icon, status, category, and tooltip
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 1 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #125.
What was wrong
The unread count already reaches the tray —
TrayState::unreadis computed in the store, filtered throughChatSummary::counts_toward_unread, and watched by the tray task — and then stopped at the tooltip.icon_nameasked one question, whether the connection was up, so the icon wasuser-availableover a chat list with three unread messages in it and over one with none. The reporter had messages waiting and the icon showed nothing, which is exactly right: the only thing that knew was a tooltip you have to hover to read.What this does
icon_namenow answers three states rather than two:user-offlinedisconnected,user-availableconnected and caught up, and a themedmail-unreadwhile something is waiting. Still a name from the icon-naming spec rather than shipped pixels, like the two it joins, so it follows the user's theme.statusgoes toNeedsAttentionwhile unread, which is the only thing StatusNotifierItem has that resembles a badge — it asks a host to emphasise the icon, and it keeps the item visible in a host that hides passive ones.attention_icon_namenames the same icon asicon_name: a host honouring the status swaps to it, a host ignoring the status reads the other, and naming one icon in both is what keeps the two answers from showing different things.Communications. It was the defaultApplicationStatus. Hosts group by it, and some only emphasise an item that claims to be a communications one — which is the state above.oxidezap (3)for a host that renders only the first line, and the description is unchanged.Item::unreadis what the icon, the status and the tooltip all go through, and it reads zero while the connection is down — a count nothing is refreshing is not worth asking to be looked at, and "Disconnected" is what the tooltip already said in that state. Written once so the icon and the tooltip cannot come to disagree about what is unread.docs/gotchas.mdgets the reasoning, next to the rest of the tray's.Not in scope
A number drawn on the icon. That means
icon_pixmap— rendering ARGB32 ourselves, with a font, at whatever sizes the host asks for, and giving up the themed name that follows the user's icon set and light/dark switch. The protocol offers no counter, and every tray that shows one paints it. Worth doing if the state above turns out not to be enough, but it is a different change and it costs the theming.Nothing changes off Linux: the tray has one implementation and the others still return "no tray implementation for this platform yet" from
spawn.Tests
tray::linux::tests, new — the icon over a state, with the hub and the click left at their defaults since nothing asks them anything:unread_reaches_the_icon_itself— the report itself: an icon with something to read does not look like one without, it is the unread name, the status isNeedsAttention, the attention icon matches it, and an idle icon isActive.a_disconnected_icon_says_the_connection_and_not_a_stale_count— three unread and no connection isuser-offline,Active, and "Disconnected".the_tooltip_carries_the_count— the title and the description at zero, one and four, and the tooltip's icon following the one being shown.Ran locally on 1.98:
cargo fmt --all --check,cargo clippy -p oxidezap-daemon --all-targets --all-features(clean), andcargo test -p oxidezap-daemon --all-features— 196 + 8 passed, 0 failed. Leaving the full-workspace and web checks to CI.🤖 Generated with Claude Code
https://claude.ai/code/session_01NX17ZrYJmz5SXjLMRn1VXo
Generated by Claude Code
Summary by cubic
Fixes the tray icon to show unread messages on the icon itself, not just in its tooltip. Closes #125.
mail-unreadwhen there are unread messages, instead of always showinguser-availablewhile connected.NeedsAttentionand category toCommunications, which hosts use to emphasise the icon and keep it visible.oxidezap (3)).Item::unreadis the single source of truth for the count, reading zero while disconnected so a stale count is not shown.Written for commit d4a5e79. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation