From a156fec25ade8629a9fe880cd34fb8011d58080e Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Thu, 30 Jun 2016 21:24:45 -0700 Subject: put node ID into the main menu. Clicking on the menu item copies the node ID into the clipboard. --- ZeroTier One.xcodeproj/project.pbxproj | 4 +++ ZeroTier One/AppDelegate.swift | 26 +++++++++++++-- ZeroTier One/NetworkMonitor.swift | 9 ++++++ ZeroTier One/NodeStatus.swift | 59 ++++++++++++++++++++++++++++++++++ ZeroTier One/ServiceCom.swift | 34 ++++++++++++++++++++ 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 ZeroTier One/NodeStatus.swift diff --git a/ZeroTier One.xcodeproj/project.pbxproj b/ZeroTier One.xcodeproj/project.pbxproj index 9bf8375e..7bda3950 100644 --- a/ZeroTier One.xcodeproj/project.pbxproj +++ b/ZeroTier One.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 932D47361D1CDC9B004BCFE2 /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 932D47341D1CDC9B004BCFE2 /* AboutViewController.swift */; }; 932D47371D1CDC9B004BCFE2 /* AboutViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 932D47351D1CDC9B004BCFE2 /* AboutViewController.xib */; }; 932D473A1D220D63004BCFE2 /* LaunchAtLoginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 932D47391D220D63004BCFE2 /* LaunchAtLoginController.m */; }; + 932D473C1D261ED4004BCFE2 /* NodeStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 932D473B1D261ED4004BCFE2 /* NodeStatus.swift */; }; 9330F1351CEAB4C400687EC8 /* ServiceCom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330F1341CEAB4C400687EC8 /* ServiceCom.swift */; }; 9330F1371CEBF87200687EC8 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330F1361CEBF87200687EC8 /* Network.swift */; }; 9330F13B1CF534E500687EC8 /* NetworkInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9330F13A1CF534E500687EC8 /* NetworkInfoCell.swift */; }; @@ -36,6 +37,7 @@ 932D47351D1CDC9B004BCFE2 /* AboutViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AboutViewController.xib; sourceTree = ""; }; 932D47381D220D63004BCFE2 /* LaunchAtLoginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchAtLoginController.h; sourceTree = ""; }; 932D47391D220D63004BCFE2 /* LaunchAtLoginController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LaunchAtLoginController.m; sourceTree = ""; }; + 932D473B1D261ED4004BCFE2 /* NodeStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeStatus.swift; sourceTree = ""; }; 9330F1341CEAB4C400687EC8 /* ServiceCom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceCom.swift; sourceTree = ""; }; 9330F1361CEBF87200687EC8 /* Network.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; 9330F13A1CF534E500687EC8 /* NetworkInfoCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkInfoCell.swift; sourceTree = ""; }; @@ -105,6 +107,7 @@ 932D47351D1CDC9B004BCFE2 /* AboutViewController.xib */, 932D47381D220D63004BCFE2 /* LaunchAtLoginController.h */, 932D47391D220D63004BCFE2 /* LaunchAtLoginController.m */, + 932D473B1D261ED4004BCFE2 /* NodeStatus.swift */, ); path = "ZeroTier One"; sourceTree = ""; @@ -189,6 +192,7 @@ 932D47321D1CD861004BCFE2 /* PreferencesViewController.swift in Sources */, 932D473A1D220D63004BCFE2 /* LaunchAtLoginController.m in Sources */, 93326BDC1CE7C816005CA2AC /* AppDelegate.swift in Sources */, + 932D473C1D261ED4004BCFE2 /* NodeStatus.swift in Sources */, 93DAFE4B1CFE53CA00547CC4 /* AuthtokenCopy.m in Sources */, 9330F13B1CF534E500687EC8 /* NetworkInfoCell.swift in Sources */, 93326BEA1CE7D9B9005CA2AC /* JoinNetworkViewController.swift in Sources */, diff --git a/ZeroTier One/AppDelegate.swift b/ZeroTier One/AppDelegate.swift index 887bab56..584b54ae 100644 --- a/ZeroTier One/AppDelegate.swift +++ b/ZeroTier One/AppDelegate.swift @@ -27,7 +27,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { var networks = [Network]() + var status: NodeStatus? = nil + + var pasteboard = NSPasteboard.generalPasteboard() + func applicationDidFinishLaunching(aNotification: NSNotification) { + pasteboard.declareTypes([NSPasteboardTypeString], owner: nil) let defaults = NSUserDefaults.standardUserDefaults() let defaultsDict = ["firstRun": true] @@ -47,10 +52,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { } - - let nc = NSNotificationCenter.defaultCenter() nc.addObserver(self, selector: #selector(onNetworkListUpdated(_:)), name: networkUpdateKey, object: nil) + nc.addObserver(self, selector: #selector(onNodeStatusUpdated(_:)), name: statusUpdateKey, object: nil) statusItem.image = NSImage(named: "MenuBarIconMac") @@ -161,9 +165,21 @@ class AppDelegate: NSObject, NSApplicationDelegate { buildMenu() } + func onNodeStatusUpdated(note: NSNotification) { + let status = note.userInfo!["status"] as! NodeStatus + self.status = status + + buildMenu() + } + func buildMenu() { let menu = NSMenu() + if let s = self.status { + menu.addItem(NSMenuItem(title: "Node ID: \(s.address)", action: #selector(AppDelegate.copyNodeID), keyEquivalent: "")) + menu.addItem(NSMenuItem.separatorItem()) + } + menu.addItem(NSMenuItem(title: "Network Details...", action: #selector(AppDelegate.showNetworks), keyEquivalent: "n")) menu.addItem(NSMenuItem(title: "Join Network...", action: #selector(AppDelegate.joinNetwork), keyEquivalent: "j")) menu.addItem(NSMenuItem.separatorItem()) @@ -224,5 +240,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { ServiceCom.joinNetwork(id) } } + + func copyNodeID() { + if let s = self.status { + pasteboard.setString(s.address, forType: NSPasteboardTypeString) + } + } } diff --git a/ZeroTier One/NetworkMonitor.swift b/ZeroTier One/NetworkMonitor.swift index c81ac47d..2071fbbb 100644 --- a/ZeroTier One/NetworkMonitor.swift +++ b/ZeroTier One/NetworkMonitor.swift @@ -9,6 +9,7 @@ import Cocoa let networkUpdateKey = "com.zerotier.one.network-list" +let statusUpdateKey = "com.zerotier.one.status" class NetworkMonitor: NSObject { @@ -58,6 +59,14 @@ class NetworkMonitor: NSObject { self.internal_updateNetworkInfo() } } + + ServiceCom.getNodeStatus() { nodeStatus -> Void in + NSOperationQueue.mainQueue().addOperationWithBlock() { () -> Void in + let nc = NSNotificationCenter.defaultCenter() + + nc.postNotificationName(statusUpdateKey, object: nil, userInfo: ["status": nodeStatus]) + } + } } func deleteSavedNetwork(nwid: String) { diff --git a/ZeroTier One/NodeStatus.swift b/ZeroTier One/NodeStatus.swift new file mode 100644 index 00000000..e2ba0820 --- /dev/null +++ b/ZeroTier One/NodeStatus.swift @@ -0,0 +1,59 @@ +// +// NodeStatus.swift +// ZeroTier One +// +// Created by Grant Limberg on 6/30/16. +// Copyright © 2016 ZeroTier, Inc. All rights reserved. +// + +import Cocoa + +class NodeStatus: NSObject { + var address: String = "" + var publicIdentity: String = "" + var online: Bool = false + var tcpFallbackActive: Bool = false + var versionMajor: Int = 0 + var versionMinor: Int = 0 + var versionRev: Int = 0 + var version: String = "" + var clock: UInt64 = 0 + + init(jsonData: [String: AnyObject]) { + if let a = jsonData["address"] as? String { + self.address = a + } + + if let p = jsonData["publicIdentity"] as? String { + self.publicIdentity = p + } + + if let o = jsonData["online"] as? NSNumber { + self.online = o.boolValue + } + + if let t = jsonData["tcpFallbackActive"] as? NSNumber { + self.tcpFallbackActive = t.boolValue + } + + if let v = jsonData["versionMajor"] as? NSNumber { + self.versionMajor = v.integerValue + } + + if let v = jsonData["versionMinor"] as? NSNumber { + self.versionMinor = v.integerValue + } + + if let v = jsonData["versionRev"] as? NSNumber { + self.versionRev = v.integerValue + } + + if let v = jsonData["version"] as? String { + self.version = v + } + + if let c = jsonData["version"] as? NSNumber { + self.clock = c.unsignedLongLongValue + } + } +} diff --git a/ZeroTier One/ServiceCom.swift b/ZeroTier One/ServiceCom.swift index 2a98ec36..6ebf0986 100644 --- a/ZeroTier One/ServiceCom.swift +++ b/ZeroTier One/ServiceCom.swift @@ -118,6 +118,40 @@ class ServiceCom: NSObject { } } + static func getNodeStatus(completionHandler: (NodeStatus -> Void)) { + let urlString = baseURL + "/status?auth=\(ServiceCom.getKey())" + + if let u = NSURL(string: urlString) { + let request = NSMutableURLRequest(URL: u) + let session = NSURLSession.sharedSession() + let task = session.dataTaskWithRequest(request) { (data, response, error) in + if error != nil{ + NSLog("\(error)") + return + } + + let httpResponse = response as! NSHTTPURLResponse + let status = httpResponse.statusCode + + if status == 200 { + do { + let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as! [String: AnyObject] + + let status = NodeStatus(jsonData: json) + + completionHandler(status) + } + catch { + } + } + } + + task.resume() + } + else { + NSLog("bad URL") + } + } static func joinNetwork(network: String, allowManaged: Bool = true, allowGlobal: Bool = false, allowDefault: Bool = false) { let urlString = baseURL + "/network/\(network)?auth=\(ServiceCom.getKey())" -- cgit v1.2.3