Skip to content

feat(tray): show subscription utilization as clockwise ring icon on macOS#2353

Open
TuYv wants to merge 9 commits intofarion1231:mainfrom
TuYv:feat/tray-ring-icon
Open

feat(tray): show subscription utilization as clockwise ring icon on macOS#2353
TuYv wants to merge 9 commits intofarion1231:mainfrom
TuYv:feat/tray-ring-icon

Conversation

@TuYv
Copy link
Copy Markdown
Contributor

@TuYv TuYv commented Apr 26, 2026

Summary / 概述

  1. 利用换行在同一行展示订阅使用率和剩余刷新时间(尝试了二级菜单展示刷新时间感觉并不是很友好)
  2. 在 macOS 托盘图标上以扇形进度填充展示当前订阅利用率(觉得ccswitch的logo挺适合搞一个扇形进度的 就试了一下):
  • 图标像素按利用率着色(绿 <70%、橙 70–90%、红 ≥90%),从 12 点钟方向顺时针填充
  • 图标跟随主界面当前聚焦的 app;切换到无订阅数据的第三方 app 时自动 fallback 到上一个官方 app
  • 设置页新增「托盘进度图标」开关,关闭/开启立即生效
  • 同步修复已有回归:去掉 format_subscription_summary 中的 \n,解决首次点击托盘菜单被强制收起的问题
  • 子菜单下方新增 disabled 详情行,显示用量百分比与重置倒计时(如 🟢 h9% 1h 30m · w27% 2d 0h

Related Issue / 关联 Issue

Fixes #

Screenshots / 截图

Before / 修改前 After / 修改后
image image
image |

Code Review Fixes / CR 修复记录

经过两轮 Code Review,共修复以下问题:

第一轮 CR

  • [P2] 利用率跨越颜色阈值时图标不刷新:将图标缓存 key 从单纯的取整百分比改为 (rounded_u8, color_tier) 元组,89.x→90.x 这类跨阈值变化不再被去重逻辑误判为"无变化"
  • [P2] usage 不可用时旧 detail 行残留:补上 (Some(item), None) match 分支,usage 消失时触发菜单重建以移除过期条目
  • [P3] 每次保存设置都重置刷新节流:将条件从 if enable_progress_icon 改为 if enable_progress_icon && !was_enabled,仅在开关从关→开时才重置节流并发起请求

第二轮 CR

  • [P2] 环形图标未限定 macOS 平台:在有数据路径开头加 #[cfg(not(target_os = "macos"))] return;,Windows/Linux 不再被 macOS 专属图标资源覆盖托盘图标
  • [P2] 切换到第三方 provider 后彩色环残留compute_tray_worst_pct 返回 None 时,若之前已渲染过环形图,清空缓存并还原模板图标
  • [P3] 隐藏的 app 触发无效菜单重建update_tray_usage_labels 循环开头加 visible_apps.is_visible 检查,隐藏 section 直接跳过,不再误触发 refresh_tray_menu

Checklist / 检查清单

  • pnpm typecheck passes / 通过 TypeScript 类型检查
  • pnpm format:check passes / 通过代码格式检查
  • cargo clippy passes (if Rust code changed) / 通过 Clippy 检查(如修改了 Rust 代码)
  • Updated i18n files if user-facing text changed / 如修改了用户可见文本,已更新国际化文件

TuYv added 2 commits April 26, 2026 20:17
- Add Rust-side write-through UsageCache backed by SQLite
- Surface per-provider usage in system tray submenus (subscription quota,
  script quota, coding-plan quota for Kimi/Zhipu/MiniMax)
- Show subscription reset countdowns as a disabled second line below each
  app submenu title
- Skip hidden apps on hover refresh; drop stale disabled-script cache
- Bridge tray UsageCache writes to frontend React Query
- Add 200ms debounce to set_tray_focus_app IPC calls in frontend
Draw a clockwise sector over the tray icon to visualize subscription
usage: green <70%, orange 70-90%, red >=90%. Add a toggle in Settings
(tray_progress_icon). Toggling off immediately restores the template
icon; toggling on kicks off a background refresh so the icon appears
without requiring a menu-bar click.
@TuYv TuYv force-pushed the feat/tray-ring-icon branch from c63e1a9 to a7e3369 Compare April 26, 2026 12:18
Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a7e336975d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/tray.rs Outdated
Comment thread src-tauri/src/tray.rs Outdated
Comment thread src-tauri/src/commands/settings.rs Outdated
TuYv and others added 6 commits April 26, 2026 22:30
- tray: change LAST_TRAY_ICON_PCT cache key from rounded u8 to (u8, tier)
  so the icon re-renders when utilization crosses a color boundary even
  if both values round to the same integer (#P2)
- tray: handle (Some(item), None) match arm to trigger menu rebuild when
  usage becomes unavailable, preventing stale detail text in the tray (#P2)
- settings: only reset refresh throttle and spawn a fetch when
  tray_progress_icon transitions false→true, not on every settings save
  while already enabled (#P3)
…idden sections

- update_tray_icon: wrap ring-icon render path in #[cfg(target_os = "macos")]
  so Windows/Linux tray icons are never replaced by the macOS statusbar asset
- update_tray_icon: when compute_tray_worst_pct returns None after a ring icon
  was already shown, clear LAST_TRAY_ICON_PCT and restore the template icon
  instead of leaving a stale colored arc on screen
- update_tray_usage_labels: skip sections hidden by visible_apps setting so
  they can no longer trigger spurious full menu rebuilds on every usage refresh
Functions/statics only used in macOS rendering path caused dead-code
warnings under Linux CI clippy. Gate update_tray_icon and all its
dependencies (TRAY_LAST_OFFICIAL_APP, LAST_TRAY_ICON_PCT,
pct_to_color_tier, generate_ring_icon_rgba, get_section_subscription_pct,
compute_tray_worst_pct) plus the ring icon pixel tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two call sites in update_tray_usage_labels and refresh_tray_menu were
missed; wrap them with #[cfg(target_os = "macos")]. Rename unused
'app' params in set_tray_focused_app and update_tray_icon_pub to _app
to suppress Linux unused-variable warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ICON_BASE_BYTES and ICON_BASE_RGBA are only referenced inside
#[cfg(target_os = "macos")] code; gate them to silence Linux dead-code
warnings. Replace the early return+cfg pattern in update_tray_usage_labels
with an if/else so clippy does not flag a needless return on Linux.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@TuYv
Copy link
Copy Markdown
Contributor Author

TuYv commented Apr 26, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@TuYv
Copy link
Copy Markdown
Contributor Author

TuYv commented Apr 26, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc9b2f8823

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/App.tsx
switch_provider now accepts AppHandle and calls update_tray_icon_pub
after a successful switch, so the ring icon reflects the new provider's
category (official vs third-party) immediately instead of waiting for
the next activeApp focus change or usage refresh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@TuYv
Copy link
Copy Markdown
Contributor Author

TuYv commented Apr 26, 2026

@codex review

1 similar comment
@TuYv
Copy link
Copy Markdown
Contributor Author

TuYv commented Apr 27, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants