Skip to content
Open
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
80 changes: 79 additions & 1 deletion ClashX/Views/ProxyGroupSpeedTestMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,39 @@ class ProxyGroupSpeedTestMenuItem: NSMenuItem {

@objc func healthCheck() {
guard testType == .reTest else { return }
ApiRequest.getGroupDelay(groupName: proxyGroup.name) { _ in }

// Clear existing speed test results for all proxies in this group
ApiRequest.getMergedProxyData { [weak self] proxyResp in
guard let self = self else { return }
var proxiesToClear = [ClashProxyName]()

// Get all proxy names in this group
if let allProxies = self.proxyGroup.all {
proxiesToClear.append(contentsOf: allProxies)
}

// Clear speed test results by posting notifications with empty values
for proxyName in proxiesToClear {
NotificationCenter.default.post(name: .speedTestFinishForProxy,
object: nil,
userInfo: ["proxyName": proxyName, "delay": "", "rawValue": 0])
}

// Start actual testing after clearing results
ApiRequest.healthCheck(proxy: self.proxyGroup.name)
ApiRequest.getMergedProxyData { [weak self] proxyResp in
guard let self = self else { return }
var providers = Set<ClashProxyName>()
self.proxyGroup.all?.compactMap{
proxyResp?.proxiesMap[$0]?.enclosingProvider?.name
}.forEach{
providers.insert($0)
}
providers.forEach{
ApiRequest.healthCheck(proxy: $0)
}
}
}
menu?.cancelTracking()
}
}
Expand Down Expand Up @@ -89,11 +121,57 @@ private class ProxyGroupSpeedTestMenuItemView: MenuItemBaseView {
private func startBenchmark() {
guard let group = (enclosingMenuItem as? ProxyGroupSpeedTestMenuItem)?.proxyGroup
else { return }
let testGroup = DispatchGroup()

var proxies = [ClashProxyName]()
var providers = Set<ClashProviderName>()
for testable in group.speedtestAble {
switch testable {
case let .provider(_, provider):
providers.insert(provider)
case let .proxy(name):
proxies.append(name)
default:
continue
}
}

// First, show "Testing" state and disable the menu item
label.stringValue = NSLocalizedString("Testing", comment: "")
enclosingMenuItem?.isEnabled = false
setNeedsDisplay()

// Then clear existing speed test results for all proxies in this group
ApiRequest.getMergedProxyData { [weak self] proxyResp in
guard let self = self else { return }

var proxiesToClear = [ClashProxyName]()

// Get all proxy names in this group
if let allProxies = group.all {
proxiesToClear.append(contentsOf: allProxies)
}

// Clear speed test results by posting notifications with empty values
for proxyName in proxiesToClear {
NotificationCenter.default.post(name: .speedTestFinishForProxy,
object: nil,
userInfo: ["proxyName": proxyName, "delay": "", "rawValue": 0])
}

// Start actual testing after clearing results
for proxyName in proxies {
testGroup.enter()
ApiRequest.getProxyDelay(proxyName: proxyName) { delay in
let delayStr = delay == 0 ? NSLocalizedString("fail", comment: "") : "\(delay) ms"
NotificationCenter.default.post(name: .speedTestFinishForProxy,
object: nil,
userInfo: ["proxyName": proxyName, "delay": delayStr, "rawValue": delay])
testGroup.leave()
}
}
}

ApiRequest.getGroupDelay(groupName: group.name) {
[weak self] delays in
guard let self = self, let menu = self.enclosingMenuItem else { return }
Expand Down
11 changes: 10 additions & 1 deletion ClashX/Views/ProxyItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,18 @@ class ProxyItemView: MenuItemBaseView {
delayLabel.stringValue = str ?? ""
needsLayout = true

guard let delay = value, str != nil else {
guard let delay = value, let delayStr = str else {
delayLabel.layer?.backgroundColor = NSColor.clear.cgColor
return
}

if delayStr.isEmpty {
// Testing state - show gray badge
delayLabel.stringValue = NSLocalizedString("Testing", comment: "")
delayLabel.layer?.backgroundColor = CGColor.testing
return
}

switch delay {
case 0:
delayLabel.layer?.backgroundColor = CGColor.fail
Expand Down Expand Up @@ -134,4 +142,5 @@ private extension CGColor {
static let good = CGColor(red: 30.0 / 255, green: 181.0 / 255, blue: 30.0 / 255, alpha: 1)
static let meduim = CGColor(red: 1, green: 135.0 / 255, blue: 0, alpha: 1)
static let fail = CGColor(red: 218.0 / 255, green: 0.0, blue: 3.0 / 255, alpha: 1)
static let testing = CGColor(red: 128.0 / 255, green: 128.0 / 255, blue: 128.0 / 255, alpha: 1)
}