Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

TokenStep 各版本的更新内容,新版本在前。每个版本的完整说明在 [docs/RELEASE_NOTES_<版本号>.md](docs/)。

## 0.2.18 更新:额度预警写明窗口

额度提前用完的提示会写出是哪个窗口,例如「7 天额度会提前用完」,不再和快要重置的 5 小时窗口混淆;面板里的排名可以直接打开 Token Rank 榜单和个人主页。详见 [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)。
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 页面查看所有版本:

Expand All @@ -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 天额度会提前用完」;面板里的排名可以直接打开 Token Rank 网页。0.2.16 起菜单栏面板改为一列紧凑面板,额度刷新也更及时。详见 [0.2.18 发布说明](docs/RELEASE_NOTES_0.2.18.md)。

历次更新(主题包、引力动效、自动更新等)见 [CHANGELOG.md](CHANGELOG.md)。

Expand Down Expand Up @@ -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。
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ enum TokenStepLocalization {
"榜上 %@": "On board %@",
"榜单 %@": "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",
Expand Down Expand Up @@ -1211,6 +1214,9 @@ enum TokenStepLocalization {
"榜上 %@": "榜上 %@",
"榜单 %@": "榜單 %@",
"照此速度会提前用完": "照此速度會提前用完",
"%@额度会提前用完": "%@額度會提前用完",
"打开我的 Token Rank 主页": "打開我的 Token Rank 主頁",
"在浏览器打开 Token Rank 榜单": "在瀏覽器打開 Token Rank 榜單",
"已用 %@": "已用 %@",
"竖线是时间进度:已过 %@,已用 %@": "豎線是時間進度:已過 %@,已用 %@",
"。用得比时间快,照此速度会在重置前用完": "。用得比時間快,照此速度會在重置前用完",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
Expand Down Expand Up @@ -379,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)")
Expand All @@ -404,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)")
Expand Down Expand Up @@ -433,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions docs/RELEASE_NOTES_0.2.18.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# TokenStep 0.2.18

额度预警写明是哪个窗口会提前用完,面板里可以直接打开 Token Rank 网页。

- **预警更明确**:以前的提示只写「照此速度会提前用完」,放在服务名称旁边。如果 5 小时窗口快要重置,而实际跑快的是 7 天窗口,就容易被误读成在说 5 小时。现在提示会写出窗口名称,例如「7 天额度会提前用完」;多个窗口都会提前用完时一并列出。
- **打开 Token Rank 网页**:面板「今日排名」右上角的「榜单 N 分钟前」可以点击,会在浏览器打开 Token Rank 榜单;点击自己的排名那一行,会打开你的 Token Rank 个人主页。

统计口径与 0.2.17 相同。
2 changes: 1 addition & 1 deletion script/build_swiftui_and_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading