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
18 changes: 12 additions & 6 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.7.dmg)
[下载 TokenStep 最新版](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.8.dmg)

也可以从 Release 页面查看所有版本:

Expand All @@ -32,6 +32,12 @@ TokenStep 已使用 Developer ID 签名并通过 Apple 公证。首次打开时

Windows版本由十七做了移植,欢迎大家前往使用:https://github.com/canyexuanfan/TokenStep-Windows/releases

## 0.2.8 更新:引力边界图标精修

0.2.8 精修了「设置 → 通用 → 主题皮肤包」中的引力边界预览图标:黑洞、吸积盘和上下引力透镜弧重新居中并收进图标安全区,同时增加圆角裁切,修复图形穿出卡片边界的问题。

本次只调整主题选择图标,不改变首页、浮层和其他界面的黑洞主视觉,也不改变 Token、金额、额度、排行榜及本地采集口径。完整说明见 [0.2.8 发布说明](docs/RELEASE_NOTES_0.2.8.md)。

## 0.2.7 重大更新:引力边界黑洞主题包

0.2.7 新增第三套完整皮肤包「引力边界」。它不是给首页换一张壁纸,而是把近距事件视界、象牙白吸积盘和低速引力光流接进 TokenStep 的整套界面。
Expand Down Expand Up @@ -102,7 +108,7 @@ TokenStep 第一次从“更换配色”升级为完整的**主题皮肤包系
- 新增奥德赛弓箭阶梯 Logo;用量采用骨金、冷金或余烬橙,绿色只保留给同步成功等状态反馈。
- 关闭排行榜后浮层会自动收短,多来源额度则使用紧凑布局完整展示。

打开 `设置 → 通用 → 主题皮肤包` 即可切换。完整说明见 [0.2.4 发布说明](docs/RELEASE_NOTES_0.2.4.md),或直接[下载已签名并通过 Apple 公证的最新版](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.7.dmg)。
打开 `设置 → 通用 → 主题皮肤包` 即可切换。完整说明见 [0.2.4 发布说明](docs/RELEASE_NOTES_0.2.4.md),或直接[下载已签名并通过 Apple 公证的最新版](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.8.dmg)。

## TokenStep 适合谁?

Expand Down Expand Up @@ -161,7 +167,7 @@ TokenStep 默认只做本地统计。

## 安装方式

