diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e2aa57..bc40792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。 - 菜单栏弹窗改为紧凑排版,参照 Stats:区块不再是灰底卡片,改成一条细分隔线隔开,行距收紧,顶栏按钮缩小;网络弹窗的 IP 纯净度与 DNS 默认收起成一行(纯净度显示分数与等级,DNS 显示正在使用的地址),点一下展开、标题栏右侧的箭头收起,状态会记住;流量图变矮,连接探测改为两行细格。网络弹窗从约 1520pt 降到约 950pt,其他弹窗矮了一到两成。主窗口的详情页保持原样,照常完整显示。 +- IP 纯净度的标题行重新排版:置信度不再是带框的绿色徽章,改成标题旁一行浅灰小字,百分比按高低着色;“查看完整报告”文字链接换成外链图标,与刷新、收起并成一组按钮,macOS 26 上合成一颗玻璃胶囊。分数右侧的 cleanip.io 字标照旧可以打开完整报告。 - 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。 - 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。 diff --git a/Packages/OpenStatsKit/Sources/Localization/Translations.swift b/Packages/OpenStatsKit/Sources/Localization/Translations.swift index 0b9cf02..fa30aa3 100644 --- a/Packages/OpenStatsKit/Sources/Localization/Translations.swift +++ b/Packages/OpenStatsKit/Sources/Localization/Translations.swift @@ -84,6 +84,7 @@ VPN / 代理 VPN / Proxy VPN 隧道 VPN Tunnel Xcode 归档 Xcode Archives Xcode 编译缓存 Xcode Build Cache +cleanip.io 对这次评分的把握:各数据源结论越一致越高 How sure cleanip.io is about this score: the more its sources agree, the higher macOS 系统目录(系统组件) macOS system folder (system component) npm 缓存 npm Cache {} {} 英寸 {} {}-inch @@ -394,7 +395,6 @@ npm 缓存 npm Cache 安装失败:{} Install failed: {} 安装辅助工具 Install Helper 安静 Quiet -完整报告 Full report 定时 ping 一个地址,记录网络是否通畅 Pings an address regularly to record whether the network is reachable 定时探测网络 Connectivity Probe 家目录 Home folder @@ -642,7 +642,6 @@ npm 缓存 npm Cache 查看 View 查看全部进程 All Processes 查看包含的项目 Show items -查看完整报告 View full report 查看完整更新日志 Full Changelog 查看清理日志 View Cleanup Log 查询中… Looking up… @@ -871,7 +870,7 @@ npm 缓存 npm Cache 网络:{} Network: {} 网页数据 Web Data 网页缓存与脚本缓存,不涉及 Cookie、历史记录和密码 Web and script caches; cookies, history and passwords are untouched -置信度 {}% Confidence {}% +置信度 Confidence 联动 Wired 能效核 Efficiency 腾讯 DNSPod Tencent diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift index 31868c1..470d0d7 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/NetworkPopover.swift @@ -336,9 +336,6 @@ private struct PuritySection: View { @Environment(AppModel.self) private var model @Environment(\.isPopover) private var isPopover - /// 标题行里“查看完整报告”链接的三种长度 - enum ReportStyle { case full, short, icon } - var body: some View { // 菜单栏弹窗里默认收起成一行,只显示分数与等级 if isPopover, !model.settings.isExpanded(.networkPurity) { @@ -369,12 +366,7 @@ private struct PuritySection: View { let hint = tr("纯净度看信誉、来路、邻居与网络类型四项;机房 IP 常见信誉高、来路和类型偏低。数据来自 cleanip.io") Card(padding: DS.Space.s3, spacing: DS.Space.s2) { - // 标题、地址族徽章、置信度、报告链接、刷新按钮排成一行;宽度不够时报告链接依次缩成“完整报告”、只剩图标 - ViewThatFits(in: .horizontal) { - header(addresses, report: .full) - header(addresses, report: .short) - header(addresses, report: .icon) - } + header(addresses) if let purity = addresses?.purity { // 分数在左、cleanip.io 字标在右,色带在下占满整行 HStack(spacing: DS.Space.s2) { @@ -420,44 +412,54 @@ private struct PuritySection: View { } } - /// 标题行:IP 纯净度 · [IPv4] · [置信度 92%] · 查看完整报告 ↗ ……… ⟳ - private func header(_ addresses: PublicAddresses?, report: ReportStyle) -> some View { + /// 标题行:IP 纯净度 [IPv4] 置信度 92% ……… [↗ ⟳ ⌃] + /// 置信度是标题旁的一行浅色小字,不再用带框徽章;右侧的完整报告、刷新、收起并成一组按钮 + private func header(_ addresses: PublicAddresses?) -> some View { let network = model.network - // 320 宽的弹窗里这一行很挤:标题与徽章之间只留最小间距,右侧刷新按钮自带留白 - return HStack(spacing: DS.Space.s1) { + return HStack(spacing: DS.Space.s2) { Text(PopoverSection.networkPurity.title) .dsFont(.xs, weight: .semibold) .foregroundStyle(DS.Palette.textSecondary) .lineLimit(1) .fixedSize() - HStack(spacing: DS.Space.s1) { - if let family = network.shownFamily { - TagBadge(text: family.title, tone: .primary, compact: true) - } - if let confidence = addresses?.purity?.confidence { - TagBadge(text: tr("置信度 \(confidence)%"), tone: Self.confidenceTone(confidence), compact: true) - } + if let family = network.shownFamily { + TagBadge(text: family.title, tone: .primary, compact: true) } - if let url = addresses?.reportURL { - ReportLink(url: url, style: report).padding(.leading, DS.Space.s1) + if let confidence = addresses?.purity?.confidence { + HStack(spacing: DS.Space.s1 / 2) { + Text(tr("置信度")).foregroundStyle(DS.Palette.textTertiary) + Text(verbatim: "\(confidence)%") + .fontWeight(.medium) + .foregroundStyle(Self.confidenceColor(confidence)) + .monospacedDigit() + } + .dsFont(.xs) + .lineLimit(1) + .fixedSize() + .help(tr("cleanip.io 对这次评分的把握:各数据源结论越一致越高")) } Spacer(minLength: 0) - if isPopover { + HeaderActionGroup { + if let url = addresses?.reportURL { + MiniIconButton(systemName: "arrow.up.forward", help: tr("在 cleanip.io 查看这个 IP 的完整报告")) { + NSWorkspace.shared.open(url) + } + } RefreshButton(loading: network.isLookingUpPublic, help: tr("强制刷新:忽略缓存,立即重新查询公网 IP 与归属地")) { network.lookUpPublicAddresses(force: true) } - .collapseButton(.networkPurity, settings: model.settings) - } else { - RefreshButton(loading: network.isLookingUpPublic, help: tr("强制刷新:忽略缓存,立即重新查询公网 IP 与归属地")) { - network.lookUpPublicAddresses(force: true) + if isPopover { + MiniIconButton(systemName: "chevron.up", help: tr("收起")) { + withAnimation(DS.Motion.quick) { model.settings.setExpanded(.networkPurity, false) } + } } } } } /// 置信度高的绿、中等的灰、低的黄 - static func confidenceTone(_ confidence: Int) -> TagBadge.Tone { - confidence >= 80 ? .success : confidence >= 50 ? .neutral : .warning + static func confidenceColor(_ confidence: Int) -> Color { + confidence >= 80 ? DS.Palette.success : confidence >= 50 ? DS.Palette.textSecondary : DS.Palette.warning } static func riskLabel(_ raw: String) -> String { @@ -652,33 +654,3 @@ private struct NetworkProcessesSection: View { } } } - -/// 纯净度标题行里的“查看完整报告”链接;`icon` 只剩一个外链图标 -private struct ReportLink: View { - let url: URL - let style: PuritySection.ReportStyle - @State private var hovering = false - - var body: some View { - let help = tr("在 cleanip.io 查看这个 IP 的完整报告") - if style == .icon { - MiniIconButton(systemName: "arrow.up.forward.square", help: help) { NSWorkspace.shared.open(url) } - } else { - Button { NSWorkspace.shared.open(url) } label: { - HStack(spacing: DS.Space.s1 / 2) { - Text(style == .full ? tr("查看完整报告") : tr("完整报告")) - .dsFont(.xs, weight: .medium) - Image(systemName: "arrow.up.forward.square") - .font(.system(size: DS.TextSize.xs.rawValue, weight: .semibold)) - } - .foregroundStyle(hovering ? DS.Palette.primaryHover : DS.Palette.primary) - .lineLimit(1) - .fixedSize() - .contentShape(Rectangle()) - } - .buttonStyle(.plain) - .onHover { hovering = $0 } - .help(help) - } - } -} diff --git a/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/PopoverRootView.swift b/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/PopoverRootView.swift index 2ce1f4e..aea470f 100644 --- a/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/PopoverRootView.swift +++ b/Packages/OpenStatsKit/Sources/OpenStatsUI/Popover/PopoverRootView.swift @@ -246,12 +246,13 @@ struct MiniIconButton: View { } } -/// macOS 26 上是一颗小玻璃圆钮,更早的系统只有悬停底色 +/// macOS 26 上是一颗小玻璃圆钮,更早的系统、或已经在一组玻璃按钮里时只有悬停底色 private struct MiniIconSurface: ViewModifier { let hovering: Bool + @Environment(\.isInsideGlass) private var isInsideGlass func body(content: Content) -> some View { - if DS.Glass.isAvailable { + if DS.Glass.isAvailable, !isInsideGlass { content.dsGlass(in: Circle(), interactive: true) } else { content.background(hovering ? DS.Palette.surfaceHover : .clear, in: RoundedRectangle(cornerRadius: DS.Radius.sm)) @@ -259,6 +260,21 @@ private struct MiniIconSurface: ViewModifier { } } +/// 区块标题栏右侧的一组小图标按钮:macOS 26 上合成一颗玻璃胶囊(与访达工具栏的按钮分组一致), +/// 里面的按钮不再各自带玻璃;更早的系统是一条浅灰胶囊 +struct HeaderActionGroup: View { + @ViewBuilder var content: Content + + var body: some View { + HStack(spacing: 0) { + content + } + .padding(.horizontal, DS.Space.s1 / 2) + .environment(\.isInsideGlass, true) + .dsGlass(in: Capsule(), fallback: DS.Palette.track) + } +} + /// 区块标题栏里的刷新按钮:查询进行中换成系统的转圈,查完自动变回图标 struct RefreshButton: View { var loading: Bool diff --git a/README.md b/README.md index 2281fc7..c6c80e1 100644 --- a/README.md +++ b/README.md @@ -59,15 +59,16 @@ system language by default; switch it in Settings → General → Language. -Latest release **0.3.2** (2026-09-16) · **5** changes in development · [full changelog](CHANGELOG.md) (kept in Chinese) +Latest release **0.3.2** (2026-09-16) · **6** changes in development · [full changelog](CHANGELOG.md) (kept in Chinese)
-2026-09-16 · Unreleased · 4 style · 1 added +2026-09-16 · Unreleased · 5 style · 1 added **Style** - 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。 - 菜单栏弹窗改为紧凑排版,参照 Stats:区块不再是灰底卡片,改成一条细分隔线隔开,行距收紧,顶栏按钮缩小;网络弹窗的 IP 纯净度与 DNS 默认收起成一行(纯净度显示分数与等级,DNS 显示正在使用的地址),点一下展开、标题栏右侧的箭头收起,状态会记住;流量图变矮,连接探测改为两行细格。网络弹窗从约 1520pt 降到约 950pt,其他弹窗矮了一到两成。主窗口的详情页保持原样,照常完整显示。 +- IP 纯净度的标题行重新排版:置信度不再是带框的绿色徽章,改成标题旁一行浅灰小字,百分比按高低着色;“查看完整报告”文字链接换成外链图标,与刷新、收起并成一组按钮,macOS 26 上合成一颗玻璃胶囊。分数右侧的 cleanip.io 字标照旧可以打开完整报告。 - 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。 - 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。 diff --git a/README.zh-CN.md b/README.zh-CN.md index bfb066c..056734d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -55,15 +55,16 @@ CPU 不分性能核与能效核,部分功耗与频率读数可能不显示。 -最新版本 **0.3.2**(2026-09-16) · 开发中 **5** 项改动尚未发布 · [完整更新日志](CHANGELOG.md) +最新版本 **0.3.2**(2026-09-16) · 开发中 **6** 项改动尚未发布 · [完整更新日志](CHANGELOG.md)
-2026-09-16 · 未发布 · 样式 4 · 新增 1 +2026-09-16 · 未发布 · 样式 5 · 新增 1 **样式** - 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。 - 菜单栏弹窗改为紧凑排版,参照 Stats:区块不再是灰底卡片,改成一条细分隔线隔开,行距收紧,顶栏按钮缩小;网络弹窗的 IP 纯净度与 DNS 默认收起成一行(纯净度显示分数与等级,DNS 显示正在使用的地址),点一下展开、标题栏右侧的箭头收起,状态会记住;流量图变矮,连接探测改为两行细格。网络弹窗从约 1520pt 降到约 950pt,其他弹窗矮了一到两成。主窗口的详情页保持原样,照常完整显示。 +- IP 纯净度的标题行重新排版:置信度不再是带框的绿色徽章,改成标题旁一行浅灰小字,百分比按高低着色;“查看完整报告”文字链接换成外链图标,与刷新、收起并成一组按钮,macOS 26 上合成一颗玻璃胶囊。分数右侧的 cleanip.io 字标照旧可以打开完整报告。 - 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。 - 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。 diff --git a/project.yml b/project.yml index 26ff626..ec9b343 100644 --- a/project.yml +++ b/project.yml @@ -13,7 +13,7 @@ settings: SWIFT_VERSION: "6.0" MARKETING_VERSION: "0.3.2" # 构建号四位数字,每次 make build 加一;营销版本只在发布时用 Scripts/version.sh patch / minor 修改 - CURRENT_PROJECT_VERSION: "0070" + CURRENT_PROJECT_VERSION: "0078" MACOSX_DEPLOYMENT_TARGET: "14.0" # 本地开发使用 ad-hoc 签名;发布时改为 Developer ID(见 docs/PLAN.md) CODE_SIGN_STYLE: Manual