feature: add name field in url scheme

This commit is contained in:
yichengchen 2019-09-14 18:05:36 +08:00
parent 7b34c45552
commit bf10ed494b
3 changed files with 103 additions and 75 deletions

View File

@ -86,10 +86,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
RemoteConfigManager.shared.autoUpdateCheck()
NSAppleEventManager.shared()
.setEventHandler(self,
andSelector: #selector(handleURL(event:reply:)),
forEventClass: AEEventClass(kInternetEventClass),
andEventID: AEEventID(kAEGetURL))
}
func applicationWillTerminate(_ aNotification: Notification) {
if ConfigManager.shared.proxyPortAutoSet {
let port = ConfigManager.shared.currentConfig?.port ?? 0
@ -97,32 +101,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
SystemProxyManager.shared.disableProxy(port: port, socksPort: socketPort)
}
}
func application(_ application: NSApplication, open urls: [URL]) {
guard let url = urls.first else {return}
guard let components = URLComponents(string: url.absoluteString),
let scheme = components.scheme,
scheme.hasPrefix("clash"),
let host = components.host
else {return}
if host == "install-config" {
guard let url = components.queryItems?.first(where: { item in
item.name == "url"
})?.value else {return}
remoteConfigAutoupdateMenuItem.menu?.performActionForItem(at: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
NotificationCenter.default.post(name: Notification.Name(rawValue: "didGetUrl"), object: nil, userInfo: ["url":url])
}
} else {
Logger.log(msg: "Unknown url host:\(components.path)")
}
}
func setupData() {
@ -531,7 +509,7 @@ extension AppDelegate {
}
// MARK: NSMenuDelegate
extension AppDelegate:NSMenuDelegate {
extension AppDelegate: NSMenuDelegate {
func menuWillOpen(_ menu: NSMenu) {
}
@ -539,6 +517,39 @@ extension AppDelegate:NSMenuDelegate {
syncConfig()
updateConfigFiles()
}
}
// MARK: URL Scheme
extension AppDelegate {
@objc func handleURL(event: NSAppleEventDescriptor, reply: NSAppleEventDescriptor) {
guard let url = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue else {
return
}
guard let components = URLComponents(string: url),
let scheme = components.scheme,
scheme.hasPrefix("clash"),
let host = components.host
else {return}
if host == "install-config" {
guard let url = components.queryItems?.first(where: { item in
item.name == "url"
})?.value else {return}
var userInfo = ["url":url]
if let name = components.queryItems?.first(where: { item in
item.name == "name"
})?.value {
userInfo["name"] = name
}
remoteConfigAutoupdateMenuItem.menu?.performActionForItem(at: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
NotificationCenter.default.post(name: Notification.Name(rawValue: "didGetUrl"), object: nil, userInfo: userInfo)
}
}
}
}

View File

@ -557,52 +557,63 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EbX-pj-Cz7">
<rect key="frame" x="14" y="13" width="80" height="32"/>
<buttonCell key="cell" type="push" title="Delete" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yGD-AG-oYU">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="actionDelete:" target="6WI-Hi-v9j" id="5yg-pq-0Lj"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b6c-1B-tE6">
<rect key="frame" x="97" y="13" width="85" height="32"/>
<buttonCell key="cell" type="push" title="Update" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="2Rx-ih-aGW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="actionUpdate:" target="6WI-Hi-v9j" id="Gat-ro-9Mu"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tAe-1Z-RnG">
<rect key="frame" x="185" y="13" width="65" height="32"/>
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="51K-nB-xLS">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="actionAdd:" target="6WI-Hi-v9j" id="wbk-Q8-U0x"/>
</connections>
</button>
<stackView distribution="fillEqually" orientation="horizontal" alignment="top" spacing="5" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kIY-Fj-jYe">
<rect key="frame" x="21" y="20" width="229" height="21"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tAe-1Z-RnG">
<rect key="frame" x="-6" y="-7" width="85" height="32"/>
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="51K-nB-xLS">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="actionAdd:" target="6WI-Hi-v9j" id="wbk-Q8-U0x"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b6c-1B-tE6">
<rect key="frame" x="72" y="-7" width="85" height="32"/>
<buttonCell key="cell" type="push" title="Update" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="2Rx-ih-aGW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="actionUpdate:" target="6WI-Hi-v9j" id="Gat-ro-9Mu"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EbX-pj-Cz7">
<rect key="frame" x="150" y="-7" width="85" height="32"/>
<buttonCell key="cell" type="push" title="Delete" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="yGD-AG-oYU">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="actionDelete:" target="6WI-Hi-v9j" id="5yg-pq-0Lj"/>
</connections>
</button>
</subviews>
<visibilityPriorities>
<real value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</subviews>
<constraints>
<constraint firstItem="kIY-Fj-jYe" firstAttribute="top" secondItem="LqM-v5-9Fo" secondAttribute="bottom" constant="20" id="3zQ-nf-oHX"/>
<constraint firstItem="P7n-N0-pkv" firstAttribute="leading" secondItem="BIo-GY-n0C" secondAttribute="leading" constant="20" id="5pq-wP-XDV"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="tAe-1Z-RnG" secondAttribute="trailing" constant="20" symbolic="YES" id="6x0-FS-c0n"/>
<constraint firstItem="EbX-pj-Cz7" firstAttribute="top" secondItem="LqM-v5-9Fo" secondAttribute="bottom" constant="20" id="AcW-uf-8fR"/>
<constraint firstItem="b6c-1B-tE6" firstAttribute="leading" secondItem="EbX-pj-Cz7" secondAttribute="trailing" constant="15" id="HSO-PF-eun"/>
<constraint firstAttribute="bottom" secondItem="kIY-Fj-jYe" secondAttribute="bottom" constant="20" id="9YC-cZ-0XT"/>
<constraint firstItem="LqM-v5-9Fo" firstAttribute="top" secondItem="P7n-N0-pkv" secondAttribute="bottom" constant="20" id="JZz-kk-xXU"/>
<constraint firstItem="tAe-1Z-RnG" firstAttribute="leading" secondItem="b6c-1B-tE6" secondAttribute="trailing" constant="15" id="K6N-pX-Ldv"/>
<constraint firstItem="b6c-1B-tE6" firstAttribute="top" secondItem="EbX-pj-Cz7" secondAttribute="top" id="S0W-el-lR1"/>
<constraint firstAttribute="bottom" secondItem="EbX-pj-Cz7" secondAttribute="bottom" constant="20" id="UnV-5P-AS9"/>
<constraint firstItem="kIY-Fj-jYe" firstAttribute="leading" secondItem="I57-0R-Jyy" secondAttribute="leading" id="Pun-QQ-BIZ"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="P7n-N0-pkv" secondAttribute="trailing" constant="20" symbolic="YES" id="Y8u-oJ-fWE"/>
<constraint firstItem="P7n-N0-pkv" firstAttribute="top" secondItem="BIo-GY-n0C" secondAttribute="top" constant="20" id="dyb-pn-Moi"/>
<constraint firstItem="tAe-1Z-RnG" firstAttribute="top" secondItem="b6c-1B-tE6" secondAttribute="top" id="lQA-HM-luH"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kIY-Fj-jYe" secondAttribute="trailing" id="kr2-IE-r4l"/>
<constraint firstItem="LqM-v5-9Fo" firstAttribute="leading" secondItem="BIo-GY-n0C" secondAttribute="leading" constant="20" id="nbe-A2-uN7"/>
<constraint firstAttribute="trailing" secondItem="LqM-v5-9Fo" secondAttribute="trailing" constant="20" id="w3r-DJ-wwf"/>
<constraint firstItem="EbX-pj-Cz7" firstAttribute="leading" secondItem="BIo-GY-n0C" secondAttribute="leading" constant="20" id="yc1-QL-Gs0"/>
</constraints>
</view>
<connections>

View File

@ -29,10 +29,12 @@ class RemoteConfigViewController: NSViewController {
NotificationCenter.default
.rx.notification(Notification.Name("didGetUrl")).bind {
[weak self] (note) in
guard let self = self else {return}
guard let url = note.userInfo?["url"] as? String else {return}
self.showAdd(defaultUrl: url)
[weak self] (note) in
guard let self = self else {return}
guard let url = note.userInfo?["url"] as? String else {return}
let name = note.userInfo?["name"] as? String
self.showAdd(defaultUrl: url, name:name)
}.disposed(by: disposeBag)
}
@ -77,14 +79,14 @@ extension RemoteConfigViewController {
updateButton.isEnabled = !config.updating
}
func showAdd(defaultUrl: String? = nil) {
func showAdd(defaultUrl: String? = nil, name: String? = nil) {
let alertView = NSAlert()
alertView.addButton(withTitle: NSLocalizedString("OK", comment: ""))
alertView.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
alertView.messageText = NSLocalizedString("Add a remote config", comment: "")
let remoteConfigInputView = RemoteConfigAddView.createFromNib()!
if let defaultUrl = defaultUrl {
remoteConfigInputView.setUrl(string: defaultUrl)
remoteConfigInputView.setUrl(string: defaultUrl, name: name)
}
alertView.accessoryView = remoteConfigInputView
let response = alertView.runModal()
@ -208,9 +210,13 @@ class RemoteConfigAddView: NSView, NibLoadable {
return isUrlVaild() && getConfigName().count > 0
}
func setUrl(string: String) {
func setUrl(string: String, name: String?) {
urlTextField.stringValue = string
updateConfigName()
if let name = name, name.count > 0 {
configNameTextField.placeholderString = name
} else {
updateConfigName()
}
}
private func isUrlVaild() -> Bool {