import SwiftUI /// Observes the latest connectivity measurements and testing progress. struct ConnectivityCell: View { @ObservedObject var module: ServerConnectivity let node: CatalogTreeNode let workflow: CatalogWorkflow var selected = false var body: some View { let value = presentation() HStack(spacing: 5) { Text(value.text) .foregroundStyle( selected ? AnyShapeStyle(Color(nsColor: .alternateSelectedControlTextColor)) : AnyShapeStyle(.primary)) if value.testing { ProgressView().controlSize(.mini) .tint(selected ? Color(nsColor: .alternateSelectedControlTextColor) : nil) } } .help(value.help) .accessibilityElement(children: .ignore) .accessibilityLabel(Text(ConnectivityCopy.text("响应延迟"))) .accessibilityValue( Text( value.text + " " + value.help + (value.testing ? " " + ConnectivityCopy.text("测试中") : "")) ) } private struct Presentation { let text: String let help: String let testing: Bool } private func presentation() -> Presentation { let record: ServerConnectivity.Record? let text: String var prefix = "" let summary = module.summary(for: node.connectivityServerIDs) if node.isGroup { record = summary.record text = record.map { ConnectivityCopy.outcome($0.outcome) } ?? (summary.hasResults ? "—" : "") if let id = summary.serverID { prefix = workflow.displayName(for: id) + " · " } } else { record = module.history(for: node.id).first text = record.map { ConnectivityCopy.outcome($0.outcome) } ?? "" } let help = record.map { prefix + $0.finishedAt.formatted(date: .numeric, time: .standard) } ?? (summary.hasResults && node.isGroup ? ConnectivityCopy.text("无成功结果") : ConnectivityCopy.text("尚未测试")) return Presentation(text: text, help: help, testing: summary.isTesting) } } struct ConnectivityTestButton: View { @ObservedObject var module: ServerConnectivity let node: CatalogTreeNode var body: some View { let isTesting = node.connectivityServerIDs.contains { module.testing.contains($0) } Button(ConnectivityCopy.text(isTesting ? "测试中..." : "延迟测试")) { module.test(node.connectivityServerIDs) } .disabled( isTesting || !node.containsServerConfiguration || (!node.isGroup && module.isCooling(node.id)) ) } } /// Copy is kept at the presentation edge; failures never render raw errors or URLs. enum ConnectivityCopy { static func text(_ key: String) -> String { NSLocalizedString(key, tableName: "Connectivity", bundle: .main, comment: "") } static func outcome(_ value: ServerConnectivity.Outcome) -> String { switch value { case .success(let milliseconds): "\(milliseconds) ms" case .unsupported: text("配置不支持") case .preparationTimeout: text("准备超时") case .requestTimeout: text("请求超时") case .configuration: text("配置错误") case .startup: text("启动错误") case .network: text("网络错误") case .http(let status): "HTTP \(status)" } } }