-
Notifications
You must be signed in to change notification settings - Fork 689
Expand file tree
/
Copy pathSidebarTreeControllerDelegate.swift
More file actions
152 lines (122 loc) · 4.16 KB
/
SidebarTreeControllerDelegate.swift
File metadata and controls
152 lines (122 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// SidebarTreeControllerDelegate.swift
// NetNewsWire
//
// Created by Brent Simmons on 7/24/16.
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import RSTree
import Articles
import Account
@MainActor final class SidebarTreeControllerDelegate: TreeControllerDelegate {
private var filterExceptions = Set<SidebarItemIdentifier>()
var isReadFiltered = false
func addFilterException(_ feedID: SidebarItemIdentifier) {
filterExceptions.insert(feedID)
}
func resetFilterExceptions() {
filterExceptions = Set<SidebarItemIdentifier>()
}
func treeController(treeController: TreeController, childNodesFor node: Node) -> [Node]? {
if node.isRoot {
return childNodesForRootNode(node)
}
if node.representedObject is Container {
return childNodesForContainerNode(node)
}
if node.representedObject is SmartFeedsController {
return childNodesForSmartFeeds(node)
}
return nil
}
}
private extension SidebarTreeControllerDelegate {
func childNodesForRootNode(_ rootNode: Node) -> [Node]? {
var topLevelNodes = [Node]()
let smartFeedsNode = rootNode.existingOrNewChildNode(with: SmartFeedsController.shared)
smartFeedsNode.canHaveChildNodes = true
smartFeedsNode.isGroupItem = true
topLevelNodes.append(smartFeedsNode)
topLevelNodes.append(contentsOf: sortedAccountNodes(rootNode))
return topLevelNodes
}
func childNodesForSmartFeeds(_ parentNode: Node) -> [Node] {
return SmartFeedsController.shared.smartFeeds.compactMap { (feed) -> Node? in
// All Smart Feeds should remain visible despite the Hide Read Feeds setting
return parentNode.existingOrNewChildNode(with: feed as AnyObject)
}
}
func childNodesForContainerNode(_ containerNode: Node) -> [Node]? {
let container = containerNode.representedObject as! Container
var children = [AnyObject]()
for feed in container.topLevelFeeds {
if let sidebarItemID = feed.sidebarItemID, !(!filterExceptions.contains(sidebarItemID) && isReadFiltered && feed.unreadCount == 0) {
children.append(feed)
}
}
if let folders = container.folders {
for folder in folders {
if let sidebarItemID = folder.sidebarItemID, !(!filterExceptions.contains(sidebarItemID) && isReadFiltered && folder.unreadCount == 0) {
children.append(folder)
}
}
}
var updatedChildNodes = [Node]()
for representedObject in children {
if let existingNode = containerNode.childNodeRepresentingObject(representedObject) {
if !updatedChildNodes.contains(existingNode) {
updatedChildNodes += [existingNode]
continue
}
}
if let newNode = self.createNode(representedObject: representedObject, parent: containerNode) {
updatedChildNodes += [newNode]
}
}
return updatedChildNodes.sorted(by: AppDefaults.shared.sidebarSortType, ascending: AppDefaults.shared.sidebarSortAscending)
}
func createNode(representedObject: Any, parent: Node) -> Node? {
if let feed = representedObject as? Feed {
return createNode(feed: feed, parent: parent)
}
if let folder = representedObject as? Folder {
return createNode(folder: folder, parent: parent)
}
if let account = representedObject as? Account {
return createNode(account: account, parent: parent)
}
return nil
}
func createNode(feed: Feed, parent: Node) -> Node {
return parent.createChildNode(feed)
}
func createNode(folder: Folder, parent: Node) -> Node {
let node = parent.createChildNode(folder)
node.canHaveChildNodes = true
return node
}
func createNode(account: Account, parent: Node) -> Node {
let node = parent.createChildNode(account)
node.canHaveChildNodes = true
node.isGroupItem = true
return node
}
func sortedAccountNodes(_ parent: Node) -> [Node] {
let nodes = AccountManager.shared.sortedActiveAccounts.compactMap { (account) -> Node? in
let accountNode = parent.existingOrNewChildNode(with: account)
accountNode.canHaveChildNodes = true
accountNode.isGroupItem = true
return accountNode
}
return nodes
}
func nodeInArrayRepresentingObject(_ nodes: [Node], _ representedObject: AnyObject) -> Node? {
for oneNode in nodes {
if oneNode.representedObject === representedObject {
return oneNode
}
}
return nil
}
}