1. 下载 [TokenStep 最新版 DMG](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.7.dmg)。
1. 下载 [TokenStep 最新版 DMG](https://github.com/Backtthefuture/TokenStep/releases/latest/download/TokenStep-0.2.8.dmg)。
2. 打开 DMG。
3. 把 `TokenStep.app` 拖到「应用程序」。
4. 启动 TokenStep。
Expand Down Expand Up @@ -221,15 +227,15 @@ TokenStepSwift/dist/TokenStep.app
Developer ID 签名:

```bash
TOKENSTEP_VERSION=0.2.7 \
TOKENSTEP_VERSION=0.2.8 \
CODE_SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
./script/package_release.sh
```

签名 + Apple 公证:

```bash
TOKENSTEP_VERSION=0.2.7 \
TOKENSTEP_VERSION=0.2.8 \
CODE_SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
TOKENSTEP_NOTARY_PROFILE="tokenstep-notary" \
./script/package_release.sh --notarize
Expand All @@ -244,7 +250,7 @@ release/TokenStep-<version>.dmg

维护者说明见 [docs/RELEASE.md](docs/RELEASE.md)。

0.2.7 发布说明见 [docs/RELEASE_NOTES_0.2.7.md](docs/RELEASE_NOTES_0.2.7.md);引力边界实现说明见 [docs/INTERSTELLAR_THEME_PACK_0.2.7.md](docs/INTERSTELLAR_THEME_PACK_0.2.7.md);0.2.6 更新闭环说明见 [docs/RELEASE_NOTES_0.2.6.md](docs/RELEASE_NOTES_0.2.6.md);0.2.4 奥德赛主题包说明见 [docs/ODYSSEY_THEME_PACK_0.2.4.md](docs/ODYSSEY_THEME_PACK_0.2.4.md)。
0.2.8 发布说明见 [docs/RELEASE_NOTES_0.2.8.md](docs/RELEASE_NOTES_0.2.8.md);0.2.7 发布说明见 [docs/RELEASE_NOTES_0.2.7.md](docs/RELEASE_NOTES_0.2.7.md);引力边界实现说明见 [docs/INTERSTELLAR_THEME_PACK_0.2.7.md](docs/INTERSTELLAR_THEME_PACK_0.2.7.md);0.2.6 更新闭环说明见 [docs/RELEASE_NOTES_0.2.6.md](docs/RELEASE_NOTES_0.2.6.md);0.2.4 奥德赛主题包说明见 [docs/ODYSSEY_THEME_PACK_0.2.4.md](docs/ODYSSEY_THEME_PACK_0.2.4.md)。

## 开源协议

Expand Down
103 changes: 92 additions & 11 deletions TokenStepSwift/Sources/TokenStepSwift/Views/InterstellarSkin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -337,29 +337,110 @@ struct InterstellarTokenStepMark: View {
}

struct InterstellarThemePreview: View {
private let tileShape = RoundedRectangle(cornerRadius: 13, style: .continuous)
private let warmWhite = Color(red: 1.0, green: 0.97, blue: 0.87)
private let champagne = Color(red: 224 / 255, green: 207 / 255, blue: 169 / 255)

var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 13, style: .continuous)
tileShape
.fill(
LinearGradient(
colors: [Color.black, Color(red: 11 / 255, green: 16 / 255, blue: 24 / 255)],
colors: [
Color(red: 3 / 255, green: 5 / 255, blue: 8 / 255),
Color(red: 11 / 255, green: 16 / 255, blue: 24 / 255)
],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)

Ellipse()
.fill(
RadialGradient(
colors: [champagne.opacity(0.24), champagne.opacity(0.05), Color.clear],
center: .center,
startRadius: 1,
endRadius: 22
)
)
.frame(width: 46, height: 24)

Ellipse()
.stroke(Color.tokenGreenDark.opacity(0.88), lineWidth: 3)
.frame(width: 50, height: 13)
.offset(x: -7)
.stroke(
LinearGradient(
colors: [champagne.opacity(0.18), warmWhite, champagne.opacity(0.20)],
startPoint: .leading,
endPoint: .trailing
),
lineWidth: 1.25
)
.frame(width: 42, height: 11)
.shadow(color: warmWhite.opacity(0.24), radius: 2)

InterstellarThemeLensingArcs()
.stroke(
LinearGradient(
colors: [champagne.opacity(0.34), warmWhite.opacity(0.94), champagne.opacity(0.34)],
startPoint: .top,
endPoint: .bottom
),
style: StrokeStyle(lineWidth: 1.15, lineCap: .round)
)
.frame(width: 19, height: 28)

Circle()
.fill(Color.black)
.frame(width: 20, height: 20)
.offset(x: -8)
.frame(width: 18, height: 18)
.overlay(
Circle()
.stroke(champagne.opacity(0.58), lineWidth: 0.75)
)

Capsule()
.fill(Color.tokenGreenDark)
.frame(width: 51, height: 2)
.offset(x: 2)
.fill(
LinearGradient(
stops: [
.init(color: .clear, location: 0),
.init(color: champagne.opacity(0.72), location: 0.14),
.init(color: warmWhite, location: 0.50),
.init(color: champagne.opacity(0.72), location: 0.86),
.init(color: .clear, location: 1)
],
startPoint: .leading,
endPoint: .trailing
)
)
.frame(width: 39, height: 1.5)
.offset(y: 2.5)
.shadow(color: warmWhite.opacity(0.36), radius: 1.4)
}
.overlay(RoundedRectangle(cornerRadius: 13, style: .continuous).stroke(Color.tokenGreen.opacity(0.48)))
.clipShape(tileShape)
.overlay(tileShape.stroke(champagne.opacity(0.46), lineWidth: 1))
.accessibilityHidden(true)
}
}

private struct InterstellarThemeLensingArcs: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let left = CGPoint(x: rect.minX, y: rect.midY - 1)
let right = CGPoint(x: rect.maxX, y: rect.midY - 1)

path.move(to: left)
path.addCurve(
to: right,
control1: CGPoint(x: rect.minX + rect.width * 0.12, y: rect.minY + rect.height * 0.08),
control2: CGPoint(x: rect.maxX - rect.width * 0.12, y: rect.minY + rect.height * 0.08)
)

path.move(to: CGPoint(x: rect.minX, y: rect.midY + 1))
path.addCurve(
to: CGPoint(x: rect.maxX, y: rect.midY + 1),
control1: CGPoint(x: rect.minX + rect.width * 0.12, y: rect.maxY - rect.height * 0.08),
control2: CGPoint(x: rect.maxX - rect.width * 0.12, y: rect.maxY - rect.height * 0.08)
)

return path
}
}
22 changes: 22 additions & 0 deletions docs/RELEASE_NOTES_0.2.8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# TokenStep 0.2.8

TokenStep 0.2.8 refines the Event Horizon theme selector icon and fixes its artwork overflowing the preview tile.

## Event Horizon icon refinement

- Rebuilds the theme selector preview around a centered event horizon, a thin accretion disk, and upper and lower gravitational-lensing arcs.
- Keeps every visual element inside the 58 × 48 point preview safe area.
- Adds rounded-rectangle clipping so glow and stroke effects cannot escape the tile boundary.
- Uses a restrained pearl-ivory and champagne gradient instead of the previous oversized bright band.

## Compatibility and scope

- The main Event Horizon artwork and motion in the popover, dashboard, and other interfaces are unchanged.
- Classic and Odyssey theme packs are unchanged.
- Token, cost, quota, leaderboard, updater, and local collection behavior are unchanged.

## Validation

- Swift unit suite: 107 tests, 0 failures.
- Deterministic Settings render checked at 1840 × 1904 pixels.
- Developer ID signing, Apple notarization, stapling, DMG validation, and isolated installer verification remain release gates.
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.7}"
VERSION="${TOKENSTEP_VERSION:-0.2.8}"
LAUNCH=true
VERIFY=false

Expand Down
4 changes: 2 additions & 2 deletions script/package_release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ SWIFT_DIR="$ROOT_DIR/TokenStepSwift"
BUILT_APP_BUNDLE="$SWIFT_DIR/dist/$APP_NAME.app"
APP_BUNDLE="$BUILT_APP_BUNDLE"
RELEASE_DIR="$ROOT_DIR/release"
VERSION="${TOKENSTEP_VERSION:-0.2.7}"
VERSION="${TOKENSTEP_VERSION:-0.2.8}"
IDENTITY="${CODE_SIGN_IDENTITY:-}"
NOTARIZE=false

usage() {
cat <<'USAGE'
Usage:
TOKENSTEP_VERSION=0.2.7 CODE_SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" ./script/package_release.sh [--notarize]
TOKENSTEP_VERSION=0.2.8 CODE_SIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" ./script/package_release.sh [--notarize]

Notarization credentials, choose one:
TOKENSTEP_NOTARY_PROFILE="notarytool-profile"
Expand Down
2 changes: 1 addition & 1 deletion script/render_popover_panel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ OVERLAY_DIR="$BUILD_DIR/vfs-overlay"
OVERLAY_FILE="$OVERLAY_DIR/overlay.yaml"
EMPTY_MODULEMAP="$OVERLAY_DIR/empty.modulemap"
EXECUTABLE="$BUILD_DIR/popover-panel-render"
OUTPUT_DIR="${1:-$ROOT_DIR/docs/validation/v0.2.7-theme-packs}"
OUTPUT_DIR="${1:-$ROOT_DIR/docs/validation/v0.2.8-theme-packs}"

mkdir -p "$BUILD_DIR" "$OVERLAY_DIR" "$OUTPUT_DIR"
cat > "$EMPTY_MODULEMAP" <<'EOF'
Expand Down
2 changes: 1 addition & 1 deletion script/render_voyage_interfaces.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ OVERLAY_DIR="$BUILD_DIR/vfs-overlay"
OVERLAY_FILE="$OVERLAY_DIR/overlay.yaml"
EMPTY_MODULEMAP="$OVERLAY_DIR/empty.modulemap"
EXECUTABLE="$BUILD_DIR/voyage-interface-render"
OUTPUT_DIR="${1:-$ROOT_DIR/docs/validation/v0.2.7-interstellar}"
OUTPUT_DIR="${1:-$ROOT_DIR/docs/validation/v0.2.8-interstellar}"

mkdir -p "$BUILD_DIR" "$OVERLAY_DIR" "$OUTPUT_DIR"
cat > "$EMPTY_MODULEMAP" <<'EOF'
Expand Down
Loading