Feature: support urltest rule status display in menu

This commit is contained in:
yicheng 2018-08-05 19:45:37 +08:00
parent ce19c5202f
commit 4e0c96bc52
5 changed files with 58 additions and 25 deletions

View File

@ -39,6 +39,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
PFMoveToApplicationsFolderIfNecessary()
self.startProxy()
statusItemView = StatusItemView.create(statusItem: nil,statusMenu: statusMenu)
statusItemView.onPopUpMenuAction = {
[weak self] in
guard let `self` = self else {return}
self.updateProxyList()
}
setupData()
}
@ -112,12 +117,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func updateProxyList() {
ProxyMenuItemFactory.menuItems { [unowned self] (menus) in
let startIndex = self.statusMenu.items.index(of: self.separatorLineTop)! + 1
let endIndex = self.statusMenu.items.index(of: self.sepatatorLineEndProxySelect)!
let endIndex = self.statusMenu.items.index(of: self.sepatatorLineEndProxySelect)! - 1
var items = self.statusMenu.items
for idx in startIndex ..< endIndex {
items.remove(at: idx)
}
items.removeSubrange(ClosedRange(uncheckedBounds: (lower: startIndex, upper: endIndex)))
for each in menus {
items.insert(each, at: startIndex)
}

View File

@ -16,17 +16,20 @@ class ConfigFileFactory {
proxyStr.append(targetStr)
proxyGroupStr.append("\(proxy.remark),")
}
proxyGroupStr = String(proxyGroupStr.dropLast())
let sampleConfig = NSData(contentsOfFile: Bundle.main.path(forResource: "sampleConfig", ofType: "ini")!)
var sampleConfigStr = String(data: sampleConfig! as Data, encoding: .utf8)
sampleConfigStr = sampleConfigStr?.replacingOccurrences(of: "{{ProxyPlaceHolder}}", with: proxyStr)
sampleConfigStr = sampleConfigStr?.replacingOccurrences(of: "{{ProxyGroupPlaceHolder}}", with: proxyGroupStr)
if proxies.count > 1 {
let autoGroupStr = "ProxyAuto = url-test, \(proxyGroupStr), http://www.google.com/generate_204, 300"
sampleConfigStr = sampleConfigStr?.replacingOccurrences(of: "{{ProxyAutoGroupPlaceHolder}}", with: autoGroupStr)
proxyGroupStr.append("ProxyAuto,")
}
proxyGroupStr = String(proxyGroupStr.dropLast())
sampleConfigStr = sampleConfigStr?.replacingOccurrences(of: "{{ProxyPlaceHolder}}", with: proxyStr)
sampleConfigStr = sampleConfigStr?.replacingOccurrences(of: "{{ProxyGroupPlaceHolder}}", with: proxyGroupStr)
return sampleConfigStr!
}

View File

@ -21,30 +21,51 @@ class ProxyMenuItemFactory {
}
for proxyGroup in dataDict.dictionaryValue {
guard proxyGroup.value["type"].stringValue == "Selector" else {continue}
if (ConfigManager.shared.currentConfig?.mode == .global) {
if proxyGroup.key != "GLOBAL" {continue}
} else {
if proxyGroup.key == "GLOBAL" {continue}
var menu:NSMenuItem?
switch proxyGroup.value["type"].stringValue {
case "Selector": menu = self.generateSelectorMenuItem(proxyGroup: proxyGroup)
case "URLTest": menu = self.generateUrlTestMenuItem(proxyGroup: proxyGroup)
default: continue
}
if (menu != nil) {menuItems.append(menu!)}
let menu = NSMenuItem(title: proxyGroup.key, action: nil, keyEquivalent: "")
let selectedName = proxyGroup.value["now"].stringValue
let submenu = NSMenu(title: proxyGroup.key)
for proxy in proxyGroup.value["all"].arrayValue.reversed() {
let proxyItem = NSMenuItem(title: proxy.stringValue, action: #selector(ProxyMenuItemFactory.actionSelectProxy(sender:)), keyEquivalent: "")
proxyItem.target = ProxyMenuItemFactory.self
proxyItem.state = proxy.stringValue == selectedName ? .on : .off
submenu.addItem(proxyItem)
}
menu.submenu = submenu
menuItems.append(menu);
}
completionHandler(menuItems.reversed())
}
}
static func generateSelectorMenuItem(proxyGroup:(key: String, value: JSON))->NSMenuItem? {
if (ConfigManager.shared.currentConfig?.mode == .global) {
if proxyGroup.key != "GLOBAL" {return nil}
} else {
if proxyGroup.key == "GLOBAL" {return nil}
}
let menu = NSMenuItem(title: proxyGroup.key, action: nil, keyEquivalent: "")
let selectedName = proxyGroup.value["now"].stringValue
let submenu = NSMenu(title: proxyGroup.key)
for proxy in proxyGroup.value["all"].arrayValue.reversed() {
let proxyItem = NSMenuItem(title: proxy.stringValue, action: #selector(ProxyMenuItemFactory.actionSelectProxy(sender:)), keyEquivalent: "")
proxyItem.target = ProxyMenuItemFactory.self
proxyItem.state = proxy.stringValue == selectedName ? .on : .off
submenu.addItem(proxyItem)
}
menu.submenu = submenu
return menu
}
static func generateUrlTestMenuItem(proxyGroup:(key: String, value: JSON))->NSMenuItem? {
let menu = NSMenuItem(title: proxyGroup.key, action: nil, keyEquivalent: "")
let selectedName = proxyGroup.value["now"].stringValue
let submenu = NSMenu(title: proxyGroup.key)
let nowMenuItem = NSMenuItem(title: "now:\(selectedName)", action: nil, keyEquivalent: "")
submenu.addItem(nowMenuItem)
menu.submenu = submenu
return menu
}
@objc static func actionSelectProxy(sender:NSMenuItem){
guard let proxyGroup = sender.menu?.title else {return}
let proxyName = sender.title

View File

@ -8,13 +8,15 @@ external-controller = 127.0.0.1:8080
{{ProxyPlaceHolder}}
[Proxy Group]
Proxy = select, {{ProxyGroupPlaceHolder}}
# url-test select which proxy will be used by benchmarking speed to a URL.
# name = url-test, [proxys], url, interval(second)
{{ProxyAutoGroupPlaceHolder}}
Proxy = select, {{ProxyGroupPlaceHolder}}
[Rule]

View File

@ -17,6 +17,8 @@ class StatusItemView: NSView {
@IBOutlet weak var speedContainerView: NSView!
weak var statusItem:NSStatusItem?
var onPopUpMenuAction:(()->())? = nil
static func create(statusItem:NSStatusItem?,statusMenu:NSMenu)->StatusItemView{
var topLevelObjects : NSArray?
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: "StatusItemView"), owner: self, topLevelObjects: &topLevelObjects) {
@ -57,6 +59,7 @@ class StatusItemView: NSView {
}
override func mouseDown(with event: NSEvent) {
onPopUpMenuAction?()
statusItem?.popUpMenu(self.menu!)
}
}