mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2025-02-09 08:39:00 +01:00
Simplify Container and its function implementations.
This commit is contained in:
parent
dccb215c76
commit
ca611623aa
@ -18,7 +18,7 @@ func markArticles(_ articles: Set<Article>, statusKey: String, flag: Bool) {
|
|||||||
|
|
||||||
d.keys.forEach { (accountID) in
|
d.keys.forEach { (accountID) in
|
||||||
|
|
||||||
guard let accountArticles = d[accountID], let account = accountWithID(accountID) else {
|
guard let accountArticles = d[accountID], let account = AccountManager.shared.existingAccount(with: accountID) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +29,11 @@ private extension FolderTreeControllerDelegate {
|
|||||||
|
|
||||||
var folderNodes = [Node]()
|
var folderNodes = [Node]()
|
||||||
|
|
||||||
let _ = AccountManager.shared.localAccount.visitChildren { (oneRepresentedObject) in
|
for oneRepresentedObject in AccountManager.shared.localAccount.children {
|
||||||
|
|
||||||
if let folder = oneRepresentedObject as? Folder {
|
if let folder = oneRepresentedObject as? Folder {
|
||||||
folderNodes += [createNode(folder, parent: node)]
|
folderNodes += [createNode(folder, parent: node)]
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Node.nodesSortedAlphabetically(folderNodes)
|
return Node.nodesSortedAlphabetically(folderNodes)
|
||||||
|
@ -34,22 +34,19 @@ private extension SidebarTreeControllerDelegate {
|
|||||||
// This will be expanded later to add synthetic feeds (All Unread, for instance).
|
// This will be expanded later to add synthetic feeds (All Unread, for instance).
|
||||||
|
|
||||||
var updatedChildNodes = [Node]()
|
var updatedChildNodes = [Node]()
|
||||||
|
|
||||||
let _ = AccountManager.shared.localAccount.visitChildren { (oneRepresentedObject) in
|
for oneRepresentedObject in AccountManager.shared.localAccount.children {
|
||||||
|
|
||||||
if let existingNode = node.childNodeRepresentingObject(oneRepresentedObject as AnyObject) {
|
if let existingNode = node.childNodeRepresentingObject(oneRepresentedObject) {
|
||||||
// Reuse nodes.
|
// Reuse nodes.
|
||||||
if !updatedChildNodes.contains(existingNode) {
|
if !updatedChildNodes.contains(existingNode) {
|
||||||
updatedChildNodes += [existingNode]
|
updatedChildNodes += [existingNode]
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let newNode = createNode(representedObject: oneRepresentedObject as AnyObject, parent: node) {
|
if let newNode = createNode(representedObject: oneRepresentedObject as AnyObject, parent: node) {
|
||||||
updatedChildNodes += [newNode]
|
updatedChildNodes += [newNode]
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedChildNodes = Node.nodesSortedAlphabeticallyWithFoldersAtEnd(updatedChildNodes)
|
updatedChildNodes = Node.nodesSortedAlphabeticallyWithFoldersAtEnd(updatedChildNodes)
|
||||||
@ -60,28 +57,25 @@ private extension SidebarTreeControllerDelegate {
|
|||||||
|
|
||||||
var updatedChildNodes = [Node]()
|
var updatedChildNodes = [Node]()
|
||||||
let folder = node.representedObject as! Folder
|
let folder = node.representedObject as! Folder
|
||||||
|
|
||||||
let _ = folder.visitChildren { (oneRepresentedObject) -> Bool in
|
for oneRepresentedObject in folder.children {
|
||||||
|
|
||||||
if let existingNode = node.childNodeRepresentingObject(oneRepresentedObject) {
|
if let existingNode = node.childNodeRepresentingObject(oneRepresentedObject) {
|
||||||
if !updatedChildNodes.contains(existingNode) {
|
if !updatedChildNodes.contains(existingNode) {
|
||||||
updatedChildNodes += [existingNode]
|
updatedChildNodes += [existingNode]
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let newNode = self.createNode(representedObject: oneRepresentedObject, parent: node) {
|
if let newNode = self.createNode(representedObject: oneRepresentedObject, parent: node) {
|
||||||
updatedChildNodes += [newNode]
|
updatedChildNodes += [newNode]
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedChildNodes = Node.nodesSortedAlphabeticallyWithFoldersAtEnd(updatedChildNodes)
|
updatedChildNodes = Node.nodesSortedAlphabeticallyWithFoldersAtEnd(updatedChildNodes)
|
||||||
return updatedChildNodes
|
return updatedChildNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNode(representedObject: AnyObject, parent: Node) -> Node? {
|
func createNode(representedObject: Any, parent: Node) -> Node? {
|
||||||
|
|
||||||
if let feed = representedObject as? Feed {
|
if let feed = representedObject as? Feed {
|
||||||
return createNode(feed: feed, parent: parent)
|
return createNode(feed: feed, parent: parent)
|
||||||
|
@ -31,22 +31,22 @@ public enum AccountType: Int {
|
|||||||
// TODO: more
|
// TODO: more
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class Account: DisplayNameProvider, Hashable {
|
public final class Account: DisplayNameProvider, Container, Hashable {
|
||||||
|
|
||||||
public let accountID: String
|
public let accountID: String
|
||||||
public let type: AccountType
|
public let type: AccountType
|
||||||
public var nameForDisplay = ""
|
public var nameForDisplay = ""
|
||||||
public let hashValue: Int
|
public let hashValue: Int
|
||||||
|
public var children = [AnyObject]()
|
||||||
let settingsFile: String
|
let settingsFile: String
|
||||||
let dataFolder: String
|
let dataFolder: String
|
||||||
let database: Database
|
let database: Database
|
||||||
let delegate: AccountDelegate
|
let delegate: AccountDelegate
|
||||||
var topLevelObjects = [AnyObject]()
|
|
||||||
var feedIDDictionary = [String: Feed]()
|
var feedIDDictionary = [String: Feed]()
|
||||||
var username: String?
|
var username: String?
|
||||||
var saveTimer: Timer?
|
var saveTimer: Timer?
|
||||||
|
|
||||||
var dirty = false {
|
public var dirty = false {
|
||||||
didSet {
|
didSet {
|
||||||
|
|
||||||
if refreshInProgress {
|
if refreshInProgress {
|
||||||
@ -164,7 +164,7 @@ public final class Account: DisplayNameProvider, Hashable {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if !topLevelObjectsContainsFeed(uniquedFeed) {
|
if !topLevelObjectsContainsFeed(uniquedFeed) {
|
||||||
topLevelObjects += [uniquedFeed]
|
children += [uniquedFeed]
|
||||||
}
|
}
|
||||||
didAddFeed = true
|
didAddFeed = true
|
||||||
}
|
}
|
||||||
@ -202,8 +202,12 @@ public final class Account: DisplayNameProvider, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func importOPML(_ opmlDocument: RSOPMLDocument) {
|
public func importOPML(_ opmlDocument: RSOPMLDocument) {
|
||||||
|
|
||||||
// TODO
|
guard let children = opmlDocument.children else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
importOPMLItems(children, parentFolder: nil, foldersAllowed: true)
|
||||||
|
dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Notifications
|
// MARK: - Notifications
|
||||||
@ -262,13 +266,13 @@ private extension Account {
|
|||||||
guard let childrenArray = d[Key.children] as? [[String: Any]] else {
|
guard let childrenArray = d[Key.children] as? [[String: Any]] else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
topLevelObjects = objects(with: childrenArray)
|
children = objects(with: childrenArray)
|
||||||
updateFeedIDDictionary()
|
updateFeedIDDictionary()
|
||||||
}
|
}
|
||||||
|
|
||||||
func diskDictionary() -> NSDictionary {
|
func diskDictionary() -> NSDictionary {
|
||||||
|
|
||||||
let diskObjects = topLevelObjects.flatMap { (object) -> [String: Any]? in
|
let diskObjects = children.flatMap { (object) -> [String: Any]? in
|
||||||
|
|
||||||
if let folder = object as? Folder {
|
if let folder = object as? Folder {
|
||||||
return folder.dictionary
|
return folder.dictionary
|
||||||
@ -341,7 +345,7 @@ private extension Account {
|
|||||||
|
|
||||||
func topLevelObjectsContainsFeed(_ feed: Feed) -> Bool {
|
func topLevelObjectsContainsFeed(_ feed: Feed) -> Bool {
|
||||||
|
|
||||||
return topLevelObjects.contains(where: { (object) -> Bool in
|
return children.contains(where: { (object) -> Bool in
|
||||||
if let oneFeed = object as? Feed {
|
if let oneFeed = object as? Feed {
|
||||||
if oneFeed.feedID == feed.feedID {
|
if oneFeed.feedID == feed.feedID {
|
||||||
return true
|
return true
|
||||||
@ -350,6 +354,26 @@ private extension Account {
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func importOPMLItems(_ items: [RSOPMLItem], parentFolder: Folder?, foldersAllowed: Bool) {
|
||||||
|
|
||||||
|
for item in items {
|
||||||
|
|
||||||
|
if let feedSpecifier = item.feedSpecifier {
|
||||||
|
if hasFeed(withURL: feedSpecifier.feedURL) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.isFolder {
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - OPMLRepresentable
|
// MARK: - OPMLRepresentable
|
||||||
@ -359,7 +383,7 @@ extension Account: OPMLRepresentable {
|
|||||||
public func OPMLString(indentLevel: Int) -> String {
|
public func OPMLString(indentLevel: Int) -> String {
|
||||||
|
|
||||||
var s = ""
|
var s = ""
|
||||||
for oneObject in topLevelObjects {
|
for oneObject in children {
|
||||||
if let oneOPMLObject = oneObject as? OPMLRepresentable {
|
if let oneOPMLObject = oneObject as? OPMLRepresentable {
|
||||||
s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1)
|
s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1)
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973EF1F6DD19E006346C4 /* RSCore.framework */; };
|
841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973EF1F6DD19E006346C4 /* RSCore.framework */; };
|
||||||
841973FF1F6DD1C5006346C4 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973FA1F6DD1AC006346C4 /* RSParser.framework */; };
|
841973FF1F6DD1C5006346C4 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973FA1F6DD1AC006346C4 /* RSParser.framework */; };
|
||||||
841974011F6DD1EC006346C4 /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974001F6DD1EC006346C4 /* Folder.swift */; };
|
841974011F6DD1EC006346C4 /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974001F6DD1EC006346C4 /* Folder.swift */; };
|
||||||
841974181F6DD535006346C4 /* Folder+Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974171F6DD535006346C4 /* Folder+Container.swift */; };
|
|
||||||
8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974191F6DD583006346C4 /* Account+Container.swift */; };
|
|
||||||
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974241F6DDCE4006346C4 /* AccountDelegate.swift */; };
|
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974241F6DDCE4006346C4 /* AccountDelegate.swift */; };
|
||||||
8469F8171F6DD0AD0084783E /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8401A17D1F6DC388002B1BE2 /* Database.framework */; };
|
8469F8171F6DD0AD0084783E /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8401A17D1F6DC388002B1BE2 /* Database.framework */; };
|
||||||
8469F81C1F6DD15E0084783E /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935101F62486800CEBD24 /* Account.swift */; };
|
8469F81C1F6DD15E0084783E /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935101F62486800CEBD24 /* Account.swift */; };
|
||||||
@ -20,11 +18,10 @@
|
|||||||
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */; };
|
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */; };
|
||||||
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */; };
|
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */; };
|
||||||
846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77531F6F00E300A165E2 /* AccountManager.swift */; };
|
846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77531F6F00E300A165E2 /* AccountManager.swift */; };
|
||||||
846E77571F6F03D600A165E2 /* Article+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77561F6F03D600A165E2 /* Article+Account.swift */; };
|
|
||||||
846E77591F6F03E300A165E2 /* Feed+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77581F6F03E300A165E2 /* Feed+Account.swift */; };
|
|
||||||
848935001F62484F00CEBD24 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848934F61F62484F00CEBD24 /* Account.framework */; };
|
848935001F62484F00CEBD24 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848934F61F62484F00CEBD24 /* Account.framework */; };
|
||||||
848935051F62485000CEBD24 /* AccountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935041F62485000CEBD24 /* AccountTests.swift */; };
|
848935051F62485000CEBD24 /* AccountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935041F62485000CEBD24 /* AccountTests.swift */; };
|
||||||
84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */; };
|
84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */; };
|
||||||
|
84C8B3F41F89DE430053CCA6 /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C8B3F31F89DE430053CCA6 /* DataExtensions.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -107,14 +104,10 @@
|
|||||||
841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = "<group>"; };
|
841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = "<group>"; };
|
||||||
841974001F6DD1EC006346C4 /* Folder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = "<group>"; };
|
841974001F6DD1EC006346C4 /* Folder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = "<group>"; };
|
||||||
8419740D1F6DD25F006346C4 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
|
8419740D1F6DD25F006346C4 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
|
||||||
841974171F6DD535006346C4 /* Folder+Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Container.swift"; sourceTree = "<group>"; };
|
|
||||||
841974191F6DD583006346C4 /* Account+Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Container.swift"; sourceTree = "<group>"; };
|
|
||||||
841974241F6DDCE4006346C4 /* AccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDelegate.swift; sourceTree = "<group>"; };
|
841974241F6DDCE4006346C4 /* AccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDelegate.swift; sourceTree = "<group>"; };
|
||||||
8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountDelegate.swift; sourceTree = "<group>"; };
|
8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountDelegate.swift; sourceTree = "<group>"; };
|
||||||
8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountRefresher.swift; sourceTree = "<group>"; };
|
8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountRefresher.swift; sourceTree = "<group>"; };
|
||||||
846E77531F6F00E300A165E2 /* AccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = "<group>"; };
|
846E77531F6F00E300A165E2 /* AccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = "<group>"; };
|
||||||
846E77561F6F03D600A165E2 /* Article+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Article+Account.swift"; path = "Extensions/Article+Account.swift"; sourceTree = "<group>"; };
|
|
||||||
846E77581F6F03E300A165E2 /* Feed+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Feed+Account.swift"; path = "Extensions/Feed+Account.swift"; sourceTree = "<group>"; };
|
|
||||||
848934F61F62484F00CEBD24 /* Account.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Account.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
848934F61F62484F00CEBD24 /* Account.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Account.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
848934FA1F62484F00CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
848934FA1F62484F00CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
848934FF1F62484F00CEBD24 /* AccountTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccountTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
848934FF1F62484F00CEBD24 /* AccountTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccountTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@ -122,6 +115,7 @@
|
|||||||
848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
|
848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
|
||||||
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombinedRefreshProgress.swift; sourceTree = "<group>"; };
|
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombinedRefreshProgress.swift; sourceTree = "<group>"; };
|
||||||
|
84C8B3F31F89DE430053CCA6 /* DataExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtensions.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -184,16 +178,6 @@
|
|||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
841974141F6DD4FF006346C4 /* Container */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
8419740D1F6DD25F006346C4 /* Container.swift */,
|
|
||||||
841974191F6DD583006346C4 /* Account+Container.swift */,
|
|
||||||
841974171F6DD535006346C4 /* Folder+Container.swift */,
|
|
||||||
);
|
|
||||||
path = Container;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
8419742B1F6DDE84006346C4 /* LocalAccount */ = {
|
8419742B1F6DDE84006346C4 /* LocalAccount */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -214,15 +198,6 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
846E77551F6F03B200A165E2 /* Extensions */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
846E77581F6F03E300A165E2 /* Feed+Account.swift */,
|
|
||||||
846E77561F6F03D600A165E2 /* Article+Account.swift */,
|
|
||||||
);
|
|
||||||
name = Extensions;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
848934EC1F62484F00CEBD24 = {
|
848934EC1F62484F00CEBD24 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -231,8 +206,8 @@
|
|||||||
841974241F6DDCE4006346C4 /* AccountDelegate.swift */,
|
841974241F6DDCE4006346C4 /* AccountDelegate.swift */,
|
||||||
841974001F6DD1EC006346C4 /* Folder.swift */,
|
841974001F6DD1EC006346C4 /* Folder.swift */,
|
||||||
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */,
|
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */,
|
||||||
846E77551F6F03B200A165E2 /* Extensions */,
|
84C8B3F31F89DE430053CCA6 /* DataExtensions.swift */,
|
||||||
841974141F6DD4FF006346C4 /* Container */,
|
8419740D1F6DD25F006346C4 /* Container.swift */,
|
||||||
8419742B1F6DDE84006346C4 /* LocalAccount */,
|
8419742B1F6DDE84006346C4 /* LocalAccount */,
|
||||||
8469F80F1F6DC3C10084783E /* Frameworks */,
|
8469F80F1F6DC3C10084783E /* Frameworks */,
|
||||||
848934FA1F62484F00CEBD24 /* Info.plist */,
|
848934FA1F62484F00CEBD24 /* Info.plist */,
|
||||||
@ -453,18 +428,15 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
846E77571F6F03D600A165E2 /* Article+Account.swift in Sources */,
|
84C8B3F41F89DE430053CCA6 /* DataExtensions.swift in Sources */,
|
||||||
84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */,
|
84C3654A1F899F3B001EC85C /* CombinedRefreshProgress.swift in Sources */,
|
||||||
8469F81C1F6DD15E0084783E /* Account.swift in Sources */,
|
8469F81C1F6DD15E0084783E /* Account.swift in Sources */,
|
||||||
846E77451F6EF9B900A165E2 /* Container.swift in Sources */,
|
846E77451F6EF9B900A165E2 /* Container.swift in Sources */,
|
||||||
8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */,
|
|
||||||
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */,
|
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */,
|
||||||
846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */,
|
846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */,
|
||||||
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */,
|
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */,
|
||||||
841974011F6DD1EC006346C4 /* Folder.swift in Sources */,
|
841974011F6DD1EC006346C4 /* Folder.swift in Sources */,
|
||||||
846E77591F6F03E300A165E2 /* Feed+Account.swift in Sources */,
|
|
||||||
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */,
|
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */,
|
||||||
841974181F6DD535006346C4 /* Folder+Container.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -198,12 +198,6 @@ private func accountFilePathWithFolder(_ folderPath: String) -> String {
|
|||||||
return NSString(string: folderPath).appendingPathComponent(accountDataFileName)
|
return NSString(string: folderPath).appendingPathComponent(accountDataFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func accountWithID(_ accountID: String) -> Account? {
|
|
||||||
|
|
||||||
// Shortcut.
|
|
||||||
return AccountManager.shared.existingAccount(with: accountID)
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct AccountSpecifier {
|
private struct AccountSpecifier {
|
||||||
|
|
||||||
let type: String
|
let type: String
|
||||||
|
113
Frameworks/Account/Container.swift
Normal file
113
Frameworks/Account/Container.swift
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//
|
||||||
|
// Container.swift
|
||||||
|
// Evergreen
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 4/17/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import RSCore
|
||||||
|
import Data
|
||||||
|
|
||||||
|
extension NSNotification.Name {
|
||||||
|
|
||||||
|
public static let ChildrenDidChange = Notification.Name("ChildrenDidChange")
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol Container {
|
||||||
|
|
||||||
|
var children: [AnyObject] { get }
|
||||||
|
|
||||||
|
//Recursive
|
||||||
|
func flattenedFeeds() -> Set<Feed>
|
||||||
|
func hasFeed(with feedID: String) -> Bool
|
||||||
|
func hasFeed(withURL url: String) -> Bool
|
||||||
|
func existingFeed(with feedID: String) -> Feed?
|
||||||
|
func existingFeed(withURL url: String) -> Feed?
|
||||||
|
func existingFolder(with name: String) -> Folder?
|
||||||
|
|
||||||
|
func postChildrenDidChangeNotification()
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Container {
|
||||||
|
|
||||||
|
func flattenedFeeds() -> Set<Feed> {
|
||||||
|
|
||||||
|
var feeds = Set<Feed>()
|
||||||
|
|
||||||
|
for object in children {
|
||||||
|
if let feed = object as? Feed {
|
||||||
|
feeds.insert(feed)
|
||||||
|
}
|
||||||
|
else if let container = object as? Container {
|
||||||
|
feeds.formUnion(container.flattenedFeeds())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return feeds
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasFeed(with feedID: String) -> Bool {
|
||||||
|
|
||||||
|
return existingFeed(with: feedID) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasFeed(withURL url: String) -> Bool {
|
||||||
|
|
||||||
|
return existingFeed(withURL: url) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func existingFeed(with feedID: String) -> Feed? {
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
|
||||||
|
if let feed = child as? Feed, feed.feedID == feedID {
|
||||||
|
return feed
|
||||||
|
}
|
||||||
|
if let container = child as? Container, let feed = container.existingFeed(with: feedID) {
|
||||||
|
return feed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func existingFeed(withURL url: String) -> Feed? {
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
|
||||||
|
if let feed = child as? Feed, feed.url == url {
|
||||||
|
return feed
|
||||||
|
}
|
||||||
|
if let container = child as? Container, let feed = container.existingFeed(withURL: url) {
|
||||||
|
return feed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func existingFolder(with name: String) -> Folder? {
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
|
||||||
|
if let folder = child as? Folder {
|
||||||
|
if folder.name == name {
|
||||||
|
return folder
|
||||||
|
}
|
||||||
|
if let subFolder = folder.existingFolder(with: name) {
|
||||||
|
return subFolder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChildrenDidChangeNotification() {
|
||||||
|
|
||||||
|
NotificationCenter.default.post(name: .ChildrenDidChange, object: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,68 +0,0 @@
|
|||||||
//
|
|
||||||
// Account+Container.swift
|
|
||||||
// Account
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 9/16/17.
|
|
||||||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Data
|
|
||||||
|
|
||||||
extension Account: Container {
|
|
||||||
|
|
||||||
public func flattenedFeeds() -> Set<Feed> {
|
|
||||||
|
|
||||||
var feeds = Set<Feed>()
|
|
||||||
|
|
||||||
for object in topLevelObjects {
|
|
||||||
if let feed = object as? Feed {
|
|
||||||
feeds.insert(feed)
|
|
||||||
}
|
|
||||||
else if let folder = object as? Folder {
|
|
||||||
feeds.formUnion(folder.flattenedFeeds())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return feeds
|
|
||||||
}
|
|
||||||
|
|
||||||
public func existingFeed(with feedID: String) -> Feed? {
|
|
||||||
|
|
||||||
return feedIDDictionary[feedID]
|
|
||||||
}
|
|
||||||
|
|
||||||
public func canAddItem(_ item: AnyObject) -> Bool {
|
|
||||||
|
|
||||||
return false // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
public func isChild(_ obj: AnyObject) -> Bool {
|
|
||||||
|
|
||||||
return topLevelObjects.contains(where: { (oneObject) -> Bool in
|
|
||||||
return oneObject === obj
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool {
|
|
||||||
|
|
||||||
for oneObject in topLevelObjects {
|
|
||||||
|
|
||||||
if let oneContainer = oneObject as? Container {
|
|
||||||
if visitBlock(oneObject) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if recurse && oneContainer.visitObjects(recurse, visitBlock) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if visitBlock(oneObject) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
//
|
|
||||||
// Container.swift
|
|
||||||
// Evergreen
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 4/17/16.
|
|
||||||
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import RSCore
|
|
||||||
import Data
|
|
||||||
|
|
||||||
public typealias VisitBlock = (_ obj: AnyObject) -> Bool // Return true to stop
|
|
||||||
|
|
||||||
extension NSNotification.Name {
|
|
||||||
|
|
||||||
public static let ChildrenDidChange = Notification.Name("ChildrenDidChangeNotification")
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol Container {
|
|
||||||
|
|
||||||
//Recursive
|
|
||||||
func flattenedFeeds() -> Set<Feed>
|
|
||||||
func existingFeed(with feedID: String) -> Feed?
|
|
||||||
func existingFeed(withURL url: String) -> Feed?
|
|
||||||
func hasFeed(with feedID: String) -> Bool
|
|
||||||
func hasFeed(withURL url: String) -> Bool
|
|
||||||
|
|
||||||
func isChild(_ obj: AnyObject) -> Bool
|
|
||||||
|
|
||||||
// visitBlock should return true to stop visiting.
|
|
||||||
// visitObjects returns true if a visitBlock returned true.
|
|
||||||
func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension Container {
|
|
||||||
|
|
||||||
func existingFeed(with feedID: String) -> Feed? {
|
|
||||||
|
|
||||||
let foundObject = findObject(true) { (oneDescendant) -> Bool in
|
|
||||||
if let oneFeed = oneDescendant as? Feed, oneFeed.feedID == feedID {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return foundObject as! Feed?
|
|
||||||
}
|
|
||||||
|
|
||||||
func existingFeed(withURL url: String) -> Feed? {
|
|
||||||
|
|
||||||
let foundObject = findObject(true) { (oneDescendant) -> Bool in
|
|
||||||
if let oneFeed = oneDescendant as? Feed, oneFeed.url == url {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return foundObject as! Feed?
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasFeed(with feedID: String) -> Bool {
|
|
||||||
|
|
||||||
if let _ = existingFeed(with: feedID) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasFeed(withURL url: String) -> Bool {
|
|
||||||
|
|
||||||
if let _ = existingFeed(withURL: url) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func visitChildren(visitBlock: VisitBlock) -> Bool {
|
|
||||||
|
|
||||||
return visitObjects(false, visitBlock)
|
|
||||||
}
|
|
||||||
|
|
||||||
func findObject(_ recurse: Bool, visitBlock: @escaping VisitBlock) -> AnyObject? {
|
|
||||||
|
|
||||||
var foundObject: AnyObject?
|
|
||||||
|
|
||||||
let _ = visitObjects(recurse) { (oneObject) in
|
|
||||||
|
|
||||||
if let _ = foundObject {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if visitBlock(oneObject) {
|
|
||||||
foundObject = oneObject
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return foundObject
|
|
||||||
}
|
|
||||||
|
|
||||||
func objectIsChild(_ obj: AnyObject) -> Bool {
|
|
||||||
|
|
||||||
return visitObjects(false) { (oneObject) in
|
|
||||||
return obj === oneObject
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func objectIsDescendant(_ obj: AnyObject) -> Bool {
|
|
||||||
|
|
||||||
return visitObjects(true) { (oneObject) in
|
|
||||||
return obj === oneObject
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func existingFolderWithName(_ name: String) -> Folder? {
|
|
||||||
|
|
||||||
let foundObject = findObject(false) { (oneObject) in
|
|
||||||
if let oneFolder = oneObject as? Folder, oneFolder.nameForDisplay == name {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return foundObject as! Folder?
|
|
||||||
}
|
|
||||||
|
|
||||||
public func postChildrenDidChangeNotification() {
|
|
||||||
|
|
||||||
NotificationCenter.default.post(name: .ChildrenDidChange, object: self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
//
|
|
||||||
// Folder+Container.swift
|
|
||||||
// Account
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 9/16/17.
|
|
||||||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Data
|
|
||||||
|
|
||||||
extension Folder: Container {
|
|
||||||
|
|
||||||
public func flattenedFeeds() -> Set<Feed> {
|
|
||||||
|
|
||||||
var feeds = Set<Feed>()
|
|
||||||
for oneChild in children {
|
|
||||||
if let oneFeed = oneChild as? Feed {
|
|
||||||
feeds.insert(oneFeed)
|
|
||||||
}
|
|
||||||
else if let oneContainer = oneChild as? Container {
|
|
||||||
feeds.formUnion(oneContainer.flattenedFeeds())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return feeds
|
|
||||||
}
|
|
||||||
|
|
||||||
public func isChild(_ obj: AnyObject) -> Bool {
|
|
||||||
|
|
||||||
return children.contains { $0 === obj }
|
|
||||||
}
|
|
||||||
|
|
||||||
public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool {
|
|
||||||
|
|
||||||
for oneObject in children {
|
|
||||||
|
|
||||||
if let oneContainer = oneObject as? Container {
|
|
||||||
if visitBlock(oneObject) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if recurse && oneContainer.visitObjects(recurse, visitBlock) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if visitBlock(oneObject) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
28
Frameworks/Account/DataExtensions.swift
Normal file
28
Frameworks/Account/DataExtensions.swift
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// DataExtensions.swift
|
||||||
|
// Account
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 10/7/17.
|
||||||
|
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Data
|
||||||
|
|
||||||
|
public extension Feed {
|
||||||
|
|
||||||
|
var account: Account? {
|
||||||
|
get {
|
||||||
|
return AccountManager.shared.existingAccount(with: accountID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Article {
|
||||||
|
|
||||||
|
var account: Account? {
|
||||||
|
get {
|
||||||
|
return AccountManager.shared.existingAccount(with: accountID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +0,0 @@
|
|||||||
//
|
|
||||||
// Article+Account.swift
|
|
||||||
// Account
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 9/17/17.
|
|
||||||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Data
|
|
||||||
|
|
||||||
public extension Article {
|
|
||||||
|
|
||||||
var account: Account? {
|
|
||||||
get {
|
|
||||||
return accountWithID(accountID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
//
|
|
||||||
// Feed+Account.swift
|
|
||||||
// Account
|
|
||||||
//
|
|
||||||
// Created by Brent Simmons on 9/17/17.
|
|
||||||
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Data
|
|
||||||
|
|
||||||
struct FeedDictionaryKey {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension Feed {
|
|
||||||
|
|
||||||
var account: Account? {
|
|
||||||
get {
|
|
||||||
return accountWithID(accountID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,10 +9,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Data
|
import Data
|
||||||
|
|
||||||
public final class Folder: DisplayNameProvider, UnreadCountProvider {
|
public final class Folder: DisplayNameProvider, Container, UnreadCountProvider {
|
||||||
|
|
||||||
public let account: Account
|
public let account: Account
|
||||||
var children = [AnyObject]()
|
public var children = [AnyObject]()
|
||||||
var name: String?
|
var name: String?
|
||||||
static let untitledName = NSLocalizedString("Untitled ƒ", comment: "Folder name")
|
static let untitledName = NSLocalizedString("Untitled ƒ", comment: "Folder name")
|
||||||
|
|
||||||
@ -180,13 +180,11 @@ extension Folder: OPMLRepresentable {
|
|||||||
|
|
||||||
var hasAtLeastOneChild = false
|
var hasAtLeastOneChild = false
|
||||||
|
|
||||||
let _ = visitChildren { (oneChild) -> Bool in
|
for child in children {
|
||||||
|
if let opmlObject = child as? OPMLRepresentable {
|
||||||
if let oneOPMLObject = oneChild as? OPMLRepresentable {
|
s += opmlObject.OPMLString(indentLevel: indentLevel + 1)
|
||||||
s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1)
|
|
||||||
hasAtLeastOneChild = true
|
hasAtLeastOneChild = true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasAtLeastOneChild {
|
if !hasAtLeastOneChild {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
- (void)addChild:(RSOPMLItem *)child;
|
- (void)addChild:(RSOPMLItem *)child;
|
||||||
|
|
||||||
@property (nonatomic, readonly) RSOPMLFeedSpecifier *OPMLFeedSpecifier; //May be nil.
|
@property (nonatomic, readonly) RSOPMLFeedSpecifier *feedSpecifier; //May be nil.
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSString *titleFromAttributes; //May be nil.
|
@property (nonatomic, readonly) NSString *titleFromAttributes; //May be nil.
|
||||||
@property (nonatomic, readonly) BOOL isFolder;
|
@property (nonatomic, readonly) BOOL isFolder;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
@implementation RSOPMLItem
|
@implementation RSOPMLItem
|
||||||
|
|
||||||
@synthesize children = _children;
|
@synthesize children = _children;
|
||||||
@synthesize OPMLFeedSpecifier = _OPMLFeedSpecifier;
|
@synthesize feedSpecifier = _feedSpecifier;
|
||||||
|
|
||||||
|
|
||||||
- (NSArray *)children {
|
- (NSArray *)children {
|
||||||
@ -48,10 +48,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (RSOPMLFeedSpecifier *)OPMLFeedSpecifier {
|
- (RSOPMLFeedSpecifier *)feedSpecifier {
|
||||||
|
|
||||||
if (_OPMLFeedSpecifier) {
|
if (_feedSpecifier) {
|
||||||
return _OPMLFeedSpecifier;
|
return _feedSpecifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *feedURL = self.attributes.opml_xmlUrl;
|
NSString *feedURL = self.attributes.opml_xmlUrl;
|
||||||
@ -59,9 +59,9 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
_OPMLFeedSpecifier = [[RSOPMLFeedSpecifier alloc] initWithTitle:self.attributes.opml_title feedDescription:self.attributes.opml_description homePageURL:self.attributes.opml_htmlUrl feedURL:feedURL];
|
_feedSpecifier = [[RSOPMLFeedSpecifier alloc] initWithTitle:self.attributes.opml_title feedDescription:self.attributes.opml_description homePageURL:self.attributes.opml_htmlUrl feedURL:feedURL];
|
||||||
|
|
||||||
return _OPMLFeedSpecifier;
|
return _feedSpecifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)titleFromAttributes {
|
- (NSString *)titleFromAttributes {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user