Skip to content

Commit

Permalink
Implement #5 and #6
Browse files Browse the repository at this point in the history
  • Loading branch information
lapcat committed Oct 11, 2017
1 parent b6ab80e commit 0b8aac9
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 9 deletions.
1 change: 1 addition & 0 deletions source/BonjourNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Cocoa
protocol BonjourNode:NSObjectProtocol {
var children:[Any] { get }
var objectValue:String { get }
var persistentName:String { get }
func start()
func stop()
}
Expand Down
1 change: 1 addition & 0 deletions source/BrowserDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class BrowserDelegate:NSObject, NetServiceBrowserDelegate, BonjourNode {
// These need to be overridden
var children:[Any] { fatalError() }
var objectValue:String { fatalError() }
var persistentName:String { fatalError() }

func start() {
browser.includesPeerToPeer = true
Expand Down
73 changes: 72 additions & 1 deletion source/BrowserWindowController.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Cocoa

class BrowserWindowController:NSObject, NSOutlineViewDataSource, NSOutlineViewDelegate, NSWindowDelegate {
static let expandedUserDefaultsKey = "ExpandedItems"
let browserDelegate = RootBrowserDelegate()
let outlineView = CopyOutlineView()
let window:NSWindow = {
Expand Down Expand Up @@ -58,13 +59,29 @@ class BrowserWindowController:NSObject, NSOutlineViewDataSource, NSOutlineViewDe

scrollView.documentView = outlineView

outlineView.delegate = self
outlineView.dataSource = self // Do this last, because it causes data source methods to be called

NotificationCenter.default.addObserver(forName:.nodeDidAdd, object:nil, queue:nil, using:{
let object = $0.object
let parent = self.outlineView.parent(forItem:object)
self.outlineView.reloadItem(parent, reloadChildren:true)
self.outlineView.expandItem(object, expandChildren:true) // Auto-expand new items
if let node = object as? BonjourNode {
if let expandedDefaults = UserDefaults.standard.dictionary(forKey:BrowserWindowController.expandedUserDefaultsKey) {
let persistentName = node.persistentName
if let expandedNumber = expandedDefaults[persistentName] as? NSNumber {
if expandedNumber.boolValue {
self.outlineView.expandItem(node)
}
return
}
}

if node is DomainBrowserDelegate {
// Expand new domains
self.outlineView.expandItem(node)
}
}
})
NotificationCenter.default.addObserver(forName:.nodeDidRemove, object:nil, queue:nil, using:{
let object = $0.object
Expand Down Expand Up @@ -133,4 +150,58 @@ class BrowserWindowController:NSObject, NSOutlineViewDataSource, NSOutlineViewDe
}
return nil
}

func outlineViewItemWillExpand(_ notification:Notification) {
guard let userInfo = notification.userInfo else {
return
}
guard let object = userInfo["NSObject"] else {
return
}
guard let node = object as? BonjourNode else {
return
}

if node is ServiceDelegate {
node.start()
}

saveNode(node, expanded:true)
}

func outlineViewItemWillCollapse(_ notification:Notification) {
guard let userInfo = notification.userInfo else {
return
}
guard let object = userInfo["NSObject"] else {
return
}
guard let node = object as? BonjourNode else {
return
}

if node is ServiceDelegate {
node.stop()
}

saveNode(node, expanded:false)
}

func saveNode(_ node:BonjourNode, expanded:Bool) {
let standardUserDefaults = UserDefaults.standard
let key = BrowserWindowController.expandedUserDefaultsKey
let persistentName = node.persistentName
if var expandedDefaults = standardUserDefaults.dictionary(forKey:key) {
if let expandedNumber = expandedDefaults[persistentName] as? NSNumber {
if expandedNumber.boolValue == expanded {
return // No change in value
}
}
expandedDefaults[persistentName] = expanded
standardUserDefaults.set(expandedDefaults, forKey:key)
}
else {
standardUserDefaults.set([persistentName:expanded], forKey:key)
}
}
}
1 change: 1 addition & 0 deletions source/DomainBrowserDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class DomainBrowserDelegate:BrowserDelegate {
var delegates = [ServiceBrowserDelegate]()
override var children:[Any] { return delegates }
override var objectValue:String { return domain }
override var persistentName:String { return domain }

required init(_ domain:String) {
self.domain = domain
Expand Down
2 changes: 1 addition & 1 deletion source/ServiceBrowserDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ServiceBrowserDelegate:BrowserDelegate {
var delegates = [ServiceDelegate]()
override var children:[Any] { return delegates }
override var objectValue:String { return type }
override var persistentName:String { return type + domain }

required init(type:String, domain:String) {
self.type = type
Expand Down Expand Up @@ -34,7 +35,6 @@ class ServiceBrowserDelegate:BrowserDelegate {
let newDelegate = ServiceDelegate(service)
delegates.append(newDelegate)
delegates.sort { $0.service.name < $1.service.name }
newDelegate.start()
NotificationCenter.default.post(name:.nodeDidAdd, object:newDelegate)
}

Expand Down
23 changes: 16 additions & 7 deletions source/ServiceDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class ServiceDelegate:NSObject, NetServiceDelegate, BonjourNode {
var records = [String]()
var children:[Any] { return resolved + records }
var objectValue:String { return service.name }
var persistentName:String
var started = false

required init(_ service:NetService) {
self.service = service
persistentName = "\(service.name).\(service.type)\(service.domain)"
super.init()
reloadTXTRecord()
}

@available(*, unavailable)
Expand All @@ -19,15 +21,22 @@ class ServiceDelegate:NSObject, NetServiceDelegate, BonjourNode {
}

func start() {
service.delegate = self
service.startMonitoring()
service.resolve(withTimeout:0.0)
if !started {
started = true
reloadTXTRecord()
service.delegate = self
service.startMonitoring()
service.resolve(withTimeout:0.0)
}
}

func stop() {
service.delegate = nil
service.stopMonitoring()
service.stop()
if started {
started = false
service.delegate = nil
service.stopMonitoring()
service.stop()
}
}

func netServiceDidResolveAddress(_ sender:NetService) {
Expand Down

0 comments on commit 0b8aac9

Please sign in to comment.