From f76a2aa212c751894c2fb02ef1e7ad0160cb2efb 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: Fri, 25 Sep 2026 21:49:22 -0700 Subject: [PATCH 1/4] fix(popover): name the quota window that runs out early MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The badge only said "照此速度会提前用完" next to the provider name, so with the 5-hour window minutes from its reset it read as a false alarm about that window, while it was the 7-day window running ahead. The badge now names the window, for example "7 天额度会提前用完". Co-Authored-By: Claude Opus 5.5 --- .../TokenStepSwift/Support/Localization.swift | 2 ++ .../Views/Popover/CompactPopoverSections.swift | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift b/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift index fa83236..829e5c3 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift @@ -516,6 +516,7 @@ enum TokenStepLocalization { "榜上 %@": "On board %@", "榜单 %@": "Board %@", "照此速度会提前用完": "Runs out early at this pace", + "%@额度会提前用完": "%@ runs out early", "已用 %@": "%@ used", "竖线是时间进度:已过 %@,已用 %@": "The tick marks time passed: %@ of the window gone, %@ used", "。用得比时间快,照此速度会在重置前用完": ". Usage is ahead of time and runs out before the reset at this pace", @@ -1211,6 +1212,7 @@ enum TokenStepLocalization { "榜上 %@": "榜上 %@", "榜单 %@": "榜單 %@", "照此速度会提前用完": "照此速度會提前用完", + "%@额度会提前用完": "%@額度會提前用完", "已用 %@": "已用 %@", "竖线是时间进度:已过 %@,已用 %@": "豎線是時間進度:已過 %@,已用 %@", "。用得比时间快,照此速度会在重置前用完": "。用得比時間快,照此速度會在重置前用完", diff --git a/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift b/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift index 847f89c..3673b6f 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift @@ -255,6 +255,15 @@ struct CompactQuotaSection: View { ) } + /// Names the window that runs out early, so a warning next to a window + /// about to reset is not read as being about that one. + private func runsOutEarlyBadge(_ provider: CompactPopoverModel.QuotaProviderRow) -> String { + let titles = provider.windows.filter(\.runsOutEarly).map(\.title) + guard !titles.isEmpty else { return L("照此速度会提前用完") } + let separator = TokenStepLocalization.language == .en ? ", " : "、" + return LFormat("%@额度会提前用完", titles.joined(separator: separator)) + } + /// Explains the bar's tick: how much of the window's time has passed. private func paceHelp(_ window: CompactPopoverModel.QuotaWindowRow) -> String { guard let elapsed = window.elapsedFraction else { @@ -277,8 +286,10 @@ struct CompactQuotaSection: View { .foregroundStyle(Color.tokenInk) Spacer(minLength: 4) if provider.runsOutEarly { - Text(L("照此速度会提前用完")) + Text(runsOutEarlyBadge(provider)) .font(.system(size: 11, weight: .semibold)) + .lineLimit(1) + .minimumScaleFactor(0.8) .foregroundStyle(CompactPopoverStyle.color(for: .warning)) .padding(.horizontal, 7) .padding(.vertical, 2) From 0b76959c637880538da11bd74c52a60a63ccad87 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: Fri, 25 Sep 2026 22:47:05 -0700 Subject: [PATCH 2/4] chore: prepare TokenStep 0.2.18 Add release notes, the CHANGELOG entry, README download links, and the default build version. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 4 ++++ README.md | 10 +++++----- docs/RELEASE_NOTES_0.2.18.md | 7 +++++++ script/build_swiftui_and_run.sh | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 docs/RELEASE_NOTES_0.2.18.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c1fd66..161fae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ TokenStep 各版本的更新内容,新版本在前。每个版本的完整说明在 [docs/RELEASE_NOTES_<版本号>.md](docs/)。 +## 0.2.18 更新:额度预警写明窗口 + +额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」,不再和快要重置的 5 小时窗口混淆。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。 + ## 0.2.17 更新:修复刘海卡片闪烁 在有刘海的 Mac 上,鼠标放在 Token Island 边缘时,展开的卡片不再反复弹出又收起。详见 [0.2.17 发布说明](docs/RELEASE_NOTES_0.2.17.md)。 diff --git a/README.md b/README.md index 82c6d51..37349ca 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.17.dmg) +[下载 TokenStep 最新版](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.18.dmg) 也可以从 Release 页面查看所有版本: @@ -32,9 +32,9 @@ TokenStep 已使用 Developer ID 签名并通过 Apple 公证。首次打开时 Windows版本由十七做了移植,欢迎大家前往使用:https://github.com/canyexuanfan/TokenStep-Windows/releases -## 最新版本:0.2.17 +## 最新版本:0.2.18 -修复刘海 Mac 上鼠标放在 Token Island 边缘时卡片反复闪烁的问题。上一版 0.2.16 把菜单栏面板改成了一列紧凑面板,额度刷新也更及时。详见 [0.2.17 发布说明](docs/RELEASE_NOTES_0.2.17.md)。 +额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」。0.2.16 起菜单栏面板改为一列紧凑面板,额度刷新也更及时。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。 历次更新(主题包、引力动效、自动更新等)见 [CHANGELOG.md](CHANGELOG.md)。 @@ -95,7 +95,7 @@ TokenStep 默认只做本地统计。 ## 安装方式 -1. 下载 [TokenStep 最新版 DMG](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.17.dmg)。 +1. 下载 [TokenStep 最新版 DMG](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.18.dmg)。 2. 打开 DMG。 3. 把 `TokenStep.app` 拖到「应用程序」。 4. 启动 TokenStep。 @@ -166,7 +166,7 @@ TokenStepSwift/dist/TokenStep.app 公开发布强制执行 Developer ID 签名、Apple 公证、票据装订、系统分发检查和隔离安装验证。不再生成可被误上传的“仅签名、未公证”发布包: ```bash -TOKENSTEP_VERSION=0.2.17 \ +TOKENSTEP_VERSION=0.2.18 \ 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.18.md b/docs/RELEASE_NOTES_0.2.18.md new file mode 100644 index 0000000..4344d2c --- /dev/null +++ b/docs/RELEASE_NOTES_0.2.18.md @@ -0,0 +1,7 @@ +# TokenStep 0.2.18 + +额度预警写明是哪个窗口会提前用完。 + +- **预警更明确**:以前的提示只写「照此速度会提前用完」,放在服务名称旁边。如果 5 小时窗口快要重置,而实际跑快的是 7 天窗口,就容易被误读成在说 5 小时。现在提示会写出窗口名称,例如「7 天额度会提前用完」;多个窗口都会提前用完时一并列出。 + +统计口径与 0.2.17 相同。 diff --git a/script/build_swiftui_and_run.sh b/script/build_swiftui_and_run.sh index 266c4a3..dd3e07b 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.17}" +VERSION="${TOKENSTEP_VERSION:-0.2.18}" LAUNCH=true VERIFY=false From b6de2bd252fe1be4e61af26523f9cb9ee77edfe0 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: Fri, 25 Sep 2026 22:50:28 -0700 Subject: [PATCH 3/4] feat(popover): open Token Rank from the rank section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compact rank section had no way to reach the Token Rank site. The "榜单 N 分钟前" label is now a link to the board, and clicking your own rank line opens your Token Rank page. Both reuse AppState's existing openers. Co-Authored-By: Claude Opus 5.5 --- .../TokenStepSwift/Support/Localization.swift | 4 ++ .../Popover/CompactPopoverSections.swift | 43 ++++++++++++++++++- .../Views/PopoverPanelView.swift | 7 ++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift b/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift index 829e5c3..5ecd824 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Support/Localization.swift @@ -517,6 +517,8 @@ enum TokenStepLocalization { "榜单 %@": "Board %@", "照此速度会提前用完": "Runs out early at this pace", "%@额度会提前用完": "%@ runs out early", + "打开我的 Token Rank 主页": "Open my Token Rank page", + "在浏览器打开 Token Rank 榜单": "Open the Token Rank board in the browser", "已用 %@": "%@ used", "竖线是时间进度:已过 %@,已用 %@": "The tick marks time passed: %@ of the window gone, %@ used", "。用得比时间快,照此速度会在重置前用完": ". Usage is ahead of time and runs out before the reset at this pace", @@ -1213,6 +1215,8 @@ enum TokenStepLocalization { "榜单 %@": "榜單 %@", "照此速度会提前用完": "照此速度會提前用完", "%@额度会提前用完": "%@額度會提前用完", + "打开我的 Token Rank 主页": "打開我的 Token Rank 主頁", + "在浏览器打开 Token Rank 榜单": "在瀏覽器打開 Token Rank 榜單", "已用 %@": "已用 %@", "竖线是时间进度:已过 %@,已用 %@": "豎線是時間進度:已過 %@,已用 %@", "。用得比时间快,照此速度会在重置前用完": "。用得比時間快,照此速度會在重置前用完", diff --git a/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift b/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift index 3673b6f..02bed58 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Views/Popover/CompactPopoverSections.swift @@ -390,10 +390,20 @@ struct CompactTokenSection: View { struct CompactRankSection: View { var section: CompactPopoverModel.RankSection var fetchedAt: Date + /// Opens the Token Rank board in the browser. + var openBoard: (() -> Void)? + /// Opens the user's own Token Rank page. + var openMyPage: (() -> Void)? var body: some View { VStack(alignment: .leading, spacing: 10) { - CompactSectionHeader(title: L("今日排名"), trailing: LFormat("榜单 %@", CompactPopoverStyle.relative(fetchedAt))) + HStack(alignment: .firstTextBaseline) { + Text(L("今日排名")) + .font(.system(size: 12, weight: .bold)) + .foregroundStyle(Color.tokenInk.opacity(0.62)) + Spacer(minLength: 8) + boardLink + } HStack(alignment: .firstTextBaseline, spacing: 8) { if let rank = section.myRank { Text("#\(rank)") @@ -415,6 +425,13 @@ struct CompactRankSection: View { .foregroundStyle(.secondary) } } + .contentShape(Rectangle()) + .onTapGesture { openMyPage?() } + .onHover { hovering in + guard openMyPage != nil else { return } + if hovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } + } + .help(openMyPage == nil ? "" : L("打开我的 Token Rank 主页")) ForEach(section.podium) { entry in HStack(spacing: 8) { Text("\(entry.rank)") @@ -444,6 +461,30 @@ struct CompactRankSection: View { } } + @ViewBuilder + private var boardLink: some View { + let label = HStack(spacing: 3) { + Text(LFormat("榜单 %@", CompactPopoverStyle.relative(fetchedAt))) + if openBoard != nil { + Image(systemName: "arrow.up.right") + .font(.system(size: 9, weight: .semibold)) + } + } + .font(.system(size: 11)) + .foregroundStyle(.secondary) + + if let openBoard { + Button(action: openBoard) { label.contentShape(Rectangle()) } + .buttonStyle(.plain) + .onHover { hovering in + if hovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } + } + .help(L("在浏览器打开 Token Rank 榜单")) + } else { + label + } + } + private var rankCaption: String { if section.myRank == nil { // A full board may hide ranks past the limit; a short one lists diff --git a/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift b/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift index fc3461c..d6e6cc1 100644 --- a/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift +++ b/TokenStepSwift/Sources/TokenStepSwift/Views/PopoverPanelView.swift @@ -23,7 +23,12 @@ struct PopoverPanelView: View { if let rank = rankSection, let board = appState.tokenRank { sectionDivider section { - CompactRankSection(section: rank, fetchedAt: board.fetchedAt) + CompactRankSection( + section: rank, + fetchedAt: board.fetchedAt, + openBoard: { appState.openTokenRankLeaderboardPage() }, + openMyPage: { appState.openTokenRankUserPage() } + ) } } notices From 7b3421bce4e85a1c64b85bdf9131d77a166aeef6 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: Fri, 25 Sep 2026 22:50:29 -0700 Subject: [PATCH 4/4] docs: note the Token Rank links in 0.2.18 Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- README.md | 2 +- docs/RELEASE_NOTES_0.2.18.md | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161fae8..b334e12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ TokenStep 各版本的更新内容,新版本在前。每个版本的完整说 ## 0.2.18 更新:额度预警写明窗口 -额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」,不再和快要重置的 5 小时窗口混淆。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。 +额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」,不再和快要重置的 5 小时窗口混淆;面板里的排名可以直接打开 Token Rank 榜单和个人主页。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。 ## 0.2.17 更新:修复刘海卡片闪烁 diff --git a/README.md b/README.md index 37349ca..c0c4b92 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Windows版本由十七做了移植,欢迎大家前往使用:https://github.c ## 最新版本:0.2.18 -额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」。0.2.16 起菜单栏面板改为一列紧凑面板,额度刷新也更及时。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。 +额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」;面板里的排名可以直接打开 Token Rank 网页。0.2.16 起菜单栏面板改为一列紧凑面板,额度刷新也更及时。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。 历次更新(主题包、引力动效、自动更新等)见 [CHANGELOG.md](CHANGELOG.md)。 diff --git a/docs/RELEASE_NOTES_0.2.18.md b/docs/RELEASE_NOTES_0.2.18.md index 4344d2c..814caec 100644 --- a/docs/RELEASE_NOTES_0.2.18.md +++ b/docs/RELEASE_NOTES_0.2.18.md @@ -1,7 +1,8 @@ # TokenStep 0.2.18 -额度预警写明是哪个窗口会提前用完。 +额度预警写明是哪个窗口会提前用完,面板里可以直接打开 Token Rank 网页。 - **预警更明确**:以前的提示只写「照此速度会提前用完」,放在服务名称旁边。如果 5 小时窗口快要重置,而实际跑快的是 7 天窗口,就容易被误读成在说 5 小时。现在提示会写出窗口名称,例如「7 天额度会提前用完」;多个窗口都会提前用完时一并列出。 +- **打开 Token Rank 网页**:面板「今日排名」右上角的「榜单 N 分钟前」可以点击,会在浏览器打开 Token Rank 榜单;点击自己的排名那一行,会打开你的 Token Rank 个人主页。 统计口径与 0.2.17 相同。