IP 纯净度标题行重新排版:置信度改为浅色小字,完整报告、刷新、收起并成一组按钮

- 置信度不再是带框徽章,改为标题旁的 12pt 浅灰文字,百分比按高低着色(confidenceTone → confidenceColor)
- “查看完整报告 / 完整报告”文字链接与 ReportLink、ReportStyle、ViewThatFits 三档标题行一并去掉,改为外链图标
- 新增 HeaderActionGroup:一组小图标按钮在 macOS 26 上合成一颗玻璃胶囊,更早系统为浅灰胶囊;组内的 MiniIconButton 不再各自带玻璃
- 译文与更新日志同步
This commit is contained in:
gentpan committed 2026-09-16 19:32:11 +05:00
1 parent 4099ec636e
commit 84542374bc
7 files changed
+59 -69

No files matched your search

@@ -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
@@ -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)
}
}
}
@@ -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<Content: View>: 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