2018-08-04 21:49:32 +08:00
|
|
|
//
|
2018-11-30 22:14:20 +08:00
|
|
|
// MenuItemFactory.swift
|
2018-08-04 21:49:32 +08:00
|
|
|
// ClashX
|
|
|
|
//
|
|
|
|
// Created by CYC on 2018/8/4.
|
2018-08-08 13:47:38 +08:00
|
|
|
// Copyright © 2018年 yichengchen. All rights reserved.
|
2018-08-04 21:49:32 +08:00
|
|
|
//
|
|
|
|
|
|
|
|
import Cocoa
|
|
|
|
import SwiftyJSON
|
|
|
|
import RxCocoa
|
|
|
|
|
2018-11-30 22:14:20 +08:00
|
|
|
class MenuItemFactory {
|
2018-08-04 21:49:32 +08:00
|
|
|
static func menuItems(completionHandler:@escaping (([NSMenuItem])->())){
|
|
|
|
ApiRequest.requestProxyGroupList { (res) in
|
|
|
|
let dataDict = JSON(res)
|
|
|
|
var menuItems = [NSMenuItem]()
|
2018-08-04 23:41:28 +08:00
|
|
|
if (ConfigManager.shared.currentConfig?.mode == .direct) {
|
|
|
|
completionHandler(menuItems)
|
|
|
|
return
|
|
|
|
}
|
2018-08-08 20:10:15 +08:00
|
|
|
for proxyGroup in dataDict.dictionaryValue.sorted(by: { $0.0 < $1.0}) {
|
2018-08-05 19:45:37 +08:00
|
|
|
var menu:NSMenuItem?
|
|
|
|
switch proxyGroup.value["type"].stringValue {
|
2018-08-11 12:18:57 +08:00
|
|
|
case "Selector": menu = self.generateSelectorMenuItem(json: dataDict, key: proxyGroup.key)
|
2018-10-02 12:25:53 +08:00
|
|
|
case "URLTest","Fallback": menu = self.generateUrlTestMenuItem(proxyGroup: proxyGroup)
|
2019-02-15 22:47:17 +08:00
|
|
|
case "LoadBalance":
|
|
|
|
menu = self.generateLoadBalanceMenuItem(proxyGroup: proxyGroup)
|
|
|
|
|
2018-08-05 19:45:37 +08:00
|
|
|
default: continue
|
2018-08-04 23:41:28 +08:00
|
|
|
}
|
2018-08-05 19:45:37 +08:00
|
|
|
if (menu != nil) {menuItems.append(menu!)}
|
2018-08-04 23:41:28 +08:00
|
|
|
|
2018-08-04 21:49:32 +08:00
|
|
|
}
|
2018-08-04 22:09:11 +08:00
|
|
|
completionHandler(menuItems.reversed())
|
2018-08-04 21:49:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-11 12:18:57 +08:00
|
|
|
static func generateSelectorMenuItem(json:JSON,key:String)->NSMenuItem? {
|
|
|
|
let proxyGroup:(key: String, value: JSON) = (key,json[key])
|
|
|
|
let isGlobalMode = ConfigManager.shared.currentConfig?.mode == .global
|
|
|
|
if (isGlobalMode) {
|
2018-08-05 19:45:37 +08:00
|
|
|
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)
|
2018-08-11 14:02:34 +08:00
|
|
|
var hasSelected = false
|
2018-11-04 17:20:25 +08:00
|
|
|
submenu.minimumWidth = 20
|
2018-08-08 20:10:15 +08:00
|
|
|
for proxy in proxyGroup.value["all"].arrayValue {
|
2018-08-11 12:18:57 +08:00
|
|
|
if isGlobalMode {
|
|
|
|
if json[proxy.stringValue]["type"] == "Selector" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
2018-10-02 12:05:55 +08:00
|
|
|
|
2019-02-18 21:38:34 +08:00
|
|
|
let proxyItem = ProxyMenuItem(proxyName: proxy.stringValue, action: #selector(MenuItemFactory.actionSelectProxy(sender:)))
|
|
|
|
|
2018-11-30 22:14:20 +08:00
|
|
|
proxyItem.target = MenuItemFactory.self
|
2019-02-18 21:38:34 +08:00
|
|
|
proxyItem.isSelected = proxy.stringValue == selectedName
|
2018-12-09 00:46:36 +08:00
|
|
|
|
2019-02-18 21:38:34 +08:00
|
|
|
let fittitingWidth = proxyItem.suggestWidth()
|
|
|
|
if fittitingWidth > submenu.minimumWidth {
|
|
|
|
submenu.minimumWidth = fittitingWidth
|
2018-11-04 17:20:25 +08:00
|
|
|
}
|
2018-12-09 00:46:36 +08:00
|
|
|
|
2019-02-18 21:38:34 +08:00
|
|
|
if proxyItem.isSelected {hasSelected = true}
|
2018-08-05 19:45:37 +08:00
|
|
|
submenu.addItem(proxyItem)
|
2018-10-19 23:32:36 +08:00
|
|
|
submenu.autoenablesItems = false
|
2018-12-09 00:46:36 +08:00
|
|
|
|
2018-11-04 17:20:25 +08:00
|
|
|
}
|
|
|
|
for item in submenu.items {
|
|
|
|
item.view?.frame.size.width = submenu.minimumWidth
|
2018-08-05 19:45:37 +08:00
|
|
|
}
|
|
|
|
menu.submenu = submenu
|
2018-08-11 14:02:34 +08:00
|
|
|
if (!hasSelected && submenu.items.count>0) {
|
2018-12-09 00:46:36 +08:00
|
|
|
self.actionSelectProxy(sender: submenu.items[0] as! ProxyMenuItem)
|
2018-08-11 14:02:34 +08:00
|
|
|
}
|
2018-08-05 19:45:37 +08:00
|
|
|
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: "")
|
2018-10-02 12:05:55 +08:00
|
|
|
|
2018-08-05 19:45:37 +08:00
|
|
|
submenu.addItem(nowMenuItem)
|
|
|
|
menu.submenu = submenu
|
|
|
|
return menu
|
|
|
|
}
|
|
|
|
|
2019-02-15 22:47:17 +08:00
|
|
|
static func generateLoadBalanceMenuItem(proxyGroup:(key: String, value: JSON))->NSMenuItem? {
|
|
|
|
let menu = NSMenuItem(title: proxyGroup.key, action: nil, keyEquivalent: "")
|
|
|
|
let submenu = NSMenu(title: proxyGroup.key)
|
|
|
|
|
|
|
|
for proxy in proxyGroup.value["all"].arrayValue {
|
2019-02-18 21:38:34 +08:00
|
|
|
let proxyItem = ProxyMenuItem(proxyName: proxy.stringValue, action: #selector(MenuItemFactory.actionSelectProxy(sender:)))
|
|
|
|
let fittitingWidth = proxyItem.suggestWidth()
|
|
|
|
if fittitingWidth > submenu.minimumWidth {
|
|
|
|
submenu.minimumWidth = fittitingWidth
|
2019-02-15 22:47:17 +08:00
|
|
|
}
|
|
|
|
submenu.addItem(proxyItem)
|
|
|
|
}
|
|
|
|
|
|
|
|
for item in submenu.items {
|
|
|
|
item.view?.frame.size.width = submenu.minimumWidth
|
|
|
|
}
|
|
|
|
menu.submenu = submenu
|
|
|
|
|
|
|
|
return menu
|
|
|
|
}
|
2018-11-30 22:14:20 +08:00
|
|
|
|
2018-12-01 22:57:39 +08:00
|
|
|
static func generateSwitchConfigSubMenu() -> NSMenu {
|
|
|
|
let subMenu = NSMenu(title: "Switch Configs")
|
2018-11-30 22:14:20 +08:00
|
|
|
for config in ConfigManager.getConfigFilesList() {
|
|
|
|
let item = NSMenuItem(title: config, action: #selector(MenuItemFactory.actionSelectConfig(sender:)), keyEquivalent: "")
|
|
|
|
item.target = MenuItemFactory.self
|
|
|
|
item.state = ConfigManager.selectConfigName == config ? .on : .off
|
2018-12-01 22:57:39 +08:00
|
|
|
subMenu.addItem(item)
|
2018-11-30 22:14:20 +08:00
|
|
|
}
|
2018-12-01 22:57:39 +08:00
|
|
|
return subMenu
|
2018-11-30 22:14:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extension MenuItemFactory {
|
2018-12-09 00:46:36 +08:00
|
|
|
@objc static func actionSelectProxy(sender:ProxyMenuItem){
|
2018-08-04 21:49:32 +08:00
|
|
|
guard let proxyGroup = sender.menu?.title else {return}
|
2018-12-09 00:46:36 +08:00
|
|
|
let proxyName = sender.proxyName
|
2018-08-04 21:49:32 +08:00
|
|
|
|
|
|
|
ApiRequest.updateProxyGroup(group: proxyGroup, selectProxy: proxyName) { (success) in
|
|
|
|
if (success) {
|
|
|
|
for items in sender.menu?.items ?? [NSMenuItem]() {
|
|
|
|
items.state = .off
|
|
|
|
}
|
|
|
|
sender.state = .on
|
2018-08-06 23:06:50 +08:00
|
|
|
// remember select proxy
|
|
|
|
ConfigManager.selectedProxyMap[proxyGroup] = proxyName
|
2018-08-04 21:49:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-30 22:14:20 +08:00
|
|
|
@objc static func actionSelectConfig(sender:NSMenuItem){
|
|
|
|
let config = sender.title
|
|
|
|
ConfigManager.selectConfigName = config
|
|
|
|
NotificationCenter.default.post(Notification(name: kShouldUpDateConfig))
|
|
|
|
}
|
2018-08-04 21:49:32 +08:00
|
|
|
}
|
2018-10-02 12:05:55 +08:00
|
|
|
|