From 8dfdc3bdd7774386bc03e34aedd67dc389dbc272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AI=E4=BA=A7=E5=93=81=E9=BB=84=E5=8F=94?= Date: Sun, 27 Sep 2026 17:52:43 -0700 Subject: [PATCH 1/4] fix(popover): refresh the Token Rank board from the refresh button refreshNow() refreshed usage and quotas but never the leaderboard, so the board could stay up to 30 minutes old after a manual refresh. It now forces a leaderboard fetch too, and the refresh buttons keep spinning until the board is back when Token Rank is linked. Co-Authored-By: Claude Opus 5.5 --- .../Sources/TokenStepSwift/Stores/AppState.swift | 8 +++++++- .../Sources/TokenStepSwift/Views/MainWindowView.swift | 8 ++++---- .../Sources/TokenStepSwift/Views/PopoverPanelView.swift | 6 +++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/TokenStepSwift/Sources/TokenStepSwift/Stores/AppState.swift b/TokenStepSwift/Sources/TokenStepSwift/Stores/AppState.swift index 0b1bbd6..0104fa6 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Stores/AppState.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Stores/AppState.swift @@ -164,6 +164,11 @@ final class AppState: ObservableObject { settings.agentWorkRankVisibility.shouldShow(hasLocalIdentity: agentWorkRankIdentity != nil) } + /// What the refresh buttons show as syncing: usage, plus the TokenRank board when it is linked. + var isRefreshingForDisplay: Bool { + isRefreshing || (shouldShowAgentWorkRank && isRefreshingTokenRank) + } + func load() { defer { MemoryPressure.relieveAllocatorPressure() } let loadedSettings = DataService.loadSettingsForAppLaunch() @@ -196,10 +201,11 @@ final class AppState: ObservableObject { autostartEnabled = AutostartService.isEnabled } - /// The refresh button and ⌘R: usage plus quotas, skipping quota caches. + /// The refresh button and ⌘R: usage, quotas and the TokenRank board, skipping caches. func refreshNow() { refresh() refreshCodexQuota(force: true, bypassCache: true) + refreshTokenRank(force: true) } func refresh(forceCollection: Bool = true) { diff --git a/TokenStepSwift/Sources/TokenStepSwift/Views/MainWindowView.swift b/TokenStepSwift/Sources/TokenStepSwift/Views/MainWindowView.swift index 82fc9e2..4cb60d9 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Views/MainWindowView.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Views/MainWindowView.swift @@ -117,9 +117,9 @@ struct MainWindowView: View { HStack(spacing: 8) { HStack(spacing: 6) { Circle() - .fill(appState.isRefreshing ? Color.secondary.opacity(0.7) : Color.tokenSuccess) + .fill(appState.isRefreshingForDisplay ? Color.secondary.opacity(0.7) : Color.tokenSuccess) .frame(width: 7, height: 7) - Text(appState.isRefreshing ? L("同步中") : L("已同步")) + Text(appState.isRefreshingForDisplay ? L("同步中") : L("已同步")) .font(.caption.weight(.heavy)) } .padding(.horizontal, 10) @@ -135,8 +135,8 @@ struct MainWindowView: View { .frame(width: 28, height: 28) } .buttonStyle(.plain) - .disabled(appState.isRefreshing) - .help(appState.isRefreshing ? L("同步中") : L("刷新")) + .disabled(appState.isRefreshingForDisplay) + .help(appState.isRefreshingForDisplay ? L("同步中") : L("刷新")) DashboardUpdateButton() diff --git a/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift b/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift index 2c8a183..7b93ae8 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift @@ -150,7 +150,7 @@ struct PopoverPanelView: View { appState.refreshNow() } label: { Group { - if appState.isRefreshing { + if appState.isRefreshingForDisplay { ProgressView().controlSize(.small) } else { Image(systemName: "arrow.clockwise") @@ -161,8 +161,8 @@ struct PopoverPanelView: View { .contentShape(Rectangle()) } .buttonStyle(.plain) - .disabled(appState.isRefreshing) - .help(appState.isRefreshing ? L("同步中") : L("刷新")) + .disabled(appState.isRefreshingForDisplay) + .help(appState.isRefreshingForDisplay ? L("同步中") : L("刷新")) .accessibilityLabel(L("刷新")) Button { From a8fde060d21596b97788f9bf34615e9719dc332e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AI=E4=BA=A7=E5=93=81=E9=BB=84=E5=8F=94?= Date: Sun, 27 Sep 2026 17:52:43 -0700 Subject: [PATCH 2/4] chore: prepare TokenStep 0.2.22 Release notes, CHANGELOG, README and the build default, via script/prepare_release.sh. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 4 ++++ README.md | 10 +++++----- docs/RELEASE_NOTES_0.2.22.md | 8 ++++++++ script/build_swiftui_and_run.sh | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 docs/RELEASE_NOTES_0.2.22.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 72d05e1..4871a61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ TokenStep 各版本的更新内容,新版本在前。每个版本的完整说明在 [docs/RELEASE_NOTES_<版本号>.md](docs/)。 +## 0.2.22 更新:刷新时同步更新 Token Rank 榜单 + +面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存重新读取 Token Rank 榜单和排名,关联了 Token Rank 时刷新按钮会等榜单读取完再停止转圈。详见 [0.2.22 发布说明](docs/RELEASE_NOTES_0.2.22.md)。 + ## 0.2.21 更新:仪表盘与设置改版 仪表盘和设置参考 Token Rank 个人页重新设计:今日页新增与昨天对比、Token 构成、近 5 周热力图和按客户端堆叠的分时图;历史页新增年度热力图、常用时段和最长连续达标;设置改为左侧栏分组,改动立即生效。详见 [0.2.21 发布说明](docs/RELEASE_NOTES_0.2.21.md)。 diff --git a/README.md b/README.md index 1749a87..7cb13ea 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ TokenStep 是一个 macOS 菜单栏 App,用来本地统计你在 Codex、Claud 下载最新版 DMG,打开后把 `TokenStep.app` 拖进「应用程序」即可使用: -[下载 TokenStep 最新版](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.21.dmg) +[下载 TokenStep 最新版](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.22.dmg) 也可以从 Release 页面查看所有版本: @@ -32,9 +32,9 @@ TokenStep 已使用 Developer ID 签名并通过 Apple 公证。首次打开时 Windows版本由十七做了移植,欢迎大家前往使用:https://github.com/canyexuanfan/TokenStep-Windows/releases -## 最新版本:0.2.21 +## 最新版本:0.2.22 -仪表盘和设置参考 Token Rank 个人页重新设计:今日页新增与昨天对比、Token 构成、近 5 周热力图和按客户端堆叠的分时图;历史页新增年度热力图、常用时段和最长连续达标;设置改为左侧栏分组,改动立即生效。详见 [0.2.21 发布说明](docs/RELEASE_NOTES_0.2.21.md)。 +面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存重新读取 Token Rank 榜单和排名,关联了 Token Rank 时刷新按钮会等榜单读取完再停止转圈。详见 [0.2.22 发布说明](docs/RELEASE_NOTES_0.2.22.md)。 历次更新(主题包、引力动效、自动更新等)见 [CHANGELOG.md](CHANGELOG.md)。 @@ -95,7 +95,7 @@ TokenStep 默认只做本地统计。 ## 安装方式 -1. 下载 [TokenStep 最新版 DMG](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.21.dmg)。 +1. 下载 [TokenStep 最新版 DMG](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.22.dmg)。 2. 打开 DMG。 3. 把 `TokenStep.app` 拖到「应用程序」。 4. 启动 TokenStep。 @@ -166,7 +166,7 @@ TokenStepSwift/dist/TokenStep.app 公开发布强制执行 Developer ID 签名、Apple 公证、票据装订、系统分发检查和隔离安装验证。不再生成可被误上传的“仅签名、未公证”发布包: ```bash -TOKENSTEP_VERSION=0.2.21 \ +TOKENSTEP_VERSION=0.2.22 \ CODE_SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \ TOKENSTEP_NOTARY_PROFILE="tokenstep-notary" \ ./script/package_release.sh --notarize diff --git a/docs/RELEASE_NOTES_0.2.22.md b/docs/RELEASE_NOTES_0.2.22.md new file mode 100644 index 0000000..6010b97 --- /dev/null +++ b/docs/RELEASE_NOTES_0.2.22.md @@ -0,0 +1,8 @@ +# TokenStep 0.2.22 + +点刷新按钮时,Token Rank 榜单也会一起更新。 + +- **刷新榜单**:面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存,重新读取 Token Rank 榜单和你的排名。之前刷新只更新用量和额度,榜单最多要等 30 分钟才会变。 +- **同步状态**:关联了 Token Rank 时,刷新按钮会等榜单也读取完再停止转圈;没有关联时和以前一样。 + +Token、金额与额度的统计口径不变。 diff --git a/script/build_swiftui_and_run.sh b/script/build_swiftui_and_run.sh index 751a178..c72b0c2 100755 --- a/script/build_swiftui_and_run.sh +++ b/script/build_swiftui_and_run.sh @@ -23,7 +23,7 @@ HELPER_EXECUTABLE="$BUILD_DIR/$HELPER_NAME" ICON_FILE="$ROOT_DIR/TokenUsageMenuApp/assets/TokenStepIcon.icns" ODYSSEY_ASSET_DIR="$ROOT_DIR/TokenUsageMenuApp/assets/odyssey" INTERSTELLAR_ASSET_DIR="$ROOT_DIR/TokenUsageMenuApp/assets/interstellar" -VERSION="${TOKENSTEP_VERSION:-0.2.21}" +VERSION="${TOKENSTEP_VERSION:-0.2.22}" LAUNCH=true VERIFY=false From 6f167ac9c4118fb563d6f9579f5dc75cf15cc031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AI=E4=BA=A7=E5=93=81=E9=BB=84=E5=8F=94?= Date: Sun, 27 Sep 2026 17:53:35 -0700 Subject: [PATCH 3/4] feat(popover): show the viewer's Token Rank board tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rank row already knew the viewer's token count on the board but never showed it. It now sits on the right of the rank, e.g. "#35 / 1200 人 … 榜单用量 28.5M". Co-Authored-By: Claude Opus 5.5 --- .../Sources/TokenStepSwift/Support/Localization.swift | 2 ++ .../Views/Popover/CompactPopoverSections.swift | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift b/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift index 4ff8817..35137c1 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift @@ -571,6 +571,7 @@ enum TokenStepLocalization { "本地比榜单多 %@,同步后预计升到 #%d": "%@ more locally than on the board; about #%d after sync", "本地比榜单多 %@,等待同步": "%@ more locally than on the board, waiting for sync", "榜单 %@": "Board %@", + "榜单用量 %@": "%@ on board", "照此速度会提前用完": "Runs out early at this pace", "%@额度会提前用完": "%@ runs out early", "已重置": "Reset", @@ -1328,6 +1329,7 @@ enum TokenStepLocalization { "本地比榜单多 %@,同步后预计升到 #%d": "本機比榜單多 %@,同步後預計升到 #%d", "本地比榜单多 %@,等待同步": "本機比榜單多 %@,等待同步", "榜单 %@": "榜單 %@", + "榜单用量 %@": "榜單用量 %@", "照此速度会提前用完": "照此速度會提前用完", "%@额度会提前用完": "%@額度會提前用完", "已重置": "已重置", diff --git a/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift b/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift index 8561d54..c20eb57 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift @@ -473,6 +473,12 @@ struct CompactRankSection: View { .font(.system(size: 12)) .foregroundStyle(.secondary) Spacer(minLength: 4) + if let tokens = section.myBoardTokens { + Text(LFormat("榜单用量 %@", TokenStepFormat.tokens(tokens, compact: true))) + .font(.system(size: 12, weight: .semibold)) + .monospacedDigit() + .foregroundStyle(Color.tokenInk) + } } .contentShape(Rectangle()) .onTapGesture { openMyPage?() } From def4bc293315ffe3954402909802e2dd36fbd519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?AI=E4=BA=A7=E5=93=81=E9=BB=84=E5=8F=94?= Date: Sun, 27 Sep 2026 17:53:35 -0700 Subject: [PATCH 4/4] chore: note the board tokens in the 0.2.22 release documents Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 4 ++-- README.md | 2 +- docs/RELEASE_NOTES_0.2.22.md | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4871a61..aba39a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,9 @@ TokenStep 各版本的更新内容,新版本在前。每个版本的完整说明在 [docs/RELEASE_NOTES_<版本号>.md](docs/)。 -## 0.2.22 更新:刷新时同步更新 Token Rank 榜单 +## 0.2.22 更新:刷新时同步更新 Token Rank 榜单,面板显示榜单用量 -面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存重新读取 Token Rank 榜单和排名,关联了 Token Rank 时刷新按钮会等榜单读取完再停止转圈。详见 [0.2.22 发布说明](docs/RELEASE_NOTES_0.2.22.md)。 +面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存重新读取 Token Rank 榜单和排名,关联了 Token Rank 时刷新按钮会等榜单读取完再停止转圈;面板的「今日排名」在名次旁显示你在榜单上的 Token 用量。详见 [0.2.22 发布说明](docs/RELEASE_NOTES_0.2.22.md)。 ## 0.2.21 更新:仪表盘与设置改版 diff --git a/README.md b/README.md index 7cb13ea..bc2e1be 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Windows版本由十七做了移植,欢迎大家前往使用:https://github.c ## 最新版本:0.2.22 -面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存重新读取 Token Rank 榜单和排名,关联了 Token Rank 时刷新按钮会等榜单读取完再停止转圈。详见 [0.2.22 发布说明](docs/RELEASE_NOTES_0.2.22.md)。 +面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存重新读取 Token Rank 榜单和排名,关联了 Token Rank 时刷新按钮会等榜单读取完再停止转圈;面板的「今日排名」在名次旁显示你在榜单上的 Token 用量。详见 [0.2.22 发布说明](docs/RELEASE_NOTES_0.2.22.md)。 历次更新(主题包、引力动效、自动更新等)见 [CHANGELOG.md](CHANGELOG.md)。 diff --git a/docs/RELEASE_NOTES_0.2.22.md b/docs/RELEASE_NOTES_0.2.22.md index 6010b97..a842222 100644 --- a/docs/RELEASE_NOTES_0.2.22.md +++ b/docs/RELEASE_NOTES_0.2.22.md @@ -1,8 +1,9 @@ # TokenStep 0.2.22 -点刷新按钮时,Token Rank 榜单也会一起更新。 +点刷新按钮时,Token Rank 榜单也会一起更新;面板里能看到你在榜单上的 Token 用量。 - **刷新榜单**:面板和主窗口的刷新按钮(以及 ⌘R)现在会跳过缓存,重新读取 Token Rank 榜单和你的排名。之前刷新只更新用量和额度,榜单最多要等 30 分钟才会变。 +- **榜单用量**:面板的「今日排名」在名次旁显示你今天在榜单上的 Token 用量。 - **同步状态**:关联了 Token Rank 时,刷新按钮会等榜单也读取完再停止转圈;没有关联时和以前一样。 Token、金额与额度的统计口径不变。