diff --git a/Account/Sources/Account/Account.swift b/Account/Sources/Account/Account.swift index 4bc3d0c58..830c4bcb1 100644 --- a/Account/Sources/Account/Account.swift +++ b/Account/Sources/Account/Account.swift @@ -56,7 +56,7 @@ public enum FetchType { case unread(_: Int? = nil) case today(_: Int? = nil) case folder(Folder, Bool) - case webFeed(Feed) + case feed(Feed) case articleIDs(Set) case search(String) case searchWithArticleIDs(String, Set) @@ -73,7 +73,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public static let articleIDs = "articleIDs" // StatusesDidChange public static let statusKey = "statusKey" // StatusesDidChange public static let statusFlag = "statusFlag" // StatusesDidChange - public static let webFeeds = "webFeeds" // AccountDidDownloadArticles, StatusesDidChange + public static let feeds = "feeds" // AccountDidDownloadArticles, StatusesDidChange public static let syncErrors = "syncErrors" // AccountsDidFailToSyncWithErrors } @@ -142,7 +142,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } } - public var topLevelWebFeeds = Set() + public var topLevelFeeds = Set() public var folders: Set? = Set() public var externalID: String? { @@ -161,24 +161,24 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, return nil } - private var webFeedDictionariesNeedUpdate = true - private var _idToWebFeedDictionary = [String: Feed]() - var idToWebFeedDictionary: [String: Feed] { - if webFeedDictionariesNeedUpdate { - rebuildWebFeedDictionaries() + private var feedDictionariesNeedUpdate = true + private var _idToFeedDictionary = [String: Feed]() + var idToFeedDictionary: [String: Feed] { + if feedDictionariesNeedUpdate { + rebuildFeedDictionaries() } - return _idToWebFeedDictionary + return _idToFeedDictionary } - private var _externalIDToWebFeedDictionary = [String: Feed]() - var externalIDToWebFeedDictionary: [String: Feed] { - if webFeedDictionariesNeedUpdate { - rebuildWebFeedDictionaries() + private var _externalIDToFeedDictionary = [String: Feed]() + var externalIDToFeedDictionary: [String: Feed] { + if feedDictionariesNeedUpdate { + rebuildFeedDictionaries() } - return _externalIDToWebFeedDictionary + return _externalIDToFeedDictionary } - var flattenedWebFeedURLs: Set { - return Set(flattenedWebFeeds().map({ $0.url })) + var flattenedFeedURLs: Set { + return Set(flattenedFeeds().map({ $0.url })) } var username: String? { @@ -213,8 +213,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, private var unreadCounts = [String: Int]() // [feedID: Int] - private var _flattenedWebFeeds = Set() - private var flattenedWebFeedsNeedUpdate = true + private var _flattenedFeeds = Set() + private var flattenedFeedsNeedUpdate = true private lazy var opmlFile = OPMLFile(filename: (dataFolder as NSString).appendingPathComponent("Subscriptions.opml"), account: self) private lazy var metadataFile = AccountMetadataFile(filename: (dataFolder as NSString).appendingPathComponent("Settings.plist"), account: self) @@ -224,9 +224,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } } - private lazy var webFeedMetadataFile = WebFeedMetadataFile(filename: (dataFolder as NSString).appendingPathComponent("FeedMetadata.plist"), account: self) - typealias WebFeedMetadataDictionary = [String: WebFeedMetadata] - var webFeedMetadata = WebFeedMetadataDictionary() + private lazy var feedMetadataFile = FeedMetadataFile(filename: (dataFolder as NSString).appendingPathComponent("FeedMetadata.plist"), account: self) + typealias FeedMetadataDictionary = [String: FeedMetadata] + var feedMetadata = FeedMetadataDictionary() public var unreadCount = 0 { didSet { @@ -318,7 +318,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, NotificationCenter.default.addObserver(self, selector: #selector(childrenDidChange(_:)), name: .ChildrenDidChange, object: nil) metadataFile.load() - webFeedMetadataFile.load() + feedMetadataFile.load() opmlFile.load() var shouldHandleRetentionPolicyChange = false @@ -334,7 +334,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, self.metadata.performedApril2020RetentionPolicyChange = true } - self.database.cleanupDatabaseAtStartup(subscribedToWebFeedIDs: self.flattenedWebFeeds().webFeedIDs()) + self.database.cleanupDatabaseAtStartup(subscribedToFeedIDs: self.flattenedFeeds().feedIDs()) self.fetchAllUnreadCounts() } @@ -488,7 +488,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func save() { metadataFile.save() - webFeedMetadataFile.save() + feedMetadataFile.save() opmlFile.save() } @@ -499,13 +499,13 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, func addOPMLItems(_ items: [RSOPMLItem]) { for item in items { if let feedSpecifier = item.feedSpecifier { - addWebFeed(newWebFeed(with: feedSpecifier)) + addFeed(newFeed(with: feedSpecifier)) } else { if let title = item.titleFromAttributes, let folder = ensureFolder(with: title) { folder.externalID = item.attributes?["nnw_externalID"] as? String item.children?.forEach { itemChild in if let feedSpecifier = itemChild.feedSpecifier { - folder.addWebFeed(newWebFeed(with: feedSpecifier)) + folder.addFeed(newFeed(with: feedSpecifier)) } } } @@ -528,13 +528,13 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, return existingFolder(withExternalID: externalID) } - func existingContainers(withWebFeed webFeed: Feed) -> [Container] { + func existingContainers(withFeed feed: Feed) -> [Container] { var containers = [Container]() - if topLevelWebFeeds.contains(webFeed) { + if topLevelFeeds.contains(feed) { containers.append(self) } folders?.forEach { folder in - if folder.topLevelWebFeeds.contains(webFeed) { + if folder.topLevelFeeds.contains(feed) { containers.append(folder) } } @@ -579,9 +579,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, return folders?.first(where: { $0.externalID == externalID }) } - func newWebFeed(with opmlFeedSpecifier: RSOPMLFeedSpecifier) -> Feed { + func newFeed(with opmlFeedSpecifier: RSOPMLFeedSpecifier) -> Feed { let feedURL = opmlFeedSpecifier.feedURL - let metadata = webFeedMetadata(feedURL: feedURL, webFeedID: feedURL) + let metadata = feedMetadata(feedURL: feedURL, feedID: feedURL) let feed = Feed(account: self, url: opmlFeedSpecifier.feedURL, metadata: metadata) if let feedTitle = opmlFeedSpecifier.title { if feed.name == nil { @@ -591,36 +591,36 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, return feed } - public func addWebFeed(_ feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { - delegate.addWebFeed(for: self, with: feed, to: container, completion: completion) + public func addFeed(_ feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { + delegate.addFeed(for: self, with: feed, to: container, completion: completion) } - public func createWebFeed(url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { - delegate.createWebFeed(for: self, url: url, name: name, container: container, validateFeed: validateFeed, completion: completion) + public func createFeed(url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + delegate.createFeed(for: self, url: url, name: name, container: container, validateFeed: validateFeed, completion: completion) } - func createWebFeed(with name: String?, url: String, webFeedID: String, homePageURL: String?) -> Feed { - let metadata = webFeedMetadata(feedURL: url, webFeedID: webFeedID) + func createFeed(with name: String?, url: String, feedID: String, homePageURL: String?) -> Feed { + let metadata = feedMetadata(feedURL: url, feedID: feedID) let feed = Feed(account: self, url: url, metadata: metadata) feed.name = name feed.homePageURL = homePageURL return feed } - public func removeWebFeed(_ feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { - delegate.removeWebFeed(for: self, with: feed, from: container, completion: completion) + public func removeFeed(_ feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + delegate.removeFeed(for: self, with: feed, from: container, completion: completion) } - public func moveWebFeed(_ feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { - delegate.moveWebFeed(for: self, with: feed, from: from, to: to, completion: completion) + public func moveFeed(_ feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { + delegate.moveFeed(for: self, with: feed, from: from, to: to, completion: completion) } - public func renameWebFeed(_ feed: Feed, to name: String, completion: @escaping (Result) -> Void) { - delegate.renameWebFeed(for: self, with: feed, to: name, completion: completion) + public func renameFeed(_ feed: Feed, to name: String, completion: @escaping (Result) -> Void) { + delegate.renameFeed(for: self, with: feed, to: name, completion: completion) } - public func restoreWebFeed(_ feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - delegate.restoreWebFeed(for: self, feed: feed, container: container, completion: completion) + public func restoreFeed(_ feed: Feed, container: Container, completion: @escaping (Result) -> Void) { + delegate.restoreFeed(for: self, feed: feed, container: container, completion: completion) } public func addFolder(_ name: String, completion: @escaping (Result) -> Void) { @@ -639,8 +639,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, delegate.restoreFolder(for: self, folder: folder, completion: completion) } - func clearWebFeedMetadata(_ feed: Feed) { - webFeedMetadata[feed.url] = nil + func clearFeedMetadata(_ feed: Feed) { + feedMetadata[feed.url] = nil } func addFolder(_ folder: Folder) { @@ -649,8 +649,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, structureDidChange() } - public func updateUnreadCounts(for webFeeds: Set, completion: VoidCompletionBlock? = nil) { - fetchUnreadCounts(for: webFeeds, completion: completion) + public func updateUnreadCounts(for feeds: Set, completion: VoidCompletionBlock? = nil) { + fetchUnreadCounts(for: feeds, completion: completion) } public func fetchArticles(_ fetchType: FetchType) throws -> Set
{ @@ -667,8 +667,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } else { return try fetchArticles(folder: folder) } - case .webFeed(let webFeed): - return try fetchArticles(webFeed: webFeed) + case .feed(let feed): + return try fetchArticles(feed: feed) case .articleIDs(let articleIDs): return try fetchArticles(articleIDs: articleIDs) case .search(let searchString): @@ -692,8 +692,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } else { return fetchArticlesAsync(folder: folder, completion) } - case .webFeed(let webFeed): - fetchArticlesAsync(webFeed: webFeed, completion) + case .feed(let feed): + fetchArticlesAsync(feed: feed, completion) case .articleIDs(let articleIDs): fetchArticlesAsync(articleIDs: articleIDs, completion) case .search(let searchString): @@ -704,11 +704,11 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } public func fetchUnreadCountForToday(_ completion: @escaping SingleUnreadCountCompletionBlock) { - database.fetchUnreadCountForToday(for: flattenedWebFeeds().webFeedIDs(), completion: completion) + database.fetchUnreadCountForToday(for: flattenedFeeds().feedIDs(), completion: completion) } public func fetchUnreadCountForStarredArticles(_ completion: @escaping SingleUnreadCountCompletionBlock) { - database.fetchStarredAndUnreadCount(for: flattenedWebFeeds().webFeedIDs(), completion: completion) + database.fetchStarredAndUnreadCount(for: flattenedFeeds().feedIDs(), completion: completion) } public func fetchUnreadArticleIDs(_ completion: @escaping ArticleIDsCompletionBlock) { @@ -724,43 +724,43 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, database.fetchArticleIDsForStatusesWithoutArticlesNewerThanCutoffDate(completion) } - public func unreadCount(for webFeed: Feed) -> Int { - return unreadCounts[webFeed.webFeedID] ?? 0 + public func unreadCount(for feed: Feed) -> Int { + return unreadCounts[feed.feedID] ?? 0 } - public func setUnreadCount(_ unreadCount: Int, for webFeed: Feed) { - unreadCounts[webFeed.webFeedID] = unreadCount + public func setUnreadCount(_ unreadCount: Int, for feed: Feed) { + unreadCounts[feed.feedID] = unreadCount } public func structureDidChange() { // Feeds were added or deleted. Or folders added or deleted. // Or feeds inside folders were added or deleted. opmlFile.markAsDirty() - flattenedWebFeedsNeedUpdate = true - webFeedDictionariesNeedUpdate = true + flattenedFeedsNeedUpdate = true + feedDictionariesNeedUpdate = true } - func update(_ webFeed: Feed, with parsedFeed: ParsedFeed, _ completion: @escaping UpdateArticlesCompletionBlock) { + func update(_ feed: Feed, with parsedFeed: ParsedFeed, _ completion: @escaping UpdateArticlesCompletionBlock) { // Used only by an On My Mac or iCloud account. precondition(Thread.isMainThread) precondition(type == .onMyMac || type == .cloudKit) - webFeed.takeSettings(from: parsedFeed) + feed.takeSettings(from: parsedFeed) let parsedItems = parsedFeed.items guard !parsedItems.isEmpty else { completion(.success(ArticleChanges())) return } - update(webFeed.webFeedID, with: parsedItems, completion: completion) + update(feed.feedID, with: parsedItems, completion: completion) } - func update(_ webFeedID: String, with parsedItems: Set, deleteOlder: Bool = true, completion: @escaping UpdateArticlesCompletionBlock) { + func update(_ feedID: String, with parsedItems: Set, deleteOlder: Bool = true, completion: @escaping UpdateArticlesCompletionBlock) { // Used only by an On My Mac or iCloud account. precondition(Thread.isMainThread) precondition(type == .onMyMac || type == .cloudKit) - database.update(with: parsedItems, webFeedID: webFeedID, deleteOlder: deleteOlder) { updateArticlesResult in + database.update(with: parsedItems, feedID: feedID, deleteOlder: deleteOlder) { updateArticlesResult in switch updateArticlesResult { case .success(let articleChanges): self.sendNotificationAbout(articleChanges) @@ -771,16 +771,16 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } } - func update(webFeedIDsAndItems: [String: Set], defaultRead: Bool, completion: @escaping DatabaseCompletionBlock) { + func update(feedIDsAndItems: [String: Set], defaultRead: Bool, completion: @escaping DatabaseCompletionBlock) { // Used only by syncing systems. precondition(Thread.isMainThread) precondition(type != .onMyMac && type != .cloudKit) - guard !webFeedIDsAndItems.isEmpty else { + guard !feedIDsAndItems.isEmpty else { completion(nil) return } - database.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: defaultRead) { updateArticlesResult in + database.update(feedIDsAndItems: feedIDsAndItems, defaultRead: defaultRead) { updateArticlesResult in switch updateArticlesResult { case .success(let newAndUpdatedArticles): self.sendNotificationAbout(newAndUpdatedArticles) @@ -888,38 +888,38 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, // MARK: - Container - public func flattenedWebFeeds() -> Set { + public func flattenedFeeds() -> Set { assert(Thread.isMainThread) - if flattenedWebFeedsNeedUpdate { - updateFlattenedWebFeeds() + if flattenedFeedsNeedUpdate { + updateFlattenedFeeds() } - return _flattenedWebFeeds + return _flattenedFeeds } - public func removeWebFeed(_ webFeed: Feed) { - topLevelWebFeeds.remove(webFeed) + public func removeFeed(_ feed: Feed) { + topLevelFeeds.remove(feed) structureDidChange() postChildrenDidChangeNotification() } - public func removeFeeds(_ webFeeds: Set) { - guard !webFeeds.isEmpty else { + public func removeFeeds(_ feeds: Set) { + guard !feeds.isEmpty else { return } - topLevelWebFeeds.subtract(webFeeds) + topLevelFeeds.subtract(feeds) structureDidChange() postChildrenDidChangeNotification() } - public func addWebFeed(_ webFeed: Feed) { - topLevelWebFeeds.insert(webFeed) + public func addFeed(_ feed: Feed) { + topLevelFeeds.insert(feed) structureDidChange() postChildrenDidChangeNotification() } - func addFeedIfNotInAnyFolder(_ webFeed: Feed) { - if !flattenedWebFeeds().contains(webFeed) { - addWebFeed(webFeed) + func addFeedIfNotInAnyFolder(_ feed: Feed) { + if !flattenedFeeds().contains(feed) { + addFeed(feed) } } @@ -933,7 +933,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func debugDropConditionalGetInfo() { #if DEBUG - flattenedWebFeeds().forEach{ $0.dropConditionalGetInfo() } + flattenedFeeds().forEach{ $0.dropConditionalGetInfo() } #endif } @@ -965,8 +965,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } @objc func batchUpdateDidPerform(_ note: Notification) { - flattenedWebFeedsNeedUpdate = true - rebuildWebFeedDictionaries() + flattenedFeedsNeedUpdate = true + rebuildFeedDictionaries() updateUnreadCount() } @@ -1012,11 +1012,11 @@ extension Account: AccountMetadataDelegate { // MARK: - FeedMetadataDelegate -extension Account: WebFeedMetadataDelegate { +extension Account: FeedMetadataDelegate { - func valueDidChange(_ feedMetadata: WebFeedMetadata, key: WebFeedMetadata.CodingKeys) { - webFeedMetadataFile.markAsDirty() - guard let feed = existingWebFeed(withWebFeedID: feedMetadata.webFeedID) else { + func valueDidChange(_ feedMetadata: FeedMetadata, key: FeedMetadata.CodingKeys) { + feedMetadataFile.markAsDirty() + guard let feed = existingFeed(withFeedID: feedMetadata.feedID) else { return } feed.postFeedSettingDidChangeNotification(key) @@ -1028,11 +1028,11 @@ extension Account: WebFeedMetadataDelegate { private extension Account { func fetchStarredArticles(limit: Int?) throws -> Set
{ - return try database.fetchStarredArticles(flattenedWebFeeds().webFeedIDs(), limit) + return try database.fetchStarredArticles(flattenedFeeds().feedIDs(), limit) } func fetchStarredArticlesAsync(limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - database.fetchedStarredArticlesAsync(flattenedWebFeeds().webFeedIDs(), limit, completion) + database.fetchedStarredArticlesAsync(flattenedFeeds().feedIDs(), limit, completion) } func fetchUnreadArticles(limit: Int?) throws -> Set
{ @@ -1044,11 +1044,11 @@ private extension Account { } func fetchTodayArticles(limit: Int?) throws -> Set
{ - return try database.fetchTodayArticles(flattenedWebFeeds().webFeedIDs(), limit) + return try database.fetchTodayArticles(flattenedFeeds().feedIDs(), limit) } func fetchTodayArticlesAsync(limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - database.fetchTodayArticlesAsync(flattenedWebFeeds().webFeedIDs(), limit, completion) + database.fetchTodayArticlesAsync(flattenedFeeds().feedIDs(), limit, completion) } func fetchArticles(folder: Folder) throws -> Set
{ @@ -1067,17 +1067,17 @@ private extension Account { fetchUnreadArticlesAsync(forContainer: folder, limit: nil, completion) } - func fetchArticles(webFeed: Feed) throws -> Set
{ - let articles = try database.fetchArticles(webFeed.webFeedID) - validateUnreadCount(webFeed, articles) + func fetchArticles(feed: Feed) throws -> Set
{ + let articles = try database.fetchArticles(feed.feedID) + validateUnreadCount(feed, articles) return articles } - func fetchArticlesAsync(webFeed: Feed, _ completion: @escaping ArticleSetResultBlock) { - database.fetchArticlesAsync(webFeed.webFeedID) { [weak self] articleSetResult in + func fetchArticlesAsync(feed: Feed, _ completion: @escaping ArticleSetResultBlock) { + database.fetchArticlesAsync(feed.feedID) { [weak self] articleSetResult in switch articleSetResult { case .success(let articles): - self?.validateUnreadCount(webFeed, articles) + self?.validateUnreadCount(feed, articles) completion(.success(articles)) case .failure(let databaseError): completion(.failure(databaseError)) @@ -1086,7 +1086,7 @@ private extension Account { } func fetchArticlesMatching(_ searchString: String) throws -> Set
{ - return try database.fetchArticlesMatching(searchString, flattenedWebFeeds().webFeedIDs()) + return try database.fetchArticlesMatching(searchString, flattenedFeeds().feedIDs()) } func fetchArticlesMatchingWithArticleIDs(_ searchString: String, _ articleIDs: Set) throws -> Set
{ @@ -1094,7 +1094,7 @@ private extension Account { } func fetchArticlesMatchingAsync(_ searchString: String, _ completion: @escaping ArticleSetResultBlock) { - database.fetchArticlesMatchingAsync(searchString, flattenedWebFeeds().webFeedIDs(), completion) + database.fetchArticlesMatchingAsync(searchString, flattenedFeeds().feedIDs(), completion) } func fetchArticlesMatchingWithArticleIDsAsync(_ searchString: String, _ articleIDs: Set, _ completion: @escaping ArticleSetResultBlock) { @@ -1109,25 +1109,25 @@ private extension Account { return database.fetchArticlesAsync(articleIDs: articleIDs, completion) } - func fetchUnreadArticles(webFeed: Feed) throws -> Set
{ - let articles = try database.fetchUnreadArticles(Set([webFeed.webFeedID]), nil) - validateUnreadCount(webFeed, articles) + func fetchUnreadArticles(feed: Feed) throws -> Set
{ + let articles = try database.fetchUnreadArticles(Set([feed.feedID]), nil) + validateUnreadCount(feed, articles) return articles } func fetchArticles(forContainer container: Container) throws -> Set
{ - let feeds = container.flattenedWebFeeds() - let articles = try database.fetchArticles(feeds.webFeedIDs()) + let feeds = container.flattenedFeeds() + let articles = try database.fetchArticles(feeds.feedIDs()) validateUnreadCountsAfterFetchingUnreadArticles(feeds, articles) return articles } func fetchArticlesAsync(forContainer container: Container, _ completion: @escaping ArticleSetResultBlock) { - let webFeeds = container.flattenedWebFeeds() - database.fetchArticlesAsync(webFeeds.webFeedIDs()) { [weak self] (articleSetResult) in + let feeds = container.flattenedFeeds() + database.fetchArticlesAsync(feeds.feedIDs()) { [weak self] (articleSetResult) in switch articleSetResult { case .success(let articles): - self?.validateUnreadCountsAfterFetchingUnreadArticles(webFeeds, articles) + self?.validateUnreadCountsAfterFetchingUnreadArticles(feeds, articles) completion(.success(articles)) case .failure(let databaseError): completion(.failure(databaseError)) @@ -1136,8 +1136,8 @@ private extension Account { } func fetchUnreadArticles(forContainer container: Container, limit: Int?) throws -> Set
{ - let feeds = container.flattenedWebFeeds() - let articles = try database.fetchUnreadArticles(feeds.webFeedIDs(), limit) + let feeds = container.flattenedFeeds() + let articles = try database.fetchUnreadArticles(feeds.feedIDs(), limit) // We don't validate limit queries because they, by definition, won't correctly match the // complete unread state for the given container. @@ -1149,15 +1149,15 @@ private extension Account { } func fetchUnreadArticlesAsync(forContainer container: Container, limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - let webFeeds = container.flattenedWebFeeds() - database.fetchUnreadArticlesAsync(webFeeds.webFeedIDs(), limit) { [weak self] (articleSetResult) in + let feeds = container.flattenedFeeds() + database.fetchUnreadArticlesAsync(feeds.feedIDs(), limit) { [weak self] (articleSetResult) in switch articleSetResult { case .success(let articles): // We don't validate limit queries because they, by definition, won't correctly match the // complete unread state for the given container. if limit == nil { - self?.validateUnreadCountsAfterFetchingUnreadArticles(webFeeds, articles) + self?.validateUnreadCountsAfterFetchingUnreadArticles(feeds, articles) } completion(.success(articles)) @@ -1167,34 +1167,34 @@ private extension Account { } } - func validateUnreadCountsAfterFetchingUnreadArticles(_ webFeeds: Set, _ articles: Set
) { + func validateUnreadCountsAfterFetchingUnreadArticles(_ feeds: Set, _ articles: Set
) { // Validate unread counts. This was the site of a performance slowdown: // it was calling going through the entire list of articles once per feed: // feeds.forEach { validateUnreadCount($0, articles) } // Now we loop through articles exactly once. This makes a huge difference. - var unreadCountStorage = [String: Int]() // [WebFeedID: Int] + var unreadCountStorage = [String: Int]() // [FeedID: Int] for article in articles where !article.status.read { - unreadCountStorage[article.webFeedID, default: 0] += 1 + unreadCountStorage[article.feedID, default: 0] += 1 } - webFeeds.forEach { (webFeed) in - let unreadCount = unreadCountStorage[webFeed.webFeedID, default: 0] - webFeed.unreadCount = unreadCount + feeds.forEach { (feed) in + let unreadCount = unreadCountStorage[feed.feedID, default: 0] + feed.unreadCount = unreadCount } } - func validateUnreadCount(_ webFeed: Feed, _ articles: Set
) { + func validateUnreadCount(_ feed: Feed, _ articles: Set
) { // articles must contain all the unread articles for the feed. // The unread number should match the feed’s unread count. let feedUnreadCount = articles.reduce(0) { (result, article) -> Int in - if article.webFeed == webFeed && !article.status.read { + if article.feed == feed && !article.status.read { return result + 1 } return result } - webFeed.unreadCount = feedUnreadCount + feed.unreadCount = feedUnreadCount } } @@ -1202,42 +1202,42 @@ private extension Account { private extension Account { - func webFeedMetadata(feedURL: String, webFeedID: String) -> WebFeedMetadata { - if let d = webFeedMetadata[feedURL] { + func feedMetadata(feedURL: String, feedID: String) -> FeedMetadata { + if let d = feedMetadata[feedURL] { assert(d.delegate === self) return d } - let d = WebFeedMetadata(webFeedID: webFeedID) + let d = FeedMetadata(feedID: feedID) d.delegate = self - webFeedMetadata[feedURL] = d + feedMetadata[feedURL] = d return d } - func updateFlattenedWebFeeds() { + func updateFlattenedFeeds() { var feeds = Set() - feeds.formUnion(topLevelWebFeeds) + feeds.formUnion(topLevelFeeds) for folder in folders! { - feeds.formUnion(folder.flattenedWebFeeds()) + feeds.formUnion(folder.flattenedFeeds()) } - _flattenedWebFeeds = feeds - flattenedWebFeedsNeedUpdate = false + _flattenedFeeds = feeds + flattenedFeedsNeedUpdate = false } - func rebuildWebFeedDictionaries() { + func rebuildFeedDictionaries() { var idDictionary = [String: Feed]() var externalIDDictionary = [String: Feed]() - flattenedWebFeeds().forEach { (feed) in - idDictionary[feed.webFeedID] = feed + flattenedFeeds().forEach { (feed) in + idDictionary[feed.feedID] = feed if let externalID = feed.externalID { externalIDDictionary[externalID] = feed } } - _idToWebFeedDictionary = idDictionary - _externalIDToWebFeedDictionary = externalIDDictionary - webFeedDictionariesNeedUpdate = false + _idToFeedDictionary = idDictionary + _externalIDToFeedDictionary = externalIDDictionary + feedDictionariesNeedUpdate = false } func updateUnreadCount() { @@ -1245,14 +1245,14 @@ private extension Account { return } var updatedUnreadCount = 0 - for feed in flattenedWebFeeds() { + for feed in flattenedFeeds() { updatedUnreadCount += feed.unreadCount } unreadCount = updatedUnreadCount } func noteStatusesForArticlesDidChange(_ articles: Set
) { - let feeds = Set(articles.compactMap { $0.webFeed }) + let feeds = Set(articles.compactMap { $0.feed }) let statuses = Set(articles.map { $0.status }) let articleIDs = Set(articles.map { $0.articleID }) @@ -1260,7 +1260,7 @@ private extension Account { // which will update their own unread counts. updateUnreadCounts(for: feeds) - NotificationCenter.default.post(name: .StatusesDidChange, object: self, userInfo: [UserInfoKey.statuses: statuses, UserInfoKey.articles: articles, UserInfoKey.articleIDs: articleIDs, UserInfoKey.webFeeds: feeds]) + NotificationCenter.default.post(name: .StatusesDidChange, object: self, userInfo: [UserInfoKey.statuses: statuses, UserInfoKey.articles: articles, UserInfoKey.articleIDs: articleIDs, UserInfoKey.feeds: feeds]) } func noteStatusesForArticleIDsDidChange(articleIDs: Set, statusKey: ArticleStatus.Key, flag: Bool) { @@ -1293,7 +1293,7 @@ private extension Account { } func fetchUnreadCount(_ feed: Feed, _ completion: VoidCompletionBlock?) { - database.fetchUnreadCount(feed.webFeedID) { result in + database.fetchUnreadCount(feed.feedID) { result in if let unreadCount = try? result.get() { feed.unreadCount = unreadCount } @@ -1302,8 +1302,8 @@ private extension Account { } func fetchUnreadCounts(_ feeds: Set, _ completion: VoidCompletionBlock?) { - let webFeedIDs = Set(feeds.map { $0.webFeedID }) - database.fetchUnreadCounts(for: webFeedIDs) { result in + let feedIDs = Set(feeds.map { $0.feedID }) + database.fetchUnreadCounts(for: feedIDs) { result in if let unreadCountDictionary = try? result.get() { self.processUnreadCounts(unreadCountDictionary: unreadCountDictionary, feeds: feeds) } @@ -1318,7 +1318,7 @@ private extension Account { completion?() return } - self.processUnreadCounts(unreadCountDictionary: unreadCountDictionary, feeds: self.flattenedWebFeeds()) + self.processUnreadCounts(unreadCountDictionary: unreadCountDictionary, feeds: self.flattenedFeeds()) self.fetchingAllUnreadCounts = false self.updateUnreadCount() @@ -1334,19 +1334,19 @@ private extension Account { func processUnreadCounts(unreadCountDictionary: UnreadCountDictionary, feeds: Set) { for feed in feeds { // When the unread count is zero, it won’t appear in unreadCountDictionary. - let unreadCount = unreadCountDictionary[feed.webFeedID] ?? 0 + let unreadCount = unreadCountDictionary[feed.feedID] ?? 0 feed.unreadCount = unreadCount } } func sendNotificationAbout(_ articleChanges: ArticleChanges) { - var webFeeds = Set() + var feeds = Set() if let newArticles = articleChanges.newArticles { - webFeeds.formUnion(Set(newArticles.compactMap { $0.webFeed })) + feeds.formUnion(Set(newArticles.compactMap { $0.feed })) } if let updatedArticles = articleChanges.updatedArticles { - webFeeds.formUnion(Set(updatedArticles.compactMap { $0.webFeed })) + feeds.formUnion(Set(updatedArticles.compactMap { $0.feed })) } var shouldSendNotification = false @@ -1369,11 +1369,11 @@ private extension Account { } if shouldUpdateUnreadCounts { - self.updateUnreadCounts(for: webFeeds) + self.updateUnreadCounts(for: feeds) } if shouldSendNotification { - userInfo[UserInfoKey.webFeeds] = webFeeds + userInfo[UserInfoKey.feeds] = feeds NotificationCenter.default.post(name: .AccountDidDownloadArticles, object: self, userInfo: userInfo) } } @@ -1383,12 +1383,12 @@ private extension Account { extension Account { - public func existingWebFeed(withWebFeedID webFeedID: String) -> Feed? { - return idToWebFeedDictionary[webFeedID] + public func existingFeed(withFeedID feedID: String) -> Feed? { + return idToFeedDictionary[feedID] } - public func existingWebFeed(withExternalID externalID: String) -> Feed? { - return externalIDToWebFeedDictionary[externalID] + public func existingFeed(withExternalID externalID: String) -> Feed? { + return externalIDToFeedDictionary[externalID] } } @@ -1399,7 +1399,7 @@ extension Account: OPMLRepresentable { public func OPMLString(indentLevel: Int, allowCustomAttributes: Bool) -> String { var s = "" - for feed in topLevelWebFeeds.sorted() { + for feed in topLevelFeeds.sorted() { s += feed.OPMLString(indentLevel: indentLevel + 1, allowCustomAttributes: allowCustomAttributes) } for folder in folders!.sorted() { diff --git a/Account/Sources/Account/AccountDelegate.swift b/Account/Sources/Account/AccountDelegate.swift index eb66b0374..a8981bc6a 100644 --- a/Account/Sources/Account/AccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegate.swift @@ -36,13 +36,13 @@ protocol AccountDelegate { func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result) -> Void) func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result) -> Void) - func createWebFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) - func addWebFeed(for account: Account, with: Feed, to container: Container, completion: @escaping (Result) -> Void) - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) - func moveWebFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) + func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) + func addFeed(for account: Account, with: Feed, to container: Container, completion: @escaping (Result) -> Void) + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) + func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) func markArticles(for account: Account, articles: Set
, statusKey: ArticleStatus.Key, flag: Bool, completion: @escaping (Result) -> Void) diff --git a/Account/Sources/Account/AccountManager.swift b/Account/Sources/Account/AccountManager.swift index f3c1fa853..fb25443b4 100644 --- a/Account/Sources/Account/AccountManager.swift +++ b/Account/Sources/Account/AccountManager.swift @@ -203,9 +203,9 @@ public final class AccountManager: UnreadCountProvider { if let account = existingAccount(with: accountID) { return account.existingFolder(with: folderName) } - case .webFeed(let accountID, let webFeedID): + case .feed(let accountID, let feedID): if let account = existingAccount(with: accountID) { - return account.existingWebFeed(withWebFeedID: webFeedID) + return account.existingFeed(withFeedID: feedID) } default: break @@ -330,7 +330,7 @@ public final class AccountManager: UnreadCountProvider { public func anyAccountHasAtLeastOneFeed() -> Bool { for account in activeAccounts { - if account.hasAtLeastOneWebFeed() { + if account.hasAtLeastOneFeed() { return true } } @@ -344,7 +344,7 @@ public final class AccountManager: UnreadCountProvider { public func anyAccountHasFeedWithURL(_ urlString: String) -> Bool { for account in activeAccounts { - if let _ = account.existingWebFeed(withURL: urlString) { + if let _ = account.existingFeed(withURL: urlString) { return true } } diff --git a/Account/Sources/Account/ArticleFetcher.swift b/Account/Sources/Account/ArticleFetcher.swift index 39828b4ed..007c66e17 100644 --- a/Account/Sources/Account/ArticleFetcher.swift +++ b/Account/Sources/Account/ArticleFetcher.swift @@ -21,7 +21,7 @@ public protocol ArticleFetcher { extension Feed: ArticleFetcher { public func fetchArticles() throws -> Set
{ - return try account?.fetchArticles(.webFeed(self)) ?? Set
() + return try account?.fetchArticles(.feed(self)) ?? Set
() } public func fetchArticlesAsync(_ completion: @escaping ArticleSetResultBlock) { @@ -30,7 +30,7 @@ extension Feed: ArticleFetcher { completion(.success(Set
())) return } - account.fetchArticlesAsync(.webFeed(self), completion) + account.fetchArticlesAsync(.feed(self), completion) } public func fetchUnreadArticles() throws -> Set
{ @@ -43,7 +43,7 @@ extension Feed: ArticleFetcher { completion(.success(Set
())) return } - account.fetchArticlesAsync(.webFeed(self)) { articleSetResult in + account.fetchArticlesAsync(.feed(self)) { articleSetResult in switch articleSetResult { case .success(let articles): completion(.success(articles.unreadArticles())) diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index 44ef69fc9..58ada8bea 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -175,7 +175,7 @@ final class CloudKitAccountDelegate: AccountDelegate { } - func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + func createFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { guard let url = URL(string: urlString) else { completion(.failure(LocalAccountDelegateError.invalidParameter)) return @@ -183,13 +183,13 @@ final class CloudKitAccountDelegate: AccountDelegate { let editedName = name == nil || name!.isEmpty ? nil : name - createRSSWebFeed(for: account, url: url, editedName: editedName, container: container, validateFeed: validateFeed, completion: completion) + createRSSFeed(for: account, url: url, editedName: editedName, container: container, validateFeed: validateFeed, completion: completion) } - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { let editedName = name.isEmpty ? nil : name refreshProgress.addToNumberOfTasksAndRemaining(1) - accountZone.renameWebFeed(feed, editedName: editedName) { result in + accountZone.renameFeed(feed, editedName: editedName) { result in self.refreshProgress.completeTask() switch result { case .success: @@ -202,19 +202,19 @@ final class CloudKitAccountDelegate: AccountDelegate { } } - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { - removeWebFeedFromCloud(for: account, with: feed, from: container) { result in + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + removeFeedFromCloud(for: account, with: feed, from: container) { result in switch result { case .success: - account.clearWebFeedMetadata(feed) - container.removeWebFeed(feed) + account.clearFeedMetadata(feed) + container.removeFeed(feed) completion(.success(())) case .failure(let error): switch error { case CloudKitZoneError.corruptAccount: // We got into a bad state and should remove the feed to clear up the bad data - account.clearWebFeedMetadata(feed) - container.removeWebFeed(feed) + account.clearFeedMetadata(feed) + container.removeFeed(feed) default: completion(.failure(error)) } @@ -222,14 +222,14 @@ final class CloudKitAccountDelegate: AccountDelegate { } } - func moveWebFeed(for account: Account, with feed: Feed, from fromContainer: Container, to toContainer: Container, completion: @escaping (Result) -> Void) { + func moveFeed(for account: Account, with feed: Feed, from fromContainer: Container, to toContainer: Container, completion: @escaping (Result) -> Void) { refreshProgress.addToNumberOfTasksAndRemaining(1) - accountZone.moveWebFeed(feed, from: fromContainer, to: toContainer) { result in + accountZone.moveFeed(feed, from: fromContainer, to: toContainer) { result in self.refreshProgress.completeTask() switch result { case .success: - fromContainer.removeWebFeed(feed) - toContainer.addWebFeed(feed) + fromContainer.removeFeed(feed) + toContainer.addFeed(feed) completion(.success(())) case .failure(let error): self.processAccountError(account, error) @@ -238,13 +238,13 @@ final class CloudKitAccountDelegate: AccountDelegate { } } - func addWebFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { + func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { refreshProgress.addToNumberOfTasksAndRemaining(1) - accountZone.addWebFeed(feed, to: container) { result in + accountZone.addFeed(feed, to: container) { result in self.refreshProgress.completeTask() switch result { case .success: - container.addWebFeed(feed) + container.addFeed(feed) completion(.success(())) case .failure(let error): self.processAccountError(account, error) @@ -253,8 +253,8 @@ final class CloudKitAccountDelegate: AccountDelegate { } } - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - createWebFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { + createFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in switch result { case .success: completion(.success(())) @@ -301,18 +301,18 @@ final class CloudKitAccountDelegate: AccountDelegate { func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result) -> Void) { refreshProgress.addToNumberOfTasksAndRemaining(2) - accountZone.findWebFeedExternalIDs(for: folder) { result in + accountZone.findFeedExternalIDs(for: folder) { result in self.refreshProgress.completeTask() switch result { - case .success(let webFeedExternalIDs): + case .success(let feedExternalIDs): - let webFeeds = webFeedExternalIDs.compactMap { account.existingWebFeed(withExternalID: $0) } + let feeds = feedExternalIDs.compactMap { account.existingFeed(withExternalID: $0) } let group = DispatchGroup() var errorOccurred = false - for webFeed in webFeeds { + for feed in feeds { group.enter() - self.removeWebFeedFromCloud(for: account, with: webFeed, from: folder) { result in + self.removeFeedFromCloud(for: account, with: feed, from: folder) { result in group.leave() if case .failure(let error) = result { os_log(.error, log: self.log, "Remove folder, remove webfeed error: %@.", error.localizedDescription) @@ -358,7 +358,7 @@ final class CloudKitAccountDelegate: AccountDelegate { return } - let feedsToRestore = folder.topLevelWebFeeds + let feedsToRestore = folder.topLevelFeeds refreshProgress.addToNumberOfTasksAndRemaining(1 + feedsToRestore.count) accountZone.createFolder(name: name) { result in @@ -371,10 +371,10 @@ final class CloudKitAccountDelegate: AccountDelegate { let group = DispatchGroup() for feed in feedsToRestore { - folder.topLevelWebFeeds.remove(feed) + folder.topLevelFeeds.remove(feed) group.enter() - self.restoreWebFeed(for: account, feed: feed, container: folder) { result in + self.restoreFeed(for: account, feed: feed, container: folder) { result in self.refreshProgress.completeTask() group.leave() switch result { @@ -485,8 +485,8 @@ private extension CloudKitAccountDelegate { accountZone.fetchChangesInZone() { result in self.refreshProgress.completeTask() - let webFeeds = account.flattenedWebFeeds() - self.refreshProgress.addToNumberOfTasksAndRemaining(webFeeds.count) + let feeds = account.flattenedFeeds() + self.refreshProgress.addToNumberOfTasksAndRemaining(feeds.count) switch result { case .success: @@ -495,7 +495,7 @@ private extension CloudKitAccountDelegate { switch result { case .success: - self.combinedRefresh(account, webFeeds) { result in + self.combinedRefresh(account, feeds) { result in self.refreshProgress.clear() switch result { case .success: @@ -518,8 +518,8 @@ private extension CloudKitAccountDelegate { func standardRefreshAll(for account: Account, completion: @escaping (Result) -> Void) { - let intialWebFeedsCount = account.flattenedWebFeeds().count - refreshProgress.addToNumberOfTasksAndRemaining(3 + intialWebFeedsCount) + let intialFeedsCount = account.flattenedFeeds().count + refreshProgress.addToNumberOfTasksAndRemaining(3 + intialFeedsCount) func fail(_ error: Error) { self.processAccountError(account, error) @@ -532,14 +532,14 @@ private extension CloudKitAccountDelegate { case .success: self.refreshProgress.completeTask() - let webFeeds = account.flattenedWebFeeds() - self.refreshProgress.addToNumberOfTasksAndRemaining(webFeeds.count - intialWebFeedsCount) + let feeds = account.flattenedFeeds() + self.refreshProgress.addToNumberOfTasksAndRemaining(feeds.count - intialFeedsCount) self.refreshArticleStatus(for: account) { result in switch result { case .success: self.refreshProgress.completeTask() - self.combinedRefresh(account, webFeeds) { result in + self.combinedRefresh(account, feeds) { result in self.sendArticleStatus(for: account, showProgress: true) { _ in self.refreshProgress.clear() if case .failure(let error) = result { @@ -562,12 +562,12 @@ private extension CloudKitAccountDelegate { } - func combinedRefresh(_ account: Account, _ webFeeds: Set, completion: @escaping (Result) -> Void) { + func combinedRefresh(_ account: Account, _ feeds: Set, completion: @escaping (Result) -> Void) { let group = DispatchGroup() group.enter() - refresher.refreshFeeds(webFeeds) { + refresher.refreshFeeds(feeds) { group.leave() } @@ -576,13 +576,13 @@ private extension CloudKitAccountDelegate { } } - func createRSSWebFeed(for account: Account, url: URL, editedName: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + func createRSSFeed(for account: Account, url: URL, editedName: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { func addDeadFeed() { - let feed = account.createWebFeed(with: editedName, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil) - container.addWebFeed(feed) + let feed = account.createFeed(with: editedName, url: url.absoluteString, feedID: url.absoluteString, homePageURL: nil) + container.addFeed(feed) - self.accountZone.createWebFeed(url: url.absoluteString, + self.accountZone.createFeed(url: url.absoluteString, name: editedName, editedName: nil, homePageURL: nil, @@ -594,7 +594,7 @@ private extension CloudKitAccountDelegate { feed.externalID = externalID completion(.success(feed)) case .failure(let error): - container.removeWebFeed(feed) + container.removeFeed(feed) completion(.failure(error)) } } @@ -617,15 +617,15 @@ private extension CloudKitAccountDelegate { return } - if account.hasWebFeed(withURL: bestFeedSpecifier.urlString) { + if account.hasFeed(withURL: bestFeedSpecifier.urlString) { self.refreshProgress.completeTasks(4) completion(.failure(AccountError.createErrorAlreadySubscribed)) return } - let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil) + let feed = account.createFeed(with: nil, url: url.absoluteString, feedID: url.absoluteString, homePageURL: nil) feed.editedName = editedName - container.addWebFeed(feed) + container.addFeed(feed) InitialFeedDownloader.download(url) { parsedFeed in self.refreshProgress.completeTask() @@ -635,7 +635,7 @@ private extension CloudKitAccountDelegate { switch result { case .success: - self.accountZone.createWebFeed(url: bestFeedSpecifier.urlString, + self.accountZone.createFeed(url: bestFeedSpecifier.urlString, name: parsedFeed.title, editedName: editedName, homePageURL: parsedFeed.homePageURL, @@ -648,7 +648,7 @@ private extension CloudKitAccountDelegate { self.sendNewArticlesToTheCloud(account, feed) completion(.success(feed)) case .failure(let error): - container.removeWebFeed(feed) + container.removeFeed(feed) self.refreshProgress.completeTasks(2) completion(.failure(error)) } @@ -656,7 +656,7 @@ private extension CloudKitAccountDelegate { } case .failure(let error): - container.removeWebFeed(feed) + container.removeFeed(feed) self.refreshProgress.completeTasks(3) completion(.failure(error)) } @@ -664,7 +664,7 @@ private extension CloudKitAccountDelegate { } } else { self.refreshProgress.completeTasks(3) - container.removeWebFeed(feed) + container.removeFeed(feed) completion(.failure(AccountError.createErrorNotFound)) } @@ -684,7 +684,7 @@ private extension CloudKitAccountDelegate { } func sendNewArticlesToTheCloud(_ account: Account, _ feed: Feed) { - account.fetchArticlesAsync(.webFeed(feed)) { result in + account.fetchArticlesAsync(.feed(feed)) { result in switch result { case .success(let articles): self.storeArticleChanges(new: articles, updated: Set
(), deleted: Set
()) { @@ -706,7 +706,7 @@ private extension CloudKitAccountDelegate { func processAccountError(_ account: Account, _ error: Error) { if case CloudKitZoneError.userDeletedZone = error { - account.removeFeeds(account.topLevelWebFeeds) + account.removeFeeds(account.topLevelFeeds) for folder in account.folders ?? Set() { account.removeFolder(folder) } @@ -771,17 +771,17 @@ private extension CloudKitAccountDelegate { } - func removeWebFeedFromCloud(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + func removeFeedFromCloud(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { refreshProgress.addToNumberOfTasksAndRemaining(2) - accountZone.removeWebFeed(feed, from: container) { result in + accountZone.removeFeed(feed, from: container) { result in self.refreshProgress.completeTask() switch result { case .success: - guard let webFeedExternalID = feed.externalID else { + guard let feedExternalID = feed.externalID else { completion(.success(())) return } - self.articlesZone.deleteArticles(webFeedExternalID) { result in + self.articlesZone.deleteArticles(feedExternalID) { result in feed.dropConditionalGetInfo() self.refreshProgress.completeTask() completion(result) diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift b/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift index eb935dea5..0e49f2890 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountZone.swift @@ -29,7 +29,7 @@ final class CloudKitAccountZone: CloudKitZone { weak var database: CKDatabase? var delegate: CloudKitZoneDelegate? - struct CloudKitWebFeed { + struct CloudKitFeed { static let recordType = "AccountWebFeed" struct Fields { static let url = "url" @@ -60,13 +60,13 @@ final class CloudKitAccountZone: CloudKitZone { var feedRecords = [String: CKRecord]() func processFeed(feedSpecifier: RSOPMLFeedSpecifier, containerExternalID: String) { - if let webFeedRecord = feedRecords[feedSpecifier.feedURL], var containerExternalIDs = webFeedRecord[CloudKitWebFeed.Fields.containerExternalIDs] as? [String] { + if let feedRecord = feedRecords[feedSpecifier.feedURL], var containerExternalIDs = feedRecord[CloudKitFeed.Fields.containerExternalIDs] as? [String] { containerExternalIDs.append(containerExternalID) - webFeedRecord[CloudKitWebFeed.Fields.containerExternalIDs] = containerExternalIDs + feedRecord[CloudKitFeed.Fields.containerExternalIDs] = containerExternalIDs } else { - let webFeedRecord = newWebFeedCKRecord(feedSpecifier: feedSpecifier, containerExternalID: containerExternalID) - records.append(webFeedRecord) - feedRecords[feedSpecifier.feedURL] = webFeedRecord + let feedRecord = newFeedCKRecord(feedSpecifier: feedSpecifier, containerExternalID: containerExternalID) + records.append(feedRecord) + feedRecords[feedSpecifier.feedURL] = feedRecord } } @@ -90,23 +90,23 @@ final class CloudKitAccountZone: CloudKitZone { } /// Persist a web feed record to iCloud and return the external key - func createWebFeed(url: String, name: String?, editedName: String?, homePageURL: String?, container: Container, completion: @escaping (Result) -> Void) { + func createFeed(url: String, name: String?, editedName: String?, homePageURL: String?, container: Container, completion: @escaping (Result) -> Void) { let recordID = CKRecord.ID(recordName: url.md5String, zoneID: zoneID) - let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID) - record[CloudKitWebFeed.Fields.url] = url - record[CloudKitWebFeed.Fields.name] = name + let record = CKRecord(recordType: CloudKitFeed.recordType, recordID: recordID) + record[CloudKitFeed.Fields.url] = url + record[CloudKitFeed.Fields.name] = name if let editedName = editedName { - record[CloudKitWebFeed.Fields.editedName] = editedName + record[CloudKitFeed.Fields.editedName] = editedName } if let homePageURL = homePageURL { - record[CloudKitWebFeed.Fields.homePageURL] = homePageURL + record[CloudKitFeed.Fields.homePageURL] = homePageURL } guard let containerExternalID = container.externalID else { completion(.failure(CloudKitZoneError.corruptAccount)) return } - record[CloudKitWebFeed.Fields.containerExternalIDs] = [containerExternalID] + record[CloudKitFeed.Fields.containerExternalIDs] = [containerExternalID] save(record) { result in switch result { @@ -119,15 +119,15 @@ final class CloudKitAccountZone: CloudKitZone { } /// Rename the given web feed - func renameWebFeed(_ webFeed: Feed, editedName: String?, completion: @escaping (Result) -> Void) { - guard let externalID = webFeed.externalID else { + func renameFeed(_ feed: Feed, editedName: String?, completion: @escaping (Result) -> Void) { + guard let externalID = feed.externalID else { completion(.failure(CloudKitZoneError.corruptAccount)) return } let recordID = CKRecord.ID(recordName: externalID, zoneID: zoneID) - let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: recordID) - record[CloudKitWebFeed.Fields.editedName] = editedName + let record = CKRecord(recordType: CloudKitFeed.recordType, recordID: recordID) + record[CloudKitFeed.Fields.editedName] = editedName save(record) { result in switch result { @@ -140,22 +140,22 @@ final class CloudKitAccountZone: CloudKitZone { } /// Removes a web feed from a container and optionally deletes it, calling the completion with true if deleted - func removeWebFeed(_ webFeed: Feed, from: Container, completion: @escaping (Result) -> Void) { + func removeFeed(_ feed: Feed, from: Container, completion: @escaping (Result) -> Void) { guard let fromContainerExternalID = from.externalID else { completion(.failure(CloudKitZoneError.corruptAccount)) return } - fetch(externalID: webFeed.externalID) { result in + fetch(externalID: feed.externalID) { result in switch result { case .success(let record): - if let containerExternalIDs = record[CloudKitWebFeed.Fields.containerExternalIDs] as? [String] { + if let containerExternalIDs = record[CloudKitFeed.Fields.containerExternalIDs] as? [String] { var containerExternalIDSet = Set(containerExternalIDs) containerExternalIDSet.remove(fromContainerExternalID) if containerExternalIDSet.isEmpty { - self.delete(externalID: webFeed.externalID) { result in + self.delete(externalID: feed.externalID) { result in switch result { case .success: completion(.success(true)) @@ -166,7 +166,7 @@ final class CloudKitAccountZone: CloudKitZone { } else { - record[CloudKitWebFeed.Fields.containerExternalIDs] = Array(containerExternalIDSet) + record[CloudKitFeed.Fields.containerExternalIDs] = Array(containerExternalIDSet) self.save(record) { result in switch result { case .success: @@ -189,20 +189,20 @@ final class CloudKitAccountZone: CloudKitZone { } } - func moveWebFeed(_ webFeed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { + func moveFeed(_ feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { guard let fromContainerExternalID = from.externalID, let toContainerExternalID = to.externalID else { completion(.failure(CloudKitZoneError.corruptAccount)) return } - fetch(externalID: webFeed.externalID) { result in + fetch(externalID: feed.externalID) { result in switch result { case .success(let record): - if let containerExternalIDs = record[CloudKitWebFeed.Fields.containerExternalIDs] as? [String] { + if let containerExternalIDs = record[CloudKitFeed.Fields.containerExternalIDs] as? [String] { var containerExternalIDSet = Set(containerExternalIDs) containerExternalIDSet.remove(fromContainerExternalID) containerExternalIDSet.insert(toContainerExternalID) - record[CloudKitWebFeed.Fields.containerExternalIDs] = Array(containerExternalIDSet) + record[CloudKitFeed.Fields.containerExternalIDs] = Array(containerExternalIDSet) self.save(record, completion: completion) } case .failure(let error): @@ -211,19 +211,19 @@ final class CloudKitAccountZone: CloudKitZone { } } - func addWebFeed(_ webFeed: Feed, to: Container, completion: @escaping (Result) -> Void) { + func addFeed(_ feed: Feed, to: Container, completion: @escaping (Result) -> Void) { guard let toContainerExternalID = to.externalID else { completion(.failure(CloudKitZoneError.corruptAccount)) return } - fetch(externalID: webFeed.externalID) { result in + fetch(externalID: feed.externalID) { result in switch result { case .success(let record): - if let containerExternalIDs = record[CloudKitWebFeed.Fields.containerExternalIDs] as? [String] { + if let containerExternalIDs = record[CloudKitFeed.Fields.containerExternalIDs] as? [String] { var containerExternalIDSet = Set(containerExternalIDs) containerExternalIDSet.insert(toContainerExternalID) - record[CloudKitWebFeed.Fields.containerExternalIDs] = Array(containerExternalIDSet) + record[CloudKitFeed.Fields.containerExternalIDs] = Array(containerExternalIDSet) self.save(record, completion: completion) } case .failure(let error): @@ -232,20 +232,20 @@ final class CloudKitAccountZone: CloudKitZone { } } - func findWebFeedExternalIDs(for folder: Folder, completion: @escaping (Result<[String], Error>) -> Void) { + func findFeedExternalIDs(for folder: Folder, completion: @escaping (Result<[String], Error>) -> Void) { guard let folderExternalID = folder.externalID else { completion(.failure(CloudKitAccountZoneError.unknown)) return } let predicate = NSPredicate(format: "containerExternalIDs CONTAINS %@", folderExternalID) - let ckQuery = CKQuery(recordType: CloudKitWebFeed.recordType, predicate: predicate) + let ckQuery = CKQuery(recordType: CloudKitFeed.recordType, predicate: predicate) query(ckQuery) { result in switch result { case .success(let records): - let webFeedExternalIds = records.map { $0.externalID } - completion(.success(webFeedExternalIds)) + let feedExternalIds = records.map { $0.externalID } + completion(.success(feedExternalIds)) case .failure(let error): completion(.failure(error)) } @@ -322,16 +322,16 @@ final class CloudKitAccountZone: CloudKitZone { private extension CloudKitAccountZone { - func newWebFeedCKRecord(feedSpecifier: RSOPMLFeedSpecifier, containerExternalID: String) -> CKRecord { - let record = CKRecord(recordType: CloudKitWebFeed.recordType, recordID: generateRecordID()) - record[CloudKitWebFeed.Fields.url] = feedSpecifier.feedURL + func newFeedCKRecord(feedSpecifier: RSOPMLFeedSpecifier, containerExternalID: String) -> CKRecord { + let record = CKRecord(recordType: CloudKitFeed.recordType, recordID: generateRecordID()) + record[CloudKitFeed.Fields.url] = feedSpecifier.feedURL if let editedName = feedSpecifier.title { - record[CloudKitWebFeed.Fields.editedName] = editedName + record[CloudKitFeed.Fields.editedName] = editedName } if let homePageURL = feedSpecifier.homePageURL { - record[CloudKitWebFeed.Fields.homePageURL] = homePageURL + record[CloudKitFeed.Fields.homePageURL] = homePageURL } - record[CloudKitWebFeed.Fields.containerExternalIDs] = [containerExternalID] + record[CloudKitFeed.Fields.containerExternalIDs] = [containerExternalID] return record } diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift index 2686d4d7f..4b11514bb 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountZoneDelegate.swift @@ -15,9 +15,9 @@ import Articles class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { - private typealias UnclaimedWebFeed = (url: URL, name: String?, editedName: String?, homePageURL: String?, webFeedExternalID: String) - private var newUnclaimedWebFeeds = [String: [UnclaimedWebFeed]]() - private var existingUnclaimedWebFeeds = [String: [Feed]]() + private typealias UnclaimedFeed = (url: URL, name: String?, editedName: String?, homePageURL: String?, feedExternalID: String) + private var newUnclaimedFeeds = [String: [UnclaimedFeed]]() + private var existingUnclaimedFeeds = [String: [Feed]]() private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") @@ -34,8 +34,8 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result) -> Void) { for deletedRecordKey in deleted { switch deletedRecordKey.recordType { - case CloudKitAccountZone.CloudKitWebFeed.recordType: - removeWebFeed(deletedRecordKey.recordID.externalID) + case CloudKitAccountZone.CloudKitFeed.recordType: + removeFeed(deletedRecordKey.recordID.externalID) case CloudKitAccountZone.CloudKitContainer.recordType: removeContainer(deletedRecordKey.recordID.externalID) default: @@ -45,8 +45,8 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { for changedRecord in changed { switch changedRecord.recordType { - case CloudKitAccountZone.CloudKitWebFeed.recordType: - addOrUpdateWebFeed(changedRecord) + case CloudKitAccountZone.CloudKitFeed.recordType: + addOrUpdateFeed(changedRecord) case CloudKitAccountZone.CloudKitContainer.recordType: addOrUpdateContainer(changedRecord) default: @@ -57,36 +57,36 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { completion(.success(())) } - func addOrUpdateWebFeed(_ record: CKRecord) { + func addOrUpdateFeed(_ record: CKRecord) { guard let account = account, - let urlString = record[CloudKitAccountZone.CloudKitWebFeed.Fields.url] as? String, - let containerExternalIDs = record[CloudKitAccountZone.CloudKitWebFeed.Fields.containerExternalIDs] as? [String], + let urlString = record[CloudKitAccountZone.CloudKitFeed.Fields.url] as? String, + let containerExternalIDs = record[CloudKitAccountZone.CloudKitFeed.Fields.containerExternalIDs] as? [String], let url = URL(string: urlString) else { return } - let name = record[CloudKitAccountZone.CloudKitWebFeed.Fields.name] as? String - let editedName = record[CloudKitAccountZone.CloudKitWebFeed.Fields.editedName] as? String - let homePageURL = record[CloudKitAccountZone.CloudKitWebFeed.Fields.homePageURL] as? String + let name = record[CloudKitAccountZone.CloudKitFeed.Fields.name] as? String + let editedName = record[CloudKitAccountZone.CloudKitFeed.Fields.editedName] as? String + let homePageURL = record[CloudKitAccountZone.CloudKitFeed.Fields.homePageURL] as? String - if let webFeed = account.existingWebFeed(withExternalID: record.externalID) { - updateWebFeed(webFeed, name: name, editedName: editedName, homePageURL: homePageURL, containerExternalIDs: containerExternalIDs) + if let feed = account.existingFeed(withExternalID: record.externalID) { + updateFeed(feed, name: name, editedName: editedName, homePageURL: homePageURL, containerExternalIDs: containerExternalIDs) } else { for containerExternalID in containerExternalIDs { if let container = account.existingContainer(withExternalID: containerExternalID) { - createWebFeedIfNecessary(url: url, name: name, editedName: editedName, homePageURL: homePageURL, webFeedExternalID: record.externalID, container: container) + createFeedIfNecessary(url: url, name: name, editedName: editedName, homePageURL: homePageURL, feedExternalID: record.externalID, container: container) } else { - addNewUnclaimedWebFeed(url: url, name: name, editedName: editedName, homePageURL: homePageURL, webFeedExternalID: record.externalID, containerExternalID: containerExternalID) + addNewUnclaimedFeed(url: url, name: name, editedName: editedName, homePageURL: homePageURL, feedExternalID: record.externalID, containerExternalID: containerExternalID) } } } } - func removeWebFeed(_ externalID: String) { - if let webFeed = account?.existingWebFeed(withExternalID: externalID), let containers = account?.existingContainers(withWebFeed: webFeed) { + func removeFeed(_ externalID: String) { + if let feed = account?.existingFeed(withExternalID: externalID), let containers = account?.existingContainers(withFeed: feed) { containers.forEach { - webFeed.dropConditionalGetInfo() - $0.removeWebFeed(webFeed) + feed.dropConditionalGetInfo() + $0.removeFeed(feed) } } } @@ -109,24 +109,24 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { guard let container = folder, let containerExternalID = container.externalID else { return } - if let newUnclaimedWebFeeds = newUnclaimedWebFeeds[containerExternalID] { - for newUnclaimedWebFeed in newUnclaimedWebFeeds { - createWebFeedIfNecessary(url: newUnclaimedWebFeed.url, - name: newUnclaimedWebFeed.name, - editedName: newUnclaimedWebFeed.editedName, - homePageURL: newUnclaimedWebFeed.homePageURL, - webFeedExternalID: newUnclaimedWebFeed.webFeedExternalID, + if let newUnclaimedFeeds = newUnclaimedFeeds[containerExternalID] { + for newUnclaimedFeed in newUnclaimedFeeds { + createFeedIfNecessary(url: newUnclaimedFeed.url, + name: newUnclaimedFeed.name, + editedName: newUnclaimedFeed.editedName, + homePageURL: newUnclaimedFeed.homePageURL, + feedExternalID: newUnclaimedFeed.feedExternalID, container: container) } - self.newUnclaimedWebFeeds.removeValue(forKey: containerExternalID) + self.newUnclaimedFeeds.removeValue(forKey: containerExternalID) } - if let existingUnclaimedWebFeeds = existingUnclaimedWebFeeds[containerExternalID] { - for existingUnclaimedWebFeed in existingUnclaimedWebFeeds { - container.addWebFeed(existingUnclaimedWebFeed) + if let existingUnclaimedFeeds = existingUnclaimedFeeds[containerExternalID] { + for existingUnclaimedFeed in existingUnclaimedFeeds { + container.addFeed(existingUnclaimedFeed) } - self.existingUnclaimedWebFeeds.removeValue(forKey: containerExternalID) + self.existingUnclaimedFeeds.removeValue(forKey: containerExternalID) } } @@ -140,14 +140,14 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { private extension CloudKitAcountZoneDelegate { - func updateWebFeed(_ webFeed: Feed, name: String?, editedName: String?, homePageURL: String?, containerExternalIDs: [String]) { + func updateFeed(_ feed: Feed, name: String?, editedName: String?, homePageURL: String?, containerExternalIDs: [String]) { guard let account = account else { return } - webFeed.name = name - webFeed.editedName = editedName - webFeed.homePageURL = homePageURL + feed.name = name + feed.editedName = editedName + feed.homePageURL = homePageURL - let existingContainers = account.existingContainers(withWebFeed: webFeed) + let existingContainers = account.existingContainers(withFeed: feed) let existingContainerExternalIds = existingContainers.compactMap { $0.externalID } let diff = containerExternalIDs.difference(from: existingContainerExternalIds) @@ -156,50 +156,50 @@ private extension CloudKitAcountZoneDelegate { switch change { case .remove(_, let externalID, _): if let container = existingContainers.first(where: { $0.externalID == externalID }) { - container.removeWebFeed(webFeed) + container.removeFeed(feed) } case .insert(_, let externalID, _): if let container = account.existingContainer(withExternalID: externalID) { - container.addWebFeed(webFeed) + container.addFeed(feed) } else { - addExistingUnclaimedWebFeed(webFeed, containerExternalID: externalID) + addExistingUnclaimedFeed(feed, containerExternalID: externalID) } } } } - func createWebFeedIfNecessary(url: URL, name: String?, editedName: String?, homePageURL: String?, webFeedExternalID: String, container: Container) { + func createFeedIfNecessary(url: URL, name: String?, editedName: String?, homePageURL: String?, feedExternalID: String, container: Container) { guard let account = account else { return } - if account.existingWebFeed(withExternalID: webFeedExternalID) != nil { + if account.existingFeed(withExternalID: feedExternalID) != nil { return } - let webFeed = account.createWebFeed(with: name, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: homePageURL) - webFeed.editedName = editedName - webFeed.externalID = webFeedExternalID - container.addWebFeed(webFeed) + let feed = account.createFeed(with: name, url: url.absoluteString, feedID: url.absoluteString, homePageURL: homePageURL) + feed.editedName = editedName + feed.externalID = feedExternalID + container.addFeed(feed) } - func addNewUnclaimedWebFeed(url: URL, name: String?, editedName: String?, homePageURL: String?, webFeedExternalID: String, containerExternalID: String) { - if var unclaimedWebFeeds = self.newUnclaimedWebFeeds[containerExternalID] { - unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, name: name, editedName: editedName, homePageURL: homePageURL, webFeedExternalID: webFeedExternalID)) - self.newUnclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds + func addNewUnclaimedFeed(url: URL, name: String?, editedName: String?, homePageURL: String?, feedExternalID: String, containerExternalID: String) { + if var unclaimedFeeds = self.newUnclaimedFeeds[containerExternalID] { + unclaimedFeeds.append(UnclaimedFeed(url: url, name: name, editedName: editedName, homePageURL: homePageURL, feedExternalID: feedExternalID)) + self.newUnclaimedFeeds[containerExternalID] = unclaimedFeeds } else { - var unclaimedWebFeeds = [UnclaimedWebFeed]() - unclaimedWebFeeds.append(UnclaimedWebFeed(url: url, name: name, editedName: editedName, homePageURL: homePageURL, webFeedExternalID: webFeedExternalID)) - self.newUnclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds + var unclaimedFeeds = [UnclaimedFeed]() + unclaimedFeeds.append(UnclaimedFeed(url: url, name: name, editedName: editedName, homePageURL: homePageURL, feedExternalID: feedExternalID)) + self.newUnclaimedFeeds[containerExternalID] = unclaimedFeeds } } - func addExistingUnclaimedWebFeed(_ webFeed: Feed, containerExternalID: String) { - if var unclaimedWebFeeds = self.existingUnclaimedWebFeeds[containerExternalID] { - unclaimedWebFeeds.append(webFeed) - self.existingUnclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds + func addExistingUnclaimedFeed(_ feed: Feed, containerExternalID: String) { + if var unclaimedFeeds = self.existingUnclaimedFeeds[containerExternalID] { + unclaimedFeeds.append(feed) + self.existingUnclaimedFeeds[containerExternalID] = unclaimedFeeds } else { - var unclaimedWebFeeds = [Feed]() - unclaimedWebFeeds.append(webFeed) - self.existingUnclaimedWebFeeds[containerExternalID] = unclaimedWebFeeds + var unclaimedFeeds = [Feed]() + unclaimedFeeds.append(feed) + self.existingUnclaimedFeeds[containerExternalID] = unclaimedFeeds } } diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift index 0553513e1..87cc57740 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift @@ -31,7 +31,7 @@ final class CloudKitArticlesZone: CloudKitZone { static let recordType = "Article" struct Fields { static let articleStatus = "articleStatus" - static let webFeedURL = "webFeedURL" + static let feedURL = "webFeedURL" static let uniqueID = "uniqueID" static let title = "title" static let contentHTML = "contentHTML" @@ -51,7 +51,7 @@ final class CloudKitArticlesZone: CloudKitZone { struct CloudKitArticleStatus { static let recordType = "ArticleStatus" struct Fields { - static let webFeedExternalID = "webFeedExternalID" + static let feedExternalID = "webFeedExternalID" static let read = "read" static let starred = "starred" } @@ -106,8 +106,8 @@ final class CloudKitArticlesZone: CloudKitZone { } } - func deleteArticles(_ webFeedExternalID: String, completion: @escaping ((Result) -> Void)) { - let predicate = NSPredicate(format: "webFeedExternalID = %@", webFeedExternalID) + func deleteArticles(_ feedExternalID: String, completion: @escaping ((Result) -> Void)) { + let predicate = NSPredicate(format: "webFeedExternalID = %@", feedExternalID) let ckQuery = CKQuery(recordType: CloudKitArticleStatus.recordType, predicate: predicate) delete(ckQuery: ckQuery, completion: completion) } @@ -190,8 +190,8 @@ private extension CloudKitArticlesZone { func makeStatusRecord(_ article: Article) -> CKRecord { let recordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID) let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID) - if let webFeedExternalID = article.webFeed?.externalID { - record[CloudKitArticleStatus.Fields.webFeedExternalID] = webFeedExternalID + if let feedExternalID = article.feed?.externalID { + record[CloudKitArticleStatus.Fields.feedExternalID] = feedExternalID } record[CloudKitArticleStatus.Fields.read] = article.status.read ? "1" : "0" record[CloudKitArticleStatus.Fields.starred] = article.status.starred ? "1" : "0" @@ -202,8 +202,8 @@ private extension CloudKitArticlesZone { let recordID = CKRecord.ID(recordName: statusID(statusUpdate.articleID), zoneID: zoneID) let record = CKRecord(recordType: CloudKitArticleStatus.recordType, recordID: recordID) - if let webFeedExternalID = statusUpdate.article?.webFeed?.externalID { - record[CloudKitArticleStatus.Fields.webFeedExternalID] = webFeedExternalID + if let feedExternalID = statusUpdate.article?.feed?.externalID { + record[CloudKitArticleStatus.Fields.feedExternalID] = feedExternalID } record[CloudKitArticleStatus.Fields.read] = statusUpdate.isRead ? "1" : "0" @@ -218,7 +218,7 @@ private extension CloudKitArticlesZone { let articleStatusRecordID = CKRecord.ID(recordName: statusID(article.articleID), zoneID: zoneID) record[CloudKitArticle.Fields.articleStatus] = CKRecord.Reference(recordID: articleStatusRecordID, action: .deleteSelf) - record[CloudKitArticle.Fields.webFeedURL] = article.webFeed?.url + record[CloudKitArticle.Fields.feedURL] = article.feed?.url record[CloudKitArticle.Fields.uniqueID] = article.uniqueID record[CloudKitArticle.Fields.title] = article.title record[CloudKitArticle.Fields.contentHTML] = article.contentHTML diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift index 9f006c7bc..96ac57b5b 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift @@ -137,12 +137,12 @@ private extension CloudKitArticlesZoneDelegate { group.enter() compressionQueue.async { let parsedItems = records.compactMap { self.makeParsedItem($0) } - let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } + let feedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } DispatchQueue.main.async { - for (webFeedID, parsedItems) in webFeedIDsAndItems { + for (feedID, parsedItems) in feedIDsAndItems { group.enter() - self.account?.update(webFeedID, with: parsedItems, deleteOlder: false) { result in + self.account?.update(feedID, with: parsedItems, deleteOlder: false) { result in switch result { case .success(let articleChanges): guard let deletes = articleChanges.deletedArticles, !deletes.isEmpty else { @@ -196,7 +196,7 @@ private extension CloudKitArticlesZoneDelegate { } guard let uniqueID = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.uniqueID] as? String, - let webFeedURL = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.webFeedURL] as? String else { + let feedURL = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.feedURL] as? String else { return nil } @@ -216,7 +216,7 @@ private extension CloudKitArticlesZoneDelegate { let parsedItem = ParsedItem(syncServiceID: nil, uniqueID: uniqueID, - feedURL: webFeedURL, + feedURL: feedURL, url: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.url] as? String, externalURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.externalURL] as? String, title: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.title] as? String, diff --git a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift index 6592ae7c1..ff1ddb344 100644 --- a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift +++ b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift @@ -171,7 +171,7 @@ private extension CloudKitSendStatusOperation { func processAccountError(_ account: Account, _ error: Error) { if case CloudKitZoneError.userDeletedZone = error { - account.removeFeeds(account.topLevelWebFeeds) + account.removeFeeds(account.topLevelFeeds) for folder in account.folders ?? Set() { account.removeFolder(folder) } diff --git a/Account/Sources/Account/Container.swift b/Account/Sources/Account/Container.swift index fdd6d5f26..a5d1714db 100644 --- a/Account/Sources/Account/Container.swift +++ b/Account/Sources/Account/Container.swift @@ -19,27 +19,27 @@ extension Notification.Name { public protocol Container: AnyObject, ContainerIdentifiable { var account: Account? { get } - var topLevelWebFeeds: Set { get set } + var topLevelFeeds: Set { get set } var folders: Set? { get set } var externalID: String? { get set } - func hasAtLeastOneWebFeed() -> Bool + func hasAtLeastOneFeed() -> Bool func objectIsChild(_ object: AnyObject) -> Bool func hasChildFolder(with: String) -> Bool func childFolder(with: String) -> Folder? - func removeWebFeed(_ webFeed: Feed) - func addWebFeed(_ webFeed: Feed) + func removeFeed(_ feed: Feed) + func addFeed(_ feed: Feed) //Recursive — checks subfolders - func flattenedWebFeeds() -> Set - func has(_ webFeed: Feed) -> Bool - func hasWebFeed(with webFeedID: String) -> Bool - func hasWebFeed(withURL url: String) -> Bool - func existingWebFeed(withWebFeedID: String) -> Feed? - func existingWebFeed(withURL url: String) -> Feed? - func existingWebFeed(withExternalID externalID: String) -> Feed? + func flattenedFeeds() -> Set + func has(_ feed: Feed) -> Bool + func hasFeed(with feedID: String) -> Bool + func hasFeed(withURL url: String) -> Bool + func existingFeed(withFeedID: String) -> Feed? + func existingFeed(withURL url: String) -> Feed? + func existingFeed(withExternalID externalID: String) -> Feed? func existingFolder(with name: String) -> Folder? func existingFolder(withID: Int) -> Folder? @@ -48,8 +48,8 @@ public protocol Container: AnyObject, ContainerIdentifiable { public extension Container { - func hasAtLeastOneWebFeed() -> Bool { - return topLevelWebFeeds.count > 0 + func hasAtLeastOneFeed() -> Bool { + return topLevelFeeds.count > 0 } func hasChildFolder(with name: String) -> Bool { @@ -70,7 +70,7 @@ public extension Container { func objectIsChild(_ object: AnyObject) -> Bool { if let feed = object as? Feed { - return topLevelWebFeeds.contains(feed) + return topLevelFeeds.contains(feed) } if let folder = object as? Folder { return folders?.contains(folder) ?? false @@ -78,40 +78,40 @@ public extension Container { return false } - func flattenedWebFeeds() -> Set { + func flattenedFeeds() -> Set { var feeds = Set() - feeds.formUnion(topLevelWebFeeds) + feeds.formUnion(topLevelFeeds) if let folders = folders { for folder in folders { - feeds.formUnion(folder.flattenedWebFeeds()) + feeds.formUnion(folder.flattenedFeeds()) } } return feeds } - func hasWebFeed(with webFeedID: String) -> Bool { - return existingWebFeed(withWebFeedID: webFeedID) != nil + func hasFeed(with feedID: String) -> Bool { + return existingFeed(withFeedID: feedID) != nil } - func hasWebFeed(withURL url: String) -> Bool { - return existingWebFeed(withURL: url) != nil + func hasFeed(withURL url: String) -> Bool { + return existingFeed(withURL: url) != nil } - func has(_ webFeed: Feed) -> Bool { - return flattenedWebFeeds().contains(webFeed) + func has(_ feed: Feed) -> Bool { + return flattenedFeeds().contains(feed) } - func existingWebFeed(withWebFeedID webFeedID: String) -> Feed? { - for feed in flattenedWebFeeds() { - if feed.webFeedID == webFeedID { + func existingFeed(withFeedID feedID: String) -> Feed? { + for feed in flattenedFeeds() { + if feed.feedID == feedID { return feed } } return nil } - func existingWebFeed(withURL url: String) -> Feed? { - for feed in flattenedWebFeeds() { + func existingFeed(withURL url: String) -> Feed? { + for feed in flattenedFeeds() { if feed.url == url { return feed } @@ -119,8 +119,8 @@ public extension Container { return nil } - func existingWebFeed(withExternalID externalID: String) -> Feed? { - for feed in flattenedWebFeeds() { + func existingFeed(withExternalID externalID: String) -> Feed? { + for feed in flattenedFeeds() { if feed.externalID == externalID { return feed } diff --git a/Account/Sources/Account/DataExtensions.swift b/Account/Sources/Account/DataExtensions.swift index bcdebd100..a503ea62d 100644 --- a/Account/Sources/Account/DataExtensions.swift +++ b/Account/Sources/Account/DataExtensions.swift @@ -11,14 +11,14 @@ import Articles import RSParser public extension Notification.Name { - static let WebFeedSettingDidChange = Notification.Name(rawValue: "FeedSettingDidChangeNotification") + static let FeedSettingDidChange = Notification.Name(rawValue: "FeedSettingDidChangeNotification") } public extension Feed { - static let WebFeedSettingUserInfoKey = "feedSetting" + static let FeedSettingUserInfoKey = "feedSetting" - struct WebFeedSettingKey { + struct FeedSettingKey { public static let homePageURL = "homePageURL" public static let iconURL = "iconURL" public static let faviconURL = "faviconURL" @@ -40,9 +40,9 @@ extension Feed { authors = Author.authorsWithParsedAuthors(parsedFeed.authors) } - func postFeedSettingDidChangeNotification(_ codingKey: WebFeedMetadata.CodingKeys) { - let userInfo = [Feed.WebFeedSettingUserInfoKey: codingKey.stringValue] - NotificationCenter.default.post(name: .WebFeedSettingDidChange, object: self, userInfo: userInfo) + func postFeedSettingDidChangeNotification(_ codingKey: FeedMetadata.CodingKeys) { + let userInfo = [Feed.FeedSettingUserInfoKey: codingKey.stringValue] + NotificationCenter.default.post(name: .FeedSettingDidChange, object: self, userInfo: userInfo) } } @@ -56,8 +56,8 @@ public extension Article { return manager.existingAccount(with: accountID) } - var webFeed: Feed? { - return account?.existingWebFeed(withWebFeedID: webFeedID) + var feed: Feed? { + return account?.existingFeed(withFeedID: feedID) } } diff --git a/Account/Sources/Account/Feed.swift b/Account/Sources/Account/Feed.swift index df100a5e8..dbdc5f734 100644 --- a/Account/Sources/Account/Feed.swift +++ b/Account/Sources/Account/Feed.swift @@ -1,5 +1,5 @@ // -// WebFeed.swift +// Feed.swift // NetNewsWire // // Created by Brent Simmons on 7/1/17. @@ -22,18 +22,18 @@ public final class Feed: SidebarItem, Renamable, Hashable { assertionFailure("Expected feed.account, but got nil.") return nil } - return SidebarItemIdentifier.webFeed(accountID, webFeedID) + return SidebarItemIdentifier.feed(accountID, feedID) } public weak var account: Account? public let url: String - public var webFeedID: String { + public var feedID: String { get { - return metadata.webFeedID + return metadata.feedID } set { - metadata.webFeedID = newValue + metadata.feedID = newValue } } @@ -203,7 +203,7 @@ public final class Feed: SidebarItem, Renamable, Hashable { public func rename(to newName: String, completion: @escaping (Result) -> Void) { guard let account = account else { return } - account.renameWebFeed(self, to: newName, completion: completion) + account.renameFeed(self, to: newName, completion: completion) } // MARK: - UnreadCountProvider @@ -238,7 +238,7 @@ public final class Feed: SidebarItem, Renamable, Hashable { #endif } - var metadata: WebFeedMetadata + var metadata: FeedMetadata // MARK: - Private @@ -246,7 +246,7 @@ public final class Feed: SidebarItem, Renamable, Hashable { // MARK: - Init - init(account: Account, url: String, metadata: WebFeedMetadata) { + init(account: Account, url: String, metadata: FeedMetadata) { self.account = account self.accountID = account.accountID self.url = url @@ -264,13 +264,13 @@ public final class Feed: SidebarItem, Renamable, Hashable { // MARK: - Hashable public func hash(into hasher: inout Hasher) { - hasher.combine(webFeedID) + hasher.combine(feedID) } // MARK: - Equatable public class func ==(lhs: Feed, rhs: Feed) -> Bool { - return lhs.webFeedID == rhs.webFeedID && lhs.accountID == rhs.accountID + return lhs.feedID == rhs.feedID && lhs.accountID == rhs.accountID } } @@ -306,16 +306,16 @@ extension Feed: OPMLRepresentable { extension Set where Element == Feed { - func webFeedIDs() -> Set { - return Set(map { $0.webFeedID }) + func feedIDs() -> Set { + return Set(map { $0.feedID }) } func sorted() -> Array { - return sorted(by: { (webFeed1, webFeed2) -> Bool in - if webFeed1.nameForDisplay.localizedStandardCompare(webFeed2.nameForDisplay) == .orderedSame { - return webFeed1.url < webFeed2.url + return sorted(by: { (feed1, feed2) -> Bool in + if feed1.nameForDisplay.localizedStandardCompare(feed2.nameForDisplay) == .orderedSame { + return feed1.url < feed2.url } - return webFeed1.nameForDisplay.localizedStandardCompare(webFeed2.nameForDisplay) == .orderedAscending + return feed1.nameForDisplay.localizedStandardCompare(feed2.nameForDisplay) == .orderedAscending }) } diff --git a/Account/Sources/Account/WebFeedMetadata.swift b/Account/Sources/Account/FeedMetadata.swift similarity index 84% rename from Account/Sources/Account/WebFeedMetadata.swift rename to Account/Sources/Account/FeedMetadata.swift index aa381709f..ca834ee9a 100644 --- a/Account/Sources/Account/WebFeedMetadata.swift +++ b/Account/Sources/Account/FeedMetadata.swift @@ -1,5 +1,5 @@ // -// WebFeedMetadata.swift +// FeedMetadata.swift // NetNewsWire // // Created by Brent Simmons on 3/12/19. @@ -10,14 +10,14 @@ import Foundation import RSWeb import Articles -protocol WebFeedMetadataDelegate: AnyObject { - func valueDidChange(_ feedMetadata: WebFeedMetadata, key: WebFeedMetadata.CodingKeys) +protocol FeedMetadataDelegate: AnyObject { + func valueDidChange(_ feedMetadata: FeedMetadata, key: FeedMetadata.CodingKeys) } -final class WebFeedMetadata: Codable { +final class FeedMetadata: Codable { enum CodingKeys: String, CodingKey { - case webFeedID = "feedID" + case feedID = "feedID" case homePageURL case iconURL case faviconURL @@ -32,10 +32,10 @@ final class WebFeedMetadata: Codable { case folderRelationship } - var webFeedID: String { + var feedID: String { didSet { - if webFeedID != oldValue { - valueDidChange(.webFeedID) + if feedID != oldValue { + valueDidChange(.feedID) } } } @@ -137,10 +137,10 @@ final class WebFeedMetadata: Codable { } } - weak var delegate: WebFeedMetadataDelegate? + weak var delegate: FeedMetadataDelegate? - init(webFeedID: String) { - self.webFeedID = webFeedID + init(feedID: String) { + self.feedID = feedID } func valueDidChange(_ key: CodingKeys) { diff --git a/Account/Sources/Account/WebFeedMetadataFile.swift b/Account/Sources/Account/FeedMetadataFile.swift similarity index 67% rename from Account/Sources/Account/WebFeedMetadataFile.swift rename to Account/Sources/Account/FeedMetadataFile.swift index be04530d7..33a7a84b8 100644 --- a/Account/Sources/Account/WebFeedMetadataFile.swift +++ b/Account/Sources/Account/FeedMetadataFile.swift @@ -1,5 +1,5 @@ // -// WebFeedMetadataFile.swift +// FeedMetadataFile.swift // Account // // Created by Maurice Parker on 9/13/19. @@ -10,9 +10,9 @@ import Foundation import os.log import RSCore -final class WebFeedMetadataFile { +final class FeedMetadataFile { - private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "webFeedMetadataFile") + private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "feedMetadataFile") private let fileURL: URL private let account: Account @@ -36,9 +36,9 @@ final class WebFeedMetadataFile { func load() { if let fileData = try? Data(contentsOf: fileURL) { let decoder = PropertyListDecoder() - account.webFeedMetadata = (try? decoder.decode(Account.WebFeedMetadataDictionary.self, from: fileData)) ?? Account.WebFeedMetadataDictionary() + account.feedMetadata = (try? decoder.decode(Account.FeedMetadataDictionary.self, from: fileData)) ?? Account.FeedMetadataDictionary() } - account.webFeedMetadata.values.forEach { $0.delegate = account } + account.feedMetadata.values.forEach { $0.delegate = account } } func save() { @@ -59,7 +59,7 @@ final class WebFeedMetadataFile { } -private extension WebFeedMetadataFile { +private extension FeedMetadataFile { func queueSaveToDiskIfNeeded() { saveQueue.add(self, #selector(saveToDiskIfNeeded)) @@ -72,10 +72,10 @@ private extension WebFeedMetadataFile { } } - private func metadataForOnlySubscribedToFeeds() -> Account.WebFeedMetadataDictionary { - let webFeedIDs = account.idToWebFeedDictionary.keys - return account.webFeedMetadata.filter { (feedID: String, metadata: WebFeedMetadata) -> Bool in - return webFeedIDs.contains(metadata.webFeedID) + private func metadataForOnlySubscribedToFeeds() -> Account.FeedMetadataDictionary { + let feedIDs = account.idToFeedDictionary.keys + return account.feedMetadata.filter { (feedID: String, metadata: FeedMetadata) -> Bool in + return feedIDs.contains(metadata.feedID) } } diff --git a/Account/Sources/Account/Feedbin/FeedbinAPICaller.swift b/Account/Sources/Account/Feedbin/FeedbinAPICaller.swift index 8ff2028ae..e8e1d8ec1 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAPICaller.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAPICaller.swift @@ -357,7 +357,7 @@ final class FeedbinAPICaller: NSObject { } - func createTagging(webFeedID: Int, name: String, completion: @escaping (Result) -> Void) { + func createTagging(feedID: Int, name: String, completion: @escaping (Result) -> Void) { let callURL = feedbinBaseURL.appendingPathComponent("taggings.json") var request = URLRequest(url: callURL, credentials: credentials) @@ -365,7 +365,7 @@ final class FeedbinAPICaller: NSObject { let payload: Data do { - payload = try JSONEncoder().encode(FeedbinCreateTagging(feedID: webFeedID, name: name)) + payload = try JSONEncoder().encode(FeedbinCreateTagging(feedID: feedID, name: name)) } catch { completion(.failure(error)) return diff --git a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift index da4dca147..4425d4276 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift @@ -300,7 +300,7 @@ final class FeedbinAccountDelegate: AccountDelegate { func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result) -> Void) { - guard folder.hasAtLeastOneWebFeed() else { + guard folder.hasAtLeastOneFeed() else { folder.name = name return } @@ -328,7 +328,7 @@ final class FeedbinAccountDelegate: AccountDelegate { func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result) -> Void) { // Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system - guard folder.hasAtLeastOneWebFeed() else { + guard folder.hasAtLeastOneFeed() else { account.removeFolder(folder) completion(.success(())) return @@ -336,7 +336,7 @@ final class FeedbinAccountDelegate: AccountDelegate { let group = DispatchGroup() - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { if feed.folderRelationship?.count ?? 0 > 1 { @@ -368,7 +368,7 @@ final class FeedbinAccountDelegate: AccountDelegate { switch result { case .success: DispatchQueue.main.async { - account.clearWebFeedMetadata(feed) + account.clearFeedMetadata(feed) } case .failure(let error): os_log(.error, log: self.log, "Remove feed error: %@.", error.localizedDescription) @@ -388,7 +388,7 @@ final class FeedbinAccountDelegate: AccountDelegate { } - func createWebFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { refreshProgress.addToNumberOfTasksAndRemaining(1) caller.createSubscription(url: url) { result in @@ -420,7 +420,7 @@ final class FeedbinAccountDelegate: AccountDelegate { } - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { // This error should never happen guard let subscriptionID = feed.externalID else { @@ -447,7 +447,7 @@ final class FeedbinAccountDelegate: AccountDelegate { } - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { if feed.folderRelationship?.count ?? 0 > 1 { deleteTagging(for: account, with: feed, from: container, completion: completion) } else { @@ -455,14 +455,14 @@ final class FeedbinAccountDelegate: AccountDelegate { } } - func moveWebFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { + func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { if from is Account { - addWebFeed(for: account, with: feed, to: to, completion: completion) + addFeed(for: account, with: feed, to: to, completion: completion) } else { deleteTagging(for: account, with: feed, from: from) { result in switch result { case .success: - self.addWebFeed(for: account, with: feed, to: to, completion: completion) + self.addFeed(for: account, with: feed, to: to, completion: completion) case .failure(let error): completion(.failure(error)) } @@ -470,18 +470,18 @@ final class FeedbinAccountDelegate: AccountDelegate { } } - func addWebFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { + func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { - if let folder = container as? Folder, let webFeedID = Int(feed.webFeedID) { + if let folder = container as? Folder, let feedID = Int(feed.feedID) { refreshProgress.addToNumberOfTasksAndRemaining(1) - caller.createTagging(webFeedID: webFeedID, name: folder.name ?? "") { result in + caller.createTagging(feedID: feedID, name: folder.name ?? "") { result in self.refreshProgress.completeTask() switch result { case .success(let taggingID): DispatchQueue.main.async { self.saveFolderRelationship(for: feed, withFolderName: folder.name ?? "", id: String(taggingID)) - account.removeWebFeed(feed) - folder.addWebFeed(feed) + account.removeFeed(feed) + folder.addFeed(feed) completion(.success(())) } case .failure(let error): @@ -502,10 +502,10 @@ final class FeedbinAccountDelegate: AccountDelegate { } - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - if let existingFeed = account.existingWebFeed(withURL: feed.url) { - account.addWebFeed(existingFeed, to: container) { result in + if let existingFeed = account.existingFeed(withURL: feed.url) { + account.addFeed(existingFeed, to: container) { result in switch result { case .success: completion(.success(())) @@ -514,7 +514,7 @@ final class FeedbinAccountDelegate: AccountDelegate { } } } else { - createWebFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in + createFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in switch result { case .success: completion(.success(())) @@ -530,12 +530,12 @@ final class FeedbinAccountDelegate: AccountDelegate { let group = DispatchGroup() - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { - folder.topLevelWebFeeds.remove(feed) + folder.topLevelFeeds.remove(feed) group.enter() - restoreWebFeed(for: account, feed: feed, container: folder) { result in + restoreFeed(for: account, feed: feed, container: folder) { result in group.leave() switch result { case .success: @@ -780,8 +780,8 @@ private extension FeedbinAccountDelegate { if let folders = account.folders { folders.forEach { folder in if !tagNames.contains(folder.name ?? "") { - for feed in folder.topLevelWebFeeds { - account.addWebFeed(feed) + for feed in folder.topLevelFeeds { + account.addFeed(feed) clearFolderRelationship(for: feed, withFolderName: folder.name ?? "") } account.removeFolder(folder) @@ -818,17 +818,17 @@ private extension FeedbinAccountDelegate { // Remove any feeds that are no longer in the subscriptions if let folders = account.folders { for folder in folders { - for feed in folder.topLevelWebFeeds { - if !subFeedIds.contains(feed.webFeedID) { - folder.removeWebFeed(feed) + for feed in folder.topLevelFeeds { + if !subFeedIds.contains(feed.feedID) { + folder.removeFeed(feed) } } } } - for feed in account.topLevelWebFeeds { - if !subFeedIds.contains(feed.webFeedID) { - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + if !subFeedIds.contains(feed.feedID) { + account.removeFeed(feed) } } @@ -838,7 +838,7 @@ private extension FeedbinAccountDelegate { let subFeedId = String(subscription.feedID) - if let feed = account.existingWebFeed(withWebFeedID: subFeedId) { + if let feed = account.existingFeed(withFeedID: subFeedId) { feed.name = subscription.name // If the name has been changed on the server remove the locally edited name feed.editedName = nil @@ -854,9 +854,9 @@ private extension FeedbinAccountDelegate { // Actually add subscriptions all in one go, so we don’t trigger various rebuilding things that Account does. subscriptionsToAdd.forEach { subscription in - let feed = account.createWebFeed(with: subscription.name, url: subscription.url, webFeedID: String(subscription.feedID), homePageURL: subscription.homePageURL) + let feed = account.createFeed(with: subscription.name, url: subscription.url, feedID: String(subscription.feedID), homePageURL: subscription.homePageURL) feed.externalID = String(subscription.subscriptionID) - account.addWebFeed(feed) + account.addFeed(feed) } } @@ -888,25 +888,25 @@ private extension FeedbinAccountDelegate { let taggingFeedIDs = groupedTaggings.map { String($0.feedID) } // Move any feeds not in the folder to the account - for feed in folder.topLevelWebFeeds { - if !taggingFeedIDs.contains(feed.webFeedID) { - folder.removeWebFeed(feed) + for feed in folder.topLevelFeeds { + if !taggingFeedIDs.contains(feed.feedID) { + folder.removeFeed(feed) clearFolderRelationship(for: feed, withFolderName: folder.name ?? "") - account.addWebFeed(feed) + account.addFeed(feed) } } // Add any feeds not in the folder - let folderFeedIds = folder.topLevelWebFeeds.map { $0.webFeedID } + let folderFeedIds = folder.topLevelFeeds.map { $0.feedID } for tagging in groupedTaggings { let taggingFeedID = String(tagging.feedID) if !folderFeedIds.contains(taggingFeedID) { - guard let feed = account.existingWebFeed(withWebFeedID: taggingFeedID) else { + guard let feed = account.existingFeed(withFeedID: taggingFeedID) else { continue } saveFolderRelationship(for: feed, withFolderName: folderName, id: String(tagging.taggingID)) - folder.addWebFeed(feed) + folder.addFeed(feed) } } @@ -915,9 +915,9 @@ private extension FeedbinAccountDelegate { let taggedFeedIDs = Set(taggings.map { String($0.feedID) }) // Remove all feeds from the account container that have a tag - for feed in account.topLevelWebFeeds { - if taggedFeedIDs.contains(feed.webFeedID) { - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + if taggedFeedIDs.contains(feed.feedID) { + account.removeFeed(feed) } } } @@ -980,7 +980,7 @@ private extension FeedbinAccountDelegate { } func renameFolderRelationship(for account: Account, fromName: String, toName: String) { - for feed in account.flattenedWebFeeds() { + for feed in account.flattenedFeeds() { if var folderRelationship = feed.folderRelationship { let relationship = folderRelationship[fromName] folderRelationship[fromName] = nil @@ -1017,7 +1017,7 @@ private extension FeedbinAccountDelegate { } if let bestSpecifier = FeedSpecifier.bestFeed(in: Set(feedSpecifiers)) { - createWebFeed(for: account, url: bestSpecifier.urlString, name: name, container: container, validateFeed: true, completion: completion) + createFeed(for: account, url: bestSpecifier.urlString, name: name, container: container, validateFeed: true, completion: completion) } else { DispatchQueue.main.async { completion(.failure(FeedbinAccountDelegateError.invalidParameter)) @@ -1029,16 +1029,16 @@ private extension FeedbinAccountDelegate { DispatchQueue.main.async { - let feed = account.createWebFeed(with: sub.name, url: sub.url, webFeedID: String(sub.feedID), homePageURL: sub.homePageURL) + let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL) feed.externalID = String(sub.subscriptionID) feed.iconURL = sub.jsonFeed?.icon feed.faviconURL = sub.jsonFeed?.favicon - account.addWebFeed(feed, to: container) { result in + account.addFeed(feed, to: container) { result in switch result { case .success: if let name = name { - account.renameWebFeed(feed, to: name) { result in + account.renameFeed(feed, to: name) { result in switch result { case .success: self.initialFeedDownload(account: account, feed: feed, completion: completion) @@ -1064,7 +1064,7 @@ private extension FeedbinAccountDelegate { refreshProgress.addToNumberOfTasksAndRemaining(4) // Download the initial articles - self.caller.retrieveEntries(feedID: feed.webFeedID) { result in + self.caller.retrieveEntries(feedID: feed.feedID) { result in self.refreshProgress.completeTask() switch result { @@ -1248,8 +1248,8 @@ private extension FeedbinAccountDelegate { func processEntries(account: Account, entries: [FeedbinEntry]?, completion: @escaping DatabaseCompletionBlock) { let parsedItems = mapEntriesToParsedItems(entries: entries) - let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } - account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true, completion: completion) + let feedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } + account.update(feedIDsAndItems: feedIDsAndItems, defaultRead: true, completion: completion) } func mapEntriesToParsedItems(entries: [FeedbinEntry]?) -> Set { @@ -1381,7 +1381,7 @@ private extension FeedbinAccountDelegate { case .success: DispatchQueue.main.async { self.clearFolderRelationship(for: feed, withFolderName: folder.name ?? "") - folder.removeWebFeed(feed) + folder.removeFeed(feed) account.addFeedIfNotInAnyFolder(feed) completion(.success(())) } @@ -1394,7 +1394,7 @@ private extension FeedbinAccountDelegate { } } else { if let account = container as? Account { - account.removeWebFeed(feed) + account.removeFeed(feed) } completion(.success(())) } @@ -1415,11 +1415,11 @@ private extension FeedbinAccountDelegate { switch result { case .success: DispatchQueue.main.async { - account.clearWebFeedMetadata(feed) - account.removeWebFeed(feed) + account.clearFeedMetadata(feed) + account.removeFeed(feed) if let folders = account.folders { for folder in folders { - folder.removeWebFeed(feed) + folder.removeFeed(feed) } } completion(.success(())) diff --git a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift index abd8585cd..d7cc77290 100644 --- a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift @@ -314,7 +314,7 @@ final class FeedlyAccountDelegate: AccountDelegate { } } - func createWebFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { do { guard let credentials = credentials else { @@ -347,14 +347,14 @@ final class FeedlyAccountDelegate: AccountDelegate { } } - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { let folderCollectionIds = account.folders?.filter { $0.has(feed) }.compactMap { $0.externalID } guard let collectionIds = folderCollectionIds, let collectionId = collectionIds.first else { completion(.failure(FeedlyAccountDelegateError.unableToRenameFeed(feed.nameForDisplay, name))) return } - let feedId = FeedlyFeedResourceId(id: feed.webFeedID) + let feedId = FeedlyFeedResourceId(id: feed.feedID) let editedNameBefore = feed.editedName // Adding an existing feed updates it. @@ -374,14 +374,14 @@ final class FeedlyAccountDelegate: AccountDelegate { feed.editedName = name } - func addWebFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { + func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { do { guard let credentials = credentials else { throw FeedlyAccountDelegateError.notLoggedIn } - let resource = FeedlyFeedResourceId(id: feed.webFeedID) + let resource = FeedlyFeedResourceId(id: feed.feedID) let addExistingFeed = try FeedlyAddExistingFeedOperation(account: account, credentials: credentials, resource: resource, @@ -405,62 +405,62 @@ final class FeedlyAccountDelegate: AccountDelegate { } } - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { guard let folder = container as? Folder, let collectionId = folder.externalID else { return DispatchQueue.main.async { completion(.failure(FeedlyAccountDelegateError.unableToRemoveFeed(feed))) } } - caller.removeFeed(feed.webFeedID, fromCollectionWith: collectionId) { result in + caller.removeFeed(feed.feedID, fromCollectionWith: collectionId) { result in switch result { case .success: completion(.success(())) case .failure(let error): - folder.addWebFeed(feed) + folder.addFeed(feed) completion(.failure(error)) } } - folder.removeWebFeed(feed) + folder.removeFeed(feed) } - func moveWebFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { + func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { guard let from = from as? Folder, let to = to as? Folder else { return DispatchQueue.main.async { completion(.failure(FeedlyAccountDelegateError.addFeedChooseFolder)) } } - addWebFeed(for: account, with: feed, to: to) { [weak self] addResult in + addFeed(for: account, with: feed, to: to) { [weak self] addResult in switch addResult { // now that we have added the feed, remove it from the other collection case .success: - self?.removeWebFeed(for: account, with: feed, from: from) { removeResult in + self?.removeFeed(for: account, with: feed, from: from) { removeResult in switch removeResult { case .success: completion(.success(())) case .failure: - from.addWebFeed(feed) + from.addFeed(feed) completion(.failure(FeedlyAccountDelegateError.unableToMoveFeedBetweenFolders(feed, from, to))) } } case .failure(let error): - from.addWebFeed(feed) - to.removeWebFeed(feed) + from.addFeed(feed) + to.removeFeed(feed) completion(.failure(error)) } } // optimistically move the feed, undoing as appropriate to the failure - from.removeWebFeed(feed) - to.addWebFeed(feed) + from.removeFeed(feed) + to.addFeed(feed) } - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - if let existingFeed = account.existingWebFeed(withURL: feed.url) { - account.addWebFeed(existingFeed, to: container) { result in + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { + if let existingFeed = account.existingFeed(withURL: feed.url) { + account.addFeed(existingFeed, to: container) { result in switch result { case .success: completion(.success(())) @@ -469,7 +469,7 @@ final class FeedlyAccountDelegate: AccountDelegate { } } } else { - createWebFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in + createFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in switch result { case .success: completion(.success(())) @@ -483,12 +483,12 @@ final class FeedlyAccountDelegate: AccountDelegate { func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { let group = DispatchGroup() - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { - folder.topLevelWebFeeds.remove(feed) + folder.topLevelFeeds.remove(feed) group.enter() - restoreWebFeed(for: account, feed: feed, container: folder) { result in + restoreFeed(for: account, feed: feed, container: folder) { result in group.leave() switch result { case .success: diff --git a/Account/Sources/Account/Feedly/Models/FeedlyEntryParser.swift b/Account/Sources/Account/Feedly/Models/FeedlyEntryParser.swift index 2da2edc84..3e1149e25 100644 --- a/Account/Sources/Account/Feedly/Models/FeedlyEntryParser.swift +++ b/Account/Sources/Account/Feedly/Models/FeedlyEntryParser.swift @@ -19,7 +19,7 @@ struct FeedlyEntryParser { return entry.id } - /// When ingesting articles, the feedURL must match a feed's `webFeedID` for the article to be reachable between it and its matching feed. It reminds me of a foreign key. + /// When ingesting articles, the feedURL must match a feed's `feedID` for the article to be reachable between it and its matching feed. It reminds me of a foreign key. var feedUrl: String? { guard let id = entry.origin?.streamId else { // At this point, check Feedly's API isn't glitching or the response has not changed structure. diff --git a/Account/Sources/Account/Feedly/Models/FeedlyFeedParser.swift b/Account/Sources/Account/Feedly/Models/FeedlyFeedParser.swift index e2f288dce..a9faf3f25 100644 --- a/Account/Sources/Account/Feedly/Models/FeedlyFeedParser.swift +++ b/Account/Sources/Account/Feedly/Models/FeedlyFeedParser.swift @@ -17,7 +17,7 @@ struct FeedlyFeedParser { return rightToLeftTextSantizer.sanitize(feed.title) ?? "" } - var webFeedID: String { + var feedID: String { return feed.id } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift index 44156cc3f..6a97c1fc8 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyAddNewFeedOperation.swift @@ -137,7 +137,7 @@ class FeedlyAddNewFeedOperation: FeedlyOperation, FeedlyOperationDelegate, Feedl guard let handler = addCompletionHandler else { return } - if let feedResource = feedResourceId, let feed = folder.existingWebFeed(withWebFeedID: feedResource.id) { + if let feedResource = feedResourceId, let feed = folder.existingFeed(withFeedID: feedResource.id) { handler(.success(feed)) } else { diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift index 965a8f9b0..bc13136fc 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyCreateFeedsForCollectionFoldersOperation.swift @@ -31,13 +31,13 @@ final class FeedlyCreateFeedsForCollectionFoldersOperation: FeedlyOperation { let feedsBefore = Set(pairs .map { $0.1 } - .flatMap { $0.topLevelWebFeeds }) + .flatMap { $0.topLevelFeeds }) // Remove feeds in a folder which are not in the corresponding collection. for (collectionFeeds, folder) in pairs { - let feedsInFolder = folder.topLevelWebFeeds + let feedsInFolder = folder.topLevelFeeds let feedsInCollection = Set(collectionFeeds.map { $0.id }) - let feedsToRemove = feedsInFolder.filter { !feedsInCollection.contains($0.webFeedID) } + let feedsToRemove = feedsInFolder.filter { !feedsInCollection.contains($0.feedID) } if !feedsToRemove.isEmpty { folder.removeFeeds(feedsToRemove) // os_log(.debug, log: log, "\"%@\" - removed: %@", collection.label, feedsToRemove.map { $0.feedID }, feedsInCollection) @@ -58,7 +58,7 @@ final class FeedlyCreateFeedsForCollectionFoldersOperation: FeedlyOperation { .compactMap { (collectionFeed, folder) -> (Feed, Folder) in // find an existing feed previously added to the account - if let feed = account.existingWebFeed(withWebFeedID: collectionFeed.id) { + if let feed = account.existingFeed(withFeedID: collectionFeed.id) { // If the feed was renamed on Feedly, ensure we ingest the new name. if feed.nameForDisplay != collectionFeed.title { @@ -76,16 +76,16 @@ final class FeedlyCreateFeedsForCollectionFoldersOperation: FeedlyOperation { return (feed, folder) } else { // find an existing feed we created below in an earlier value - for feed in feedsAdded where feed.webFeedID == collectionFeed.id { + for feed in feedsAdded where feed.feedID == collectionFeed.id { return (feed, folder) } } // no existing feed, create a new one let parser = FeedlyFeedParser(feed: collectionFeed) - let feed = account.createWebFeed(with: parser.title, + let feed = account.createFeed(with: parser.title, url: parser.url, - webFeedID: parser.webFeedID, + feedID: parser.feedID, homePageURL: parser.homePageURL) // So the same feed isn't created more than once. @@ -97,7 +97,7 @@ final class FeedlyCreateFeedsForCollectionFoldersOperation: FeedlyOperation { os_log(.debug, log: log, "Processing %i feeds.", feedsAndFolders.count) feedsAndFolders.forEach { (feed, folder) in if !folder.has(feed) { - folder.addWebFeed(feed) + folder.addFeed(feed) } } diff --git a/Account/Sources/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift b/Account/Sources/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift index b15d17cf9..ea8dcace4 100644 --- a/Account/Sources/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift +++ b/Account/Sources/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift @@ -24,15 +24,15 @@ final class FeedlyUpdateAccountFeedsWithItemsOperation: FeedlyOperation { } override func run() { - let webFeedIDsAndItems = organisedItemsProvider.parsedItemsKeyedByFeedId + let feedIDsAndItems = organisedItemsProvider.parsedItemsKeyedByFeedId - account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true) { databaseError in + account.update(feedIDsAndItems: feedIDsAndItems, defaultRead: true) { databaseError in if let error = databaseError { self.didFinish(with: error) return } - os_log(.debug, log: self.log, "Updated %i feeds for \"%@\"", webFeedIDsAndItems.count, self.organisedItemsProvider.parsedItemsByFeedProviderName) + os_log(.debug, log: self.log, "Updated %i feeds for \"%@\"", feedIDsAndItems.count, self.organisedItemsProvider.parsedItemsByFeedProviderName) self.didFinish() } } diff --git a/Account/Sources/Account/Folder.swift b/Account/Sources/Account/Folder.swift index 3a4c6aa17..f088e3a26 100644 --- a/Account/Sources/Account/Folder.swift +++ b/Account/Sources/Account/Folder.swift @@ -33,7 +33,7 @@ public final class Folder: SidebarItem, Renamable, Container, Hashable { } public weak var account: Account? - public var topLevelWebFeeds: Set = Set() + public var topLevelFeeds: Set = Set() public var folders: Set? = nil // subfolders are not supported, so this is always nil public var name: String? { @@ -100,9 +100,9 @@ public final class Folder: SidebarItem, Renamable, Container, Hashable { // MARK: Container - public func flattenedWebFeeds() -> Set { + public func flattenedFeeds() -> Set { // Since sub-folders are not supported, it’s always the top-level feeds. - return topLevelWebFeeds + return topLevelFeeds } public func objectIsChild(_ object: AnyObject) -> Bool { @@ -110,11 +110,11 @@ public final class Folder: SidebarItem, Renamable, Container, Hashable { guard let feed = object as? Feed else { return false } - return topLevelWebFeeds.contains(feed) + return topLevelFeeds.contains(feed) } - public func addWebFeed(_ feed: Feed) { - topLevelWebFeeds.insert(feed) + public func addFeed(_ feed: Feed) { + topLevelFeeds.insert(feed) postChildrenDidChangeNotification() } @@ -122,12 +122,12 @@ public final class Folder: SidebarItem, Renamable, Container, Hashable { guard !feeds.isEmpty else { return } - topLevelWebFeeds.formUnion(feeds) + topLevelFeeds.formUnion(feeds) postChildrenDidChangeNotification() } - public func removeWebFeed(_ feed: Feed) { - topLevelWebFeeds.remove(feed) + public func removeFeed(_ feed: Feed) { + topLevelFeeds.remove(feed) postChildrenDidChangeNotification() } @@ -135,7 +135,7 @@ public final class Folder: SidebarItem, Renamable, Container, Hashable { guard !feeds.isEmpty else { return } - topLevelWebFeeds.subtract(feeds) + topLevelFeeds.subtract(feeds) postChildrenDidChangeNotification() } @@ -158,14 +158,14 @@ private extension Folder { func updateUnreadCount() { var updatedUnreadCount = 0 - for feed in topLevelWebFeeds { + for feed in topLevelFeeds { updatedUnreadCount += feed.unreadCount } unreadCount = updatedUnreadCount } func childrenContain(_ feed: Feed) -> Bool { - return topLevelWebFeeds.contains(feed) + return topLevelFeeds.contains(feed) } } @@ -189,7 +189,7 @@ extension Folder: OPMLRepresentable { var hasAtLeastOneChild = false - for feed in topLevelWebFeeds.sorted() { + for feed in topLevelFeeds.sorted() { s += feed.OPMLString(indentLevel: indentLevel + 1, allowCustomAttributes: allowCustomAttributes) hasAtLeastOneChild = true } diff --git a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift index 12caea46a..ddd60afb8 100644 --- a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift @@ -50,13 +50,13 @@ final class LocalAccountDelegate: AccountDelegate { return } - let webFeeds = account.flattenedWebFeeds() - refreshProgress.addToNumberOfTasksAndRemaining(webFeeds.count) + let feeds = account.flattenedFeeds() + refreshProgress.addToNumberOfTasksAndRemaining(feeds.count) let group = DispatchGroup() group.enter() - refresher?.refreshFeeds(webFeeds) { + refresher?.refreshFeeds(feeds) { group.leave() } @@ -122,38 +122,38 @@ final class LocalAccountDelegate: AccountDelegate { } - func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + func createFeed(for account: Account, url urlString: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { guard let url = URL(string: urlString) else { completion(.failure(LocalAccountDelegateError.invalidParameter)) return } - createRSSWebFeed(for: account, url: url, editedName: name, container: container, completion: completion) + createRSSFeed(for: account, url: url, editedName: name, container: container, completion: completion) } - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { feed.editedName = name completion(.success(())) } - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { - container.removeWebFeed(feed) + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + container.removeFeed(feed) completion(.success(())) } - func moveWebFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { - from.removeWebFeed(feed) - to.addWebFeed(feed) + func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { + from.removeFeed(feed) + to.addFeed(feed) completion(.success(())) } - func addWebFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { - container.addWebFeed(feed) + func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { + container.addFeed(feed) completion(.success(())) } - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - container.addWebFeed(feed) + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { + container.addFeed(feed) completion(.success(())) } @@ -231,7 +231,7 @@ extension LocalAccountDelegate: LocalAccountRefresherDelegate { private extension LocalAccountDelegate { - func createRSSWebFeed(for account: Account, url: URL, editedName: String?, container: Container, completion: @escaping (Result) -> Void) { + func createRSSFeed(for account: Account, url: URL, editedName: String?, container: Container, completion: @escaping (Result) -> Void) { // We need to use a batch update here because we need to assign add the feed to the // container before the name has been downloaded. This will put it in the sidebar @@ -250,7 +250,7 @@ private extension LocalAccountDelegate { return } - if account.hasWebFeed(withURL: bestFeedSpecifier.urlString) { + if account.hasFeed(withURL: bestFeedSpecifier.urlString) { self.refreshProgress.completeTask() BatchUpdate.shared.end() completion(.failure(AccountError.createErrorAlreadySubscribed)) @@ -261,9 +261,9 @@ private extension LocalAccountDelegate { self.refreshProgress.completeTask() if let parsedFeed = parsedFeed { - let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil) + let feed = account.createFeed(with: nil, url: url.absoluteString, feedID: url.absoluteString, homePageURL: nil) feed.editedName = editedName - container.addWebFeed(feed) + container.addFeed(feed) account.update(feed, with: parsedFeed, {_ in BatchUpdate.shared.end() diff --git a/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift b/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift index f4c22bbed..6f58ffd11 100644 --- a/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift +++ b/Account/Sources/Account/NewsBlur/Internals/NewsBlurAccountDelegate+Internal.swift @@ -47,8 +47,8 @@ extension NewsBlurAccountDelegate { if let folders = account.folders { folders.forEach { folder in if !folderNames.contains(folder.name ?? "") { - for feed in folder.topLevelWebFeeds { - account.addWebFeed(feed) + for feed in folder.topLevelFeeds { + account.addFeed(feed) clearFolderRelationship(for: feed, withFolderName: folder.name ?? "") } account.removeFolder(folder) @@ -84,17 +84,17 @@ extension NewsBlurAccountDelegate { // Remove any feeds that are no longer in the subscriptions if let folders = account.folders { for folder in folders { - for feed in folder.topLevelWebFeeds { - if !newsBlurFeedIds.contains(feed.webFeedID) { - folder.removeWebFeed(feed) + for feed in folder.topLevelFeeds { + if !newsBlurFeedIds.contains(feed.feedID) { + folder.removeFeed(feed) } } } } - for feed in account.topLevelWebFeeds { - if !newsBlurFeedIds.contains(feed.webFeedID) { - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + if !newsBlurFeedIds.contains(feed.feedID) { + account.removeFeed(feed) } } @@ -103,13 +103,13 @@ extension NewsBlurAccountDelegate { feeds.forEach { feed in let subFeedId = String(feed.feedID) - if let webFeed = account.existingWebFeed(withWebFeedID: subFeedId) { - webFeed.name = feed.name + if let feed = account.existingFeed(withFeedID: subFeedId) { + feed.name = feed.name // If the name has been changed on the server remove the locally edited name - webFeed.editedName = nil - webFeed.homePageURL = feed.homePageURL - webFeed.externalID = String(feed.feedID) - webFeed.faviconURL = feed.faviconURL + feed.editedName = nil + feed.homePageURL = feed.homePageURL + feed.externalID = String(feed.feedID) + feed.faviconURL = feed.faviconURL } else { feedsToAdd.insert(feed) @@ -118,9 +118,9 @@ extension NewsBlurAccountDelegate { // Actually add feeds all in one go, so we don’t trigger various rebuilding things that Account does. feedsToAdd.forEach { feed in - let webFeed = account.createWebFeed(with: feed.name, url: feed.feedURL, webFeedID: String(feed.feedID), homePageURL: feed.homePageURL) - webFeed.externalID = String(feed.feedID) - account.addWebFeed(webFeed) + let feed = account.createFeed(with: feed.name, url: feed.feedURL, feedID: String(feed.feedID), homePageURL: feed.homePageURL) + feed.externalID = String(feed.feedID) + account.addFeed(feed) } } @@ -155,25 +155,25 @@ extension NewsBlurAccountDelegate { guard let folder = folderDict[folderName] else { return } // Move any feeds not in the folder to the account - for feed in folder.topLevelWebFeeds { - if !newsBlurFolderFeedIDs.contains(feed.webFeedID) { - folder.removeWebFeed(feed) + for feed in folder.topLevelFeeds { + if !newsBlurFolderFeedIDs.contains(feed.feedID) { + folder.removeFeed(feed) clearFolderRelationship(for: feed, withFolderName: folder.name ?? "") - account.addWebFeed(feed) + account.addFeed(feed) } } // Add any feeds not in the folder - let folderFeedIds = folder.topLevelWebFeeds.map { $0.webFeedID } + let folderFeedIds = folder.topLevelFeeds.map { $0.feedID } for relationship in folderRelationships { let folderFeedID = String(relationship.feedID) if !folderFeedIds.contains(folderFeedID) { - guard let feed = account.existingWebFeed(withWebFeedID: folderFeedID) else { + guard let feed = account.existingFeed(withFeedID: folderFeedID) else { continue } saveFolderRelationship(for: feed, withFolderName: folderName, id: relationship.folderName) - folder.addWebFeed(feed) + folder.addFeed(feed) } } } @@ -182,14 +182,14 @@ extension NewsBlurAccountDelegate { // in folders and we need to remove them all from the account level. if let folderRelationships = newsBlurFolderDict[" "] { let newsBlurFolderFeedIDs = folderRelationships.map { String($0.feedID) } - for feed in account.topLevelWebFeeds { - if !newsBlurFolderFeedIDs.contains(feed.webFeedID) { - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + if !newsBlurFolderFeedIDs.contains(feed.feedID) { + account.removeFeed(feed) } } } else { - for feed in account.topLevelWebFeeds { - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + account.removeFeed(feed) } } @@ -419,24 +419,24 @@ extension NewsBlurAccountDelegate { } DispatchQueue.main.async { - let webFeed = account.createWebFeed(with: feed.name, url: feed.feedURL, webFeedID: String(feed.feedID), homePageURL: feed.homePageURL) - webFeed.externalID = String(feed.feedID) - webFeed.faviconURL = feed.faviconURL + let feed = account.createFeed(with: feed.name, url: feed.feedURL, feedID: String(feed.feedID), homePageURL: feed.homePageURL) + feed.externalID = String(feed.feedID) + feed.faviconURL = feed.faviconURL - account.addWebFeed(webFeed, to: container) { result in + account.addFeed(feed, to: container) { result in switch result { case .success: if let name = name { - account.renameWebFeed(webFeed, to: name) { result in + account.renameFeed(feed, to: name) { result in switch result { case .success: - self.initialFeedDownload(account: account, feed: webFeed, completion: completion) + self.initialFeedDownload(account: account, feed: feed, completion: completion) case .failure(let error): completion(.failure(error)) } } } else { - self.initialFeedDownload(account: account, feed: webFeed, completion: completion) + self.initialFeedDownload(account: account, feed: feed, completion: completion) } case .failure(let error): completion(.failure(error)) @@ -448,7 +448,7 @@ extension NewsBlurAccountDelegate { func downloadFeed(account: Account, feed: Feed, page: Int, completion: @escaping (Result) -> Void) { refreshProgress.addToNumberOfTasksAndRemaining(1) - caller.retrieveStories(feedID: feed.webFeedID, page: page) { result in + caller.retrieveStories(feedID: feed.feedID, page: page) { result in switch result { case .success((let stories, _)): // No more stories @@ -529,20 +529,20 @@ extension NewsBlurAccountDelegate { switch result { case .success: DispatchQueue.main.async { - let feedID = feed.webFeedID + let feedID = feed.feedID if folderName == nil { - account.removeWebFeed(feed) + account.removeFeed(feed) } if let folders = account.folders { for folder in folders where folderName != nil && folder.name == folderName { - folder.removeWebFeed(feed) + folder.removeFeed(feed) } } - if account.existingWebFeed(withWebFeedID: feedID) != nil { - account.clearWebFeedMetadata(feed) + if account.existingFeed(withFeedID: feedID) != nil { + account.clearFeedMetadata(feed) } completion(.success(())) diff --git a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift index bb5faf7cf..efd498d84 100644 --- a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -331,17 +331,17 @@ final class NewsBlurAccountDelegate: AccountDelegate { return datePublished >= since } - let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL }).mapValues { + let feedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL }).mapValues { Set($0) } - account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true) { error in + account.update(feedIDsAndItems: feedIDsAndItems, defaultRead: true) { error in if let error = error { completion(.failure(error)) return } - completion(.success(!webFeedIDsAndItems.isEmpty)) + completion(.success(!feedIDsAndItems.isEmpty)) } } @@ -400,7 +400,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { } var feedIDs: [String] = [] - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { if (feed.folderRelationship?.count ?? 0) > 1 { clearFolderRelationship(for: feed, withFolderName: folderToRemove) } else if let feedID = feed.externalID { @@ -423,7 +423,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } - func createWebFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> ()) { + func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> ()) { refreshProgress.addToNumberOfTasksAndRemaining(1) let folderName = (container as? Folder)?.name @@ -442,7 +442,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> ()) { + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> ()) { guard let feedID = feed.externalID else { completion(.failure(NewsBlurError.invalidParameter)) return @@ -469,11 +469,11 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } - func addWebFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> ()) { + func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> ()) { guard let folder = container as? Folder else { DispatchQueue.main.async { if let account = container as? Account { - account.addWebFeed(feed) + account.addFeed(feed) } completion(.success(())) } @@ -483,16 +483,16 @@ final class NewsBlurAccountDelegate: AccountDelegate { let folderName = folder.name ?? "" saveFolderRelationship(for: feed, withFolderName: folderName, id: folderName) - folder.addWebFeed(feed) + folder.addFeed(feed) completion(.success(())) } - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> ()) { + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> ()) { deleteFeed(for: account, with: feed, from: container, completion: completion) } - func moveWebFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> ()) { + func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> ()) { guard let feedID = feed.externalID else { completion(.failure(NewsBlurError.invalidParameter)) return @@ -509,8 +509,8 @@ final class NewsBlurAccountDelegate: AccountDelegate { switch result { case .success: - from.removeWebFeed(feed) - to.addWebFeed(feed) + from.removeFeed(feed) + to.addFeed(feed) completion(.success(())) case .failure(let error): @@ -519,9 +519,9 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> ()) { - if let existingFeed = account.existingWebFeed(withURL: feed.url) { - account.addWebFeed(existingFeed, to: container) { result in + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> ()) { + if let existingFeed = account.existingFeed(withURL: feed.url) { + account.addFeed(existingFeed, to: container) { result in switch result { case .success: completion(.success(())) @@ -530,7 +530,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } } else { - createWebFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in + createFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in switch result { case .success: completion(.success(())) @@ -548,9 +548,9 @@ final class NewsBlurAccountDelegate: AccountDelegate { } var feedsToRestore: [Feed] = [] - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { feedsToRestore.append(feed) - folder.topLevelWebFeeds.remove(feed) + folder.topLevelFeeds.remove(feed) } let group = DispatchGroup() @@ -562,7 +562,7 @@ final class NewsBlurAccountDelegate: AccountDelegate { case .success(let folder): for feed in feedsToRestore { group.enter() - self.restoreWebFeed(for: account, feed: feed, container: folder) { result in + self.restoreFeed(for: account, feed: feed, container: folder) { result in group.leave() switch result { case .success: diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index c271e02ec..bc3743c99 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -326,7 +326,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { let group = DispatchGroup() - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { if feed.folderRelationship?.count ?? 0 > 1 { @@ -358,7 +358,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { switch result { case .success: DispatchQueue.main.async { - account.clearWebFeedMetadata(feed) + account.clearFeedMetadata(feed) } case .failure(let error): os_log(.error, log: self.log, "Remove feed error: %@.", error.localizedDescription) @@ -390,7 +390,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } - func createWebFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { + func createFeed(for account: Account, url: String, name: String?, container: Container, validateFeed: Bool, completion: @escaping (Result) -> Void) { guard let url = URL(string: url) else { completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) return @@ -439,7 +439,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } - func renameWebFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { + func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { // This error should never happen guard let subscriptionID = feed.externalID else { @@ -466,7 +466,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } - func removeWebFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { + func removeFeed(for account: Account, with feed: Feed, from container: Container, completion: @escaping (Result) -> Void) { guard let subscriptionID = feed.externalID else { completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) return @@ -478,11 +478,11 @@ final class ReaderAPIAccountDelegate: AccountDelegate { switch result { case .success: DispatchQueue.main.async { - account.clearWebFeedMetadata(feed) - account.removeWebFeed(feed) + account.clearFeedMetadata(feed) + account.removeFeed(feed) if let folders = account.folders { for folder in folders { - folder.removeWebFeed(feed) + folder.removeFeed(feed) } } completion(.success(())) @@ -496,9 +496,9 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } - func moveWebFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { + func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { if from is Account { - addWebFeed(for: account, with: feed, to: to, completion: completion) + addFeed(for: account, with: feed, to: to, completion: completion) } else { guard let subscriptionId = feed.externalID, @@ -514,8 +514,8 @@ final class ReaderAPIAccountDelegate: AccountDelegate { self.refreshProgress.completeTask() switch result { case .success: - from.removeWebFeed(feed) - to.addWebFeed(feed) + from.removeFeed(feed) + to.addFeed(feed) completion(.success(())) case .failure(let error): completion(.failure(error)) @@ -524,7 +524,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } - func addWebFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { + func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { if let folder = container as? Folder, let feedExternalID = feed.externalID { refreshProgress.addToNumberOfTasksAndRemaining(1) caller.createTagging(subscriptionID: feedExternalID, tagName: folder.name ?? "") { result in @@ -533,8 +533,8 @@ final class ReaderAPIAccountDelegate: AccountDelegate { case .success: DispatchQueue.main.async { self.saveFolderRelationship(for: feed, folderExternalID: folder.externalID, feedExternalID: feedExternalID) - account.removeWebFeed(feed) - folder.addWebFeed(feed) + account.removeFeed(feed) + folder.addFeed(feed) completion(.success(())) } case .failure(let error): @@ -554,10 +554,10 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } - func restoreWebFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { + func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - if let existingFeed = account.existingWebFeed(withURL: feed.url) { - account.addWebFeed(existingFeed, to: container) { result in + if let existingFeed = account.existingFeed(withURL: feed.url) { + account.addFeed(existingFeed, to: container) { result in switch result { case .success: completion(.success(())) @@ -566,7 +566,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } } else { - createWebFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in + createFeed(for: account, url: feed.url, name: feed.editedName, container: container, validateFeed: true) { result in switch result { case .success: completion(.success(())) @@ -582,12 +582,12 @@ final class ReaderAPIAccountDelegate: AccountDelegate { let group = DispatchGroup() - for feed in folder.topLevelWebFeeds { + for feed in folder.topLevelFeeds { - folder.topLevelWebFeeds.remove(feed) + folder.topLevelFeeds.remove(feed) group.enter() - restoreWebFeed(for: account, feed: feed, container: folder) { result in + restoreFeed(for: account, feed: feed, container: folder) { result in group.leave() switch result { case .success: @@ -719,8 +719,8 @@ private extension ReaderAPIAccountDelegate { if let folders = account.folders { folders.forEach { folder in if !readerFolderExternalIDs.contains(folder.externalID ?? "") { - for feed in folder.topLevelWebFeeds { - account.addWebFeed(feed) + for feed in folder.topLevelFeeds { + account.addFeed(feed) clearFolderRelationship(for: feed, folderExternalID: folder.externalID) } account.removeFolder(folder) @@ -758,32 +758,32 @@ private extension ReaderAPIAccountDelegate { // Remove any feeds that are no longer in the subscriptions if let folders = account.folders { for folder in folders { - for feed in folder.topLevelWebFeeds { - if !subFeedIds.contains(feed.webFeedID) { - folder.removeWebFeed(feed) + for feed in folder.topLevelFeeds { + if !subFeedIds.contains(feed.feedID) { + folder.removeFeed(feed) } } } } - for feed in account.topLevelWebFeeds { - if !subFeedIds.contains(feed.webFeedID) { - account.clearWebFeedMetadata(feed) - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + if !subFeedIds.contains(feed.feedID) { + account.clearFeedMetadata(feed) + account.removeFeed(feed) } } // Add any feeds we don't have and update any we do subscriptions.forEach { subscription in - if let feed = account.existingWebFeed(withWebFeedID: subscription.feedID) { + if let feed = account.existingFeed(withFeedID: subscription.feedID) { feed.name = subscription.name feed.editedName = nil feed.homePageURL = subscription.homePageURL } else { - let feed = account.createWebFeed(with: subscription.name, url: subscription.url, webFeedID: subscription.feedID, homePageURL: subscription.homePageURL) + let feed = account.createFeed(with: subscription.name, url: subscription.url, feedID: subscription.feedID, homePageURL: subscription.homePageURL) feed.externalID = subscription.feedID - account.addWebFeed(feed) + account.addFeed(feed) } } @@ -818,25 +818,25 @@ private extension ReaderAPIAccountDelegate { let taggingFeedIDs = groupedTaggings.map { $0.feedID } // Move any feeds not in the folder to the account - for feed in folder.topLevelWebFeeds { - if !taggingFeedIDs.contains(feed.webFeedID) { - folder.removeWebFeed(feed) + for feed in folder.topLevelFeeds { + if !taggingFeedIDs.contains(feed.feedID) { + folder.removeFeed(feed) clearFolderRelationship(for: feed, folderExternalID: folder.externalID) - account.addWebFeed(feed) + account.addFeed(feed) } } // Add any feeds not in the folder - let folderFeedIds = folder.topLevelWebFeeds.map { $0.webFeedID } + let folderFeedIds = folder.topLevelFeeds.map { $0.feedID } for subscription in groupedTaggings { let taggingFeedID = subscription.feedID if !folderFeedIds.contains(taggingFeedID) { - guard let feed = account.existingWebFeed(withWebFeedID: taggingFeedID) else { + guard let feed = account.existingFeed(withFeedID: taggingFeedID) else { continue } saveFolderRelationship(for: feed, folderExternalID: folderExternalID, feedExternalID: subscription.feedID) - folder.addWebFeed(feed) + folder.addFeed(feed) } } @@ -845,9 +845,9 @@ private extension ReaderAPIAccountDelegate { let taggedFeedIDs = Set(subscriptions.filter({ !$0.categories.isEmpty }).map { String($0.feedID) }) // Remove all feeds from the account container that have a tag - for feed in account.topLevelWebFeeds { - if taggedFeedIDs.contains(feed.webFeedID) { - account.removeWebFeed(feed) + for feed in account.topLevelFeeds { + if taggedFeedIDs.contains(feed.feedID) { + account.removeFeed(feed) } } } @@ -921,14 +921,14 @@ private extension ReaderAPIAccountDelegate { DispatchQueue.main.async { - let feed = account.createWebFeed(with: sub.name, url: sub.url, webFeedID: String(sub.feedID), homePageURL: sub.homePageURL) + let feed = account.createFeed(with: sub.name, url: sub.url, feedID: String(sub.feedID), homePageURL: sub.homePageURL) feed.externalID = String(sub.feedID) - account.addWebFeed(feed, to: container) { result in + account.addFeed(feed, to: container) { result in switch result { case .success: if let name = name { - self.renameWebFeed(for: account, with: feed, to: name) { result in + self.renameFeed(for: account, with: feed, to: name) { result in switch result { case .success: self.initialFeedDownload(account: account, feed: feed, completion: completion) @@ -952,7 +952,7 @@ private extension ReaderAPIAccountDelegate { refreshProgress.addToNumberOfTasksAndRemaining(5) // Download the initial articles - self.caller.retrieveItemIDs(type: .allForFeed, webFeedID: feed.webFeedID) { result in + self.caller.retrieveItemIDs(type: .allForFeed, feedID: feed.feedID) { result in self.refreshProgress.completeTask() switch result { case .success(let articleIDs): @@ -1032,8 +1032,8 @@ private extension ReaderAPIAccountDelegate { func processEntries(account: Account, entries: [ReaderAPIEntry]?, completion: @escaping VoidCompletionBlock) { let parsedItems = mapEntriesToParsedItems(account: account, entries: entries) - let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } - account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true) { _ in + let feedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } + account.update(feedIDsAndItems: feedIDsAndItems, defaultRead: true) { _ in completion() } } diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index a769d956c..fd2995c25 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -554,7 +554,7 @@ final class ReaderAPICaller: NSObject { } - func retrieveItemIDs(type: ItemIDType, webFeedID: String? = nil, completion: @escaping ((Result<[String], Error>) -> Void)) { + func retrieveItemIDs(type: ItemIDType, feedID: String? = nil, completion: @escaping ((Result<[String], Error>) -> Void)) { guard let baseURL = apiBaseURL else { completion(.failure(CredentialsError.incompleteCredentials)) return @@ -579,13 +579,13 @@ final class ReaderAPICaller: NSObject { queryItems.append(URLQueryItem(name: "ot", value: String(Int(sinceTimeInterval)))) queryItems.append(URLQueryItem(name: "s", value: ReaderStreams.readingList.rawValue)) case .allForFeed: - guard let webFeedID = webFeedID else { + guard let feedID = feedID else { completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) return } let sinceTimeInterval = (Calendar.current.date(byAdding: .month, value: -3, to: Date()) ?? Date()).timeIntervalSince1970 queryItems.append(URLQueryItem(name: "ot", value: String(Int(sinceTimeInterval)))) - queryItems.append(URLQueryItem(name: "s", value: webFeedID)) + queryItems.append(URLQueryItem(name: "s", value: feedID)) case .unread: queryItems.append(URLQueryItem(name: "s", value: ReaderStreams.readingList.rawValue)) queryItems.append(URLQueryItem(name: "xt", value: ReaderState.read.rawValue)) diff --git a/Account/Sources/Account/SidebarItemIdentifier.swift b/Account/Sources/Account/SidebarItemIdentifier.swift index 2af20201e..579d322c8 100644 --- a/Account/Sources/Account/SidebarItemIdentifier.swift +++ b/Account/Sources/Account/SidebarItemIdentifier.swift @@ -16,7 +16,7 @@ public enum SidebarItemIdentifier: CustomStringConvertible, Hashable, Equatable case smartFeed(String) // String is a unique identifier case script(String) // String is a unique identifier - case webFeed(String, String) // accountID, webFeedID + case feed(String, String) // accountID, feedID case folder(String, String) // accountID, folderName public var description: String { @@ -25,8 +25,8 @@ public enum SidebarItemIdentifier: CustomStringConvertible, Hashable, Equatable return "smartFeed: \(id)" case .script(let id): return "script: \(id)" - case .webFeed(let accountID, let webFeedID): - return "feed: \(accountID)_\(webFeedID)" + case .feed(let accountID, let feedID): + return "feed: \(accountID)_\(feedID)" case .folder(let accountID, let folderName): return "folder: \(accountID)_\(folderName)" } @@ -44,11 +44,11 @@ public enum SidebarItemIdentifier: CustomStringConvertible, Hashable, Equatable "type": "script", "id": id ] - case .webFeed(let accountID, let webFeedID): + case .feed(let accountID, let feedID): return [ "type": "feed", "accountID": accountID, - "webFeedID": webFeedID + "feedID": feedID ] case .folder(let accountID, let folderName): return [ @@ -70,8 +70,8 @@ public enum SidebarItemIdentifier: CustomStringConvertible, Hashable, Equatable guard let id = userInfo["id"] as? String else { return nil } self = SidebarItemIdentifier.script(id) case "feed": - guard let accountID = userInfo["accountID"] as? String, let webFeedID = userInfo["webFeedID"] as? String else { return nil } - self = SidebarItemIdentifier.webFeed(accountID, webFeedID) + guard let accountID = userInfo["accountID"] as? String, let feedID = userInfo["feedID"] as? String else { return nil } + self = SidebarItemIdentifier.feed(accountID, feedID) case "folder": guard let accountID = userInfo["accountID"] as? String, let folderName = userInfo["folderName"] as? String else { return nil } self = SidebarItemIdentifier.folder(accountID, folderName) diff --git a/Account/Tests/AccountTests/Feedbin/AccountFeedbinFolderContentsSyncTest.swift b/Account/Tests/AccountTests/Feedbin/AccountFeedbinFolderContentsSyncTest.swift index 7dd579d0c..255413842 100644 --- a/Account/Tests/AccountTests/Feedbin/AccountFeedbinFolderContentsSyncTest.swift +++ b/Account/Tests/AccountTests/Feedbin/AccountFeedbinFolderContentsSyncTest.swift @@ -33,8 +33,8 @@ class AccountFeedbinFolderContentsSyncTest: XCTestCase { waitForExpectations(timeout: 5, handler: nil) let folder = account.folders?.filter { $0.name == "Developers" } .first! - XCTAssertEqual(156, folder?.topLevelWebFeeds.count ?? 0) - XCTAssertEqual(2, account.topLevelWebFeeds.count) + XCTAssertEqual(156, folder?.topLevelFeeds.count ?? 0) + XCTAssertEqual(2, account.topLevelFeeds.count) // Test Adding a Feed to the folder testTransport.testFiles["https://api.feedbin.com/v2/taggings.json"] = "JSON/taggings_add.json" @@ -45,8 +45,8 @@ class AccountFeedbinFolderContentsSyncTest: XCTestCase { } waitForExpectations(timeout: 5, handler: nil) - XCTAssertEqual(157, folder?.topLevelWebFeeds.count ?? 0) - XCTAssertEqual(1, account.topLevelWebFeeds.count) + XCTAssertEqual(157, folder?.topLevelFeeds.count ?? 0) + XCTAssertEqual(1, account.topLevelFeeds.count) // Test Deleting some Feeds from the folder testTransport.testFiles["https://api.feedbin.com/v2/taggings.json"] = "JSON/taggings_delete.json" @@ -57,8 +57,8 @@ class AccountFeedbinFolderContentsSyncTest: XCTestCase { } waitForExpectations(timeout: 5, handler: nil) - XCTAssertEqual(153, folder?.topLevelWebFeeds.count ?? 0) - XCTAssertEqual(5, account.topLevelWebFeeds.count) + XCTAssertEqual(153, folder?.topLevelFeeds.count ?? 0) + XCTAssertEqual(5, account.topLevelFeeds.count) TestAccountManager.shared.deleteAccount(account) diff --git a/Account/Tests/AccountTests/Feedbin/AccountFeedbinSyncTest.swift b/Account/Tests/AccountTests/Feedbin/AccountFeedbinSyncTest.swift index d96bb5377..f70a948dd 100644 --- a/Account/Tests/AccountTests/Feedbin/AccountFeedbinSyncTest.swift +++ b/Account/Tests/AccountTests/Feedbin/AccountFeedbinSyncTest.swift @@ -36,9 +36,9 @@ class AccountFeedbinSyncTest: XCTestCase { } waitForExpectations(timeout: 5, handler: nil) - XCTAssertEqual(224, account.flattenedWebFeeds().count) + XCTAssertEqual(224, account.flattenedFeeds().count) - let daringFireball = account.idToWebFeedDictionary["1296379"] + let daringFireball = account.idToFeedDictionary["1296379"] XCTAssertEqual("Daring Fireball", daringFireball!.name) XCTAssertEqual("https://daringfireball.net/feeds/json", daringFireball!.url) XCTAssertEqual("https://daringfireball.net/", daringFireball!.homePageURL) @@ -57,9 +57,9 @@ class AccountFeedbinSyncTest: XCTestCase { } waitForExpectations(timeout: 5, handler: nil) - XCTAssertEqual(225, account.flattenedWebFeeds().count) + XCTAssertEqual(225, account.flattenedFeeds().count) - let bPixels = account.idToWebFeedDictionary["1096623"] + let bPixels = account.idToFeedDictionary["1096623"] XCTAssertEqual("Beautiful Pixels", bPixels?.name) XCTAssertEqual("https://feedpress.me/beautifulpixels", bPixels?.url) XCTAssertEqual("https://beautifulpixels.com/", bPixels?.homePageURL) diff --git a/Account/Tests/AccountTests/Feedly/FeedlyCreateFeedsForCollectionFoldersOperationTests.swift b/Account/Tests/AccountTests/Feedly/FeedlyCreateFeedsForCollectionFoldersOperationTests.swift index fb4520e42..9390b3066 100644 --- a/Account/Tests/AccountTests/Feedly/FeedlyCreateFeedsForCollectionFoldersOperationTests.swift +++ b/Account/Tests/AccountTests/Feedly/FeedlyCreateFeedsForCollectionFoldersOperationTests.swift @@ -59,7 +59,7 @@ class FeedlyCreateFeedsForCollectionFoldersOperationTests: XCTestCase { completionExpectation.fulfill() } - XCTAssertTrue(account.flattenedWebFeeds().isEmpty, "Expected empty account.") + XCTAssertTrue(account.flattenedFeeds().isEmpty, "Expected empty account.") MainThreadOperationQueue.shared.add(createFeeds) @@ -73,8 +73,8 @@ class FeedlyCreateFeedsForCollectionFoldersOperationTests: XCTestCase { .flatMap { $0 } .map { $0.title }) - let accountFeeds = account.flattenedWebFeeds() - let ingestedIds = Set(accountFeeds.map { $0.webFeedID }) + let accountFeeds = account.flattenedFeeds() + let ingestedIds = Set(accountFeeds.map { $0.feedID }) let ingestedTitles = Set(accountFeeds.map { $0.nameForDisplay }) let missingIds = feedIds.subtracting(ingestedIds) @@ -92,7 +92,7 @@ class FeedlyCreateFeedsForCollectionFoldersOperationTests: XCTestCase { let ingestedFolderAndFeedIds = (account.folders ?? Set()) .sorted { $0.externalID! < $1.externalID! } .compactMap { folder -> [String: [String]]? in - return [folder.externalID!: folder.topLevelWebFeeds.map { $0.webFeedID }.sorted(by: <)] + return [folder.externalID!: folder.topLevelFeeds.map { $0.feedID }.sorted(by: <)] } XCTAssertEqual(expectedFolderAndFeedIds, ingestedFolderAndFeedIds, "Did not ingest feeds in their corresponding folders.") @@ -130,7 +130,7 @@ class FeedlyCreateFeedsForCollectionFoldersOperationTests: XCTestCase { completionExpectation.fulfill() } - XCTAssertTrue(account.flattenedWebFeeds().isEmpty, "Expected empty account.") + XCTAssertTrue(account.flattenedFeeds().isEmpty, "Expected empty account.") MainThreadOperationQueue.shared.add(createFeeds) @@ -166,8 +166,8 @@ class FeedlyCreateFeedsForCollectionFoldersOperationTests: XCTestCase { .flatMap { $0 } .map { $0.title }) - let accountFeeds = account.flattenedWebFeeds() - let ingestedIds = Set(accountFeeds.map { $0.webFeedID }) + let accountFeeds = account.flattenedFeeds() + let ingestedIds = Set(accountFeeds.map { $0.feedID }) let ingestedTitles = Set(accountFeeds.map { $0.nameForDisplay }) XCTAssertEqual(ingestedIds.count, feedIds.count) @@ -188,7 +188,7 @@ class FeedlyCreateFeedsForCollectionFoldersOperationTests: XCTestCase { let ingestedFolderAndFeedIds = (account.folders ?? Set()) .sorted { $0.externalID! < $1.externalID! } .compactMap { folder -> [String: [String]]? in - return [folder.externalID!: folder.topLevelWebFeeds.map { $0.webFeedID }.sorted(by: <)] + return [folder.externalID!: folder.topLevelFeeds.map { $0.feedID }.sorted(by: <)] } XCTAssertEqual(expectedFolderAndFeedIds, ingestedFolderAndFeedIds, "Did not ingest feeds to their corresponding folders.") diff --git a/Account/Tests/AccountTests/Feedly/FeedlyEntryParserTests.swift b/Account/Tests/AccountTests/Feedly/FeedlyEntryParserTests.swift index 1329b4339..948215095 100644 --- a/Account/Tests/AccountTests/Feedly/FeedlyEntryParserTests.swift +++ b/Account/Tests/AccountTests/Feedly/FeedlyEntryParserTests.swift @@ -55,7 +55,7 @@ class FeedlyEntryParserTests: XCTestCase { XCTAssertEqual(item.uniqueID, entry.id) // The following is not an error. - // The feedURL must match the webFeedID for the article to be connected to its matching feed. + // The feedURL must match the feedID for the article to be connected to its matching feed. XCTAssertEqual(item.feedURL, origin.streamId) XCTAssertEqual(item.title, entry.title) XCTAssertEqual(item.contentHTML, content.content) diff --git a/Account/Tests/AccountTests/Feedly/FeedlyFeedParserTests.swift b/Account/Tests/AccountTests/Feedly/FeedlyFeedParserTests.swift index 8ddd4aaec..277b6c906 100644 --- a/Account/Tests/AccountTests/Feedly/FeedlyFeedParserTests.swift +++ b/Account/Tests/AccountTests/Feedly/FeedlyFeedParserTests.swift @@ -22,7 +22,7 @@ class FeedlyFeedParserTests: XCTestCase { XCTAssertEqual(parser.title, name) XCTAssertEqual(parser.homePageURL, website) XCTAssertEqual(parser.url, url) - XCTAssertEqual(parser.webFeedID, id) + XCTAssertEqual(parser.feedID, id) } func testSanitization() { @@ -36,6 +36,6 @@ class FeedlyFeedParserTests: XCTestCase { XCTAssertEqual(parser.title, name) XCTAssertEqual(parser.homePageURL, website) XCTAssertEqual(parser.url, url) - XCTAssertEqual(parser.webFeedID, id) + XCTAssertEqual(parser.feedID, id) } } diff --git a/Account/Tests/AccountTests/Feedly/FeedlyMirrorCollectionsAsFoldersOperationTests.swift b/Account/Tests/AccountTests/Feedly/FeedlyMirrorCollectionsAsFoldersOperationTests.swift index 8fd7cbb59..940ef1d44 100644 --- a/Account/Tests/AccountTests/Feedly/FeedlyMirrorCollectionsAsFoldersOperationTests.swift +++ b/Account/Tests/AccountTests/Feedly/FeedlyMirrorCollectionsAsFoldersOperationTests.swift @@ -180,7 +180,7 @@ class FeedlyMirrorCollectionsAsFoldersOperationTests: XCTestCase { waitForExpectations(timeout: 2) - XCTAssertFalse(account.flattenedWebFeeds().isEmpty, "Expected account to have feeds.") + XCTAssertFalse(account.flattenedFeeds().isEmpty, "Expected account to have feeds.") } // Now that the folders are added, remove them all. @@ -197,7 +197,7 @@ class FeedlyMirrorCollectionsAsFoldersOperationTests: XCTestCase { waitForExpectations(timeout: 2) - let feeds = account.flattenedWebFeeds() + let feeds = account.flattenedFeeds() XCTAssertTrue(feeds.isEmpty) } diff --git a/Account/Tests/AccountTests/Feedly/FeedlyTestSupport.swift b/Account/Tests/AccountTests/Feedly/FeedlyTestSupport.swift index 3d02edf86..34432fcd9 100644 --- a/Account/Tests/AccountTests/Feedly/FeedlyTestSupport.swift +++ b/Account/Tests/AccountTests/Feedly/FeedlyTestSupport.swift @@ -134,12 +134,12 @@ class FeedlyTestSupport { return } let collectionFeeds = collection["feeds"] as! [[String: Any]] - let folderFeeds = folder.topLevelWebFeeds + let folderFeeds = folder.topLevelFeeds XCTAssertEqual(collectionFeeds.count, folderFeeds.count) let collectionFeedIds = Set(collectionFeeds.map { $0["id"] as! String }) - let folderFeedIds = Set(folderFeeds.map { $0.webFeedID }) + let folderFeedIds = Set(folderFeeds.map { $0.feedID }) let missingFeedIds = collectionFeedIds.subtracting(folderFeedIds) XCTAssertTrue(missingFeedIds.isEmpty, "Feeds with these ids were not found in the \"\(label)\" folder.") @@ -210,7 +210,7 @@ class FeedlyTestSupport { for item in articleItems where item.id == article.articleID { XCTAssertEqual(article.uniqueID, item.id) XCTAssertEqual(article.contentHTML, item.content) - XCTAssertEqual(article.webFeedID, item.feedId) + XCTAssertEqual(article.feedID, item.feedId) XCTAssertEqual(article.externalURL, item.externalUrl) } } diff --git a/Articles/Sources/Articles/Article.swift b/Articles/Sources/Articles/Article.swift index a979c7229..275085eef 100644 --- a/Articles/Sources/Articles/Article.swift +++ b/Articles/Sources/Articles/Article.swift @@ -14,7 +14,7 @@ public struct Article: Hashable { public let articleID: String // Unique database ID (possibly sync service ID) public let accountID: String - public let webFeedID: String // Likely a URL, but not necessarily + public let feedID: String // Likely a URL, but not necessarily public let uniqueID: String // Unique per feed (RSS guid, for example) public let title: String? public let contentHTML: String? @@ -28,9 +28,9 @@ public struct Article: Hashable { public let authors: Set? public let status: ArticleStatus - public init(accountID: String, articleID: String?, webFeedID: String, uniqueID: String, title: String?, contentHTML: String?, contentText: String?, url: String?, externalURL: String?, summary: String?, imageURL: String?, datePublished: Date?, dateModified: Date?, authors: Set?, status: ArticleStatus) { + public init(accountID: String, articleID: String?, feedID: String, uniqueID: String, title: String?, contentHTML: String?, contentText: String?, url: String?, externalURL: String?, summary: String?, imageURL: String?, datePublished: Date?, dateModified: Date?, authors: Set?, status: ArticleStatus) { self.accountID = accountID - self.webFeedID = webFeedID + self.feedID = feedID self.uniqueID = uniqueID self.title = title self.contentHTML = contentHTML @@ -48,12 +48,12 @@ public struct Article: Hashable { self.articleID = articleID } else { - self.articleID = Article.calculatedArticleID(webFeedID: webFeedID, uniqueID: uniqueID) + self.articleID = Article.calculatedArticleID(feedID: feedID, uniqueID: uniqueID) } } - public static func calculatedArticleID(webFeedID: String, uniqueID: String) -> String { - return databaseIDWithString("\(webFeedID) \(uniqueID)") + public static func calculatedArticleID(feedID: String, uniqueID: String) -> String { + return databaseIDWithString("\(feedID) \(uniqueID)") } // MARK: - Hashable @@ -65,7 +65,7 @@ public struct Article: Hashable { // MARK: - Equatable static public func ==(lhs: Article, rhs: Article) -> Bool { - return lhs.articleID == rhs.articleID && lhs.accountID == rhs.accountID && lhs.webFeedID == rhs.webFeedID && lhs.uniqueID == rhs.uniqueID && lhs.title == rhs.title && lhs.contentHTML == rhs.contentHTML && lhs.contentText == rhs.contentText && lhs.rawLink == rhs.rawLink && lhs.rawExternalLink == rhs.rawExternalLink && lhs.summary == rhs.summary && lhs.rawImageLink == rhs.rawImageLink && lhs.datePublished == rhs.datePublished && lhs.dateModified == rhs.dateModified && lhs.authors == rhs.authors + return lhs.articleID == rhs.articleID && lhs.accountID == rhs.accountID && lhs.feedID == rhs.feedID && lhs.uniqueID == rhs.uniqueID && lhs.title == rhs.title && lhs.contentHTML == rhs.contentHTML && lhs.contentText == rhs.contentText && lhs.rawLink == rhs.rawLink && lhs.rawExternalLink == rhs.rawExternalLink && lhs.summary == rhs.summary && lhs.rawImageLink == rhs.rawImageLink && lhs.datePublished == rhs.datePublished && lhs.dateModified == rhs.dateModified && lhs.authors == rhs.authors } } diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift index 5a7355201..cb42d7bbb 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift @@ -17,7 +17,7 @@ import Articles // Main thread only. -public typealias UnreadCountDictionary = [String: Int] // webFeedID: unreadCount +public typealias UnreadCountDictionary = [String: Int] // feedID: unreadCount public typealias UnreadCountDictionaryCompletionResult = Result public typealias UnreadCountDictionaryCompletionBlock = (UnreadCountDictionaryCompletionResult) -> Void @@ -90,32 +90,32 @@ public final class ArticlesDatabase { // MARK: - Fetching Articles - public func fetchArticles(_ webFeedID: String) throws -> Set
{ - return try articlesTable.fetchArticles(webFeedID) + public func fetchArticles(_ feedID: String) throws -> Set
{ + return try articlesTable.fetchArticles(feedID) } - public func fetchArticles(_ webFeedIDs: Set) throws -> Set
{ - return try articlesTable.fetchArticles(webFeedIDs) + public func fetchArticles(_ feedIDs: Set) throws -> Set
{ + return try articlesTable.fetchArticles(feedIDs) } public func fetchArticles(articleIDs: Set) throws -> Set
{ return try articlesTable.fetchArticles(articleIDs: articleIDs) } - public func fetchUnreadArticles(_ webFeedIDs: Set, _ limit: Int?) throws -> Set
{ - return try articlesTable.fetchUnreadArticles(webFeedIDs, limit) + public func fetchUnreadArticles(_ feedIDs: Set, _ limit: Int?) throws -> Set
{ + return try articlesTable.fetchUnreadArticles(feedIDs, limit) } - public func fetchTodayArticles(_ webFeedIDs: Set, _ limit: Int?) throws -> Set
{ - return try articlesTable.fetchArticlesSince(webFeedIDs, todayCutoffDate(), limit) + public func fetchTodayArticles(_ feedIDs: Set, _ limit: Int?) throws -> Set
{ + return try articlesTable.fetchArticlesSince(feedIDs, todayCutoffDate(), limit) } - public func fetchStarredArticles(_ webFeedIDs: Set, _ limit: Int?) throws -> Set
{ - return try articlesTable.fetchStarredArticles(webFeedIDs, limit) + public func fetchStarredArticles(_ feedIDs: Set, _ limit: Int?) throws -> Set
{ + return try articlesTable.fetchStarredArticles(feedIDs, limit) } - public func fetchArticlesMatching(_ searchString: String, _ webFeedIDs: Set) throws -> Set
{ - return try articlesTable.fetchArticlesMatching(searchString, webFeedIDs) + public func fetchArticlesMatching(_ searchString: String, _ feedIDs: Set) throws -> Set
{ + return try articlesTable.fetchArticlesMatching(searchString, feedIDs) } public func fetchArticlesMatchingWithArticleIDs(_ searchString: String, _ articleIDs: Set) throws -> Set
{ @@ -124,32 +124,32 @@ public final class ArticlesDatabase { // MARK: - Fetching Articles Async - public func fetchArticlesAsync(_ webFeedID: String, _ completion: @escaping ArticleSetResultBlock) { - articlesTable.fetchArticlesAsync(webFeedID, completion) + public func fetchArticlesAsync(_ feedID: String, _ completion: @escaping ArticleSetResultBlock) { + articlesTable.fetchArticlesAsync(feedID, completion) } - public func fetchArticlesAsync(_ webFeedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { - articlesTable.fetchArticlesAsync(webFeedIDs, completion) + public func fetchArticlesAsync(_ feedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { + articlesTable.fetchArticlesAsync(feedIDs, completion) } public func fetchArticlesAsync(articleIDs: Set, _ completion: @escaping ArticleSetResultBlock) { articlesTable.fetchArticlesAsync(articleIDs: articleIDs, completion) } - public func fetchUnreadArticlesAsync(_ webFeedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - articlesTable.fetchUnreadArticlesAsync(webFeedIDs, limit, completion) + public func fetchUnreadArticlesAsync(_ feedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { + articlesTable.fetchUnreadArticlesAsync(feedIDs, limit, completion) } - public func fetchTodayArticlesAsync(_ webFeedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - articlesTable.fetchArticlesSinceAsync(webFeedIDs, todayCutoffDate(), limit, completion) + public func fetchTodayArticlesAsync(_ feedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { + articlesTable.fetchArticlesSinceAsync(feedIDs, todayCutoffDate(), limit, completion) } - public func fetchedStarredArticlesAsync(_ webFeedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - articlesTable.fetchStarredArticlesAsync(webFeedIDs, limit, completion) + public func fetchedStarredArticlesAsync(_ feedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { + articlesTable.fetchStarredArticlesAsync(feedIDs, limit, completion) } - public func fetchArticlesMatchingAsync(_ searchString: String, _ webFeedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { - articlesTable.fetchArticlesMatchingAsync(searchString, webFeedIDs, completion) + public func fetchArticlesMatchingAsync(_ searchString: String, _ feedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { + articlesTable.fetchArticlesMatchingAsync(searchString, feedIDs, completion) } public func fetchArticlesMatchingWithArticleIDsAsync(_ searchString: String, _ articleIDs: Set, _ completion: @escaping ArticleSetResultBlock) { @@ -170,8 +170,8 @@ public final class ArticlesDatabase { } /// Fetch unread count for a single feed. - public func fetchUnreadCount(_ webFeedID: String, _ completion: @escaping SingleUnreadCountCompletionBlock) { - let operation = FetchFeedUnreadCountOperation(webFeedID: webFeedID, databaseQueue: queue, cutoffDate: articlesTable.articleCutoffDate) + public func fetchUnreadCount(_ feedID: String, _ completion: @escaping SingleUnreadCountCompletionBlock) { + let operation = FetchFeedUnreadCountOperation(feedID: feedID, databaseQueue: queue, cutoffDate: articlesTable.articleCutoffDate) operation.completionBlock = { operation in let fetchOperation = operation as! FetchFeedUnreadCountOperation completion(fetchOperation.result) @@ -179,9 +179,9 @@ public final class ArticlesDatabase { operationQueue.add(operation) } - /// Fetch non-zero unread counts for given webFeedIDs. - public func fetchUnreadCounts(for webFeedIDs: Set, _ completion: @escaping UnreadCountDictionaryCompletionBlock) { - let operation = FetchUnreadCountsForFeedsOperation(webFeedIDs: webFeedIDs, databaseQueue: queue) + /// Fetch non-zero unread counts for given feedIDs. + public func fetchUnreadCounts(for feedIDs: Set, _ completion: @escaping UnreadCountDictionaryCompletionBlock) { + let operation = FetchUnreadCountsForFeedsOperation(feedIDs: feedIDs, databaseQueue: queue) operation.completionBlock = { operation in let fetchOperation = operation as! FetchUnreadCountsForFeedsOperation completion(fetchOperation.result) @@ -189,30 +189,30 @@ public final class ArticlesDatabase { operationQueue.add(operation) } - public func fetchUnreadCountForToday(for webFeedIDs: Set, completion: @escaping SingleUnreadCountCompletionBlock) { - fetchUnreadCount(for: webFeedIDs, since: todayCutoffDate(), completion: completion) + public func fetchUnreadCountForToday(for feedIDs: Set, completion: @escaping SingleUnreadCountCompletionBlock) { + fetchUnreadCount(for: feedIDs, since: todayCutoffDate(), completion: completion) } - public func fetchUnreadCount(for webFeedIDs: Set, since: Date, completion: @escaping SingleUnreadCountCompletionBlock) { - articlesTable.fetchUnreadCount(webFeedIDs, since, completion) + public func fetchUnreadCount(for feedIDs: Set, since: Date, completion: @escaping SingleUnreadCountCompletionBlock) { + articlesTable.fetchUnreadCount(feedIDs, since, completion) } - public func fetchStarredAndUnreadCount(for webFeedIDs: Set, completion: @escaping SingleUnreadCountCompletionBlock) { - articlesTable.fetchStarredAndUnreadCount(webFeedIDs, completion) + public func fetchStarredAndUnreadCount(for feedIDs: Set, completion: @escaping SingleUnreadCountCompletionBlock) { + articlesTable.fetchStarredAndUnreadCount(feedIDs, completion) } // MARK: - Saving, Updating, and Deleting Articles /// Update articles and save new ones — for feed-based systems (local and iCloud). - public func update(with parsedItems: Set, webFeedID: String, deleteOlder: Bool, completion: @escaping UpdateArticlesCompletionBlock) { + public func update(with parsedItems: Set, feedID: String, deleteOlder: Bool, completion: @escaping UpdateArticlesCompletionBlock) { precondition(retentionStyle == .feedBased) - articlesTable.update(parsedItems, webFeedID, deleteOlder, completion) + articlesTable.update(parsedItems, feedID, deleteOlder, completion) } /// Update articles and save new ones — for sync systems (Feedbin, Feedly, etc.). - public func update(webFeedIDsAndItems: [String: Set], defaultRead: Bool, completion: @escaping UpdateArticlesCompletionBlock) { + public func update(feedIDsAndItems: [String: Set], defaultRead: Bool, completion: @escaping UpdateArticlesCompletionBlock) { precondition(retentionStyle == .syncSystem) - articlesTable.update(webFeedIDsAndItems, defaultRead, completion) + articlesTable.update(feedIDsAndItems, defaultRead, completion) } /// Delete articles @@ -289,11 +289,11 @@ public final class ArticlesDatabase { /// This prevents the database from growing forever. If we didn’t do this: /// 1) The database would grow to an inordinate size, and /// 2) the app would become very slow. - public func cleanupDatabaseAtStartup(subscribedToWebFeedIDs: Set) { + public func cleanupDatabaseAtStartup(subscribedToFeedIDs: Set) { if retentionStyle == .syncSystem { articlesTable.deleteOldArticles() } - articlesTable.deleteArticlesNotInSubscribedToFeedIDs(subscribedToWebFeedIDs) + articlesTable.deleteArticlesNotInSubscribedToFeedIDs(subscribedToFeedIDs) articlesTable.deleteOldStatuses() } diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift index ab7655474..8ddef4e2b 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift @@ -47,20 +47,20 @@ final class ArticlesTable: DatabaseTable { // MARK: - Fetching Articles for Feed - func fetchArticles(_ webFeedID: String) throws -> Set
{ - return try fetchArticles{ self.fetchArticlesForFeedID(webFeedID, $0) } + func fetchArticles(_ feedID: String) throws -> Set
{ + return try fetchArticles{ self.fetchArticlesForFeedID(feedID, $0) } } - func fetchArticlesAsync(_ webFeedID: String, _ completion: @escaping ArticleSetResultBlock) { - fetchArticlesAsync({ self.fetchArticlesForFeedID(webFeedID, $0) }, completion) + func fetchArticlesAsync(_ feedID: String, _ completion: @escaping ArticleSetResultBlock) { + fetchArticlesAsync({ self.fetchArticlesForFeedID(feedID, $0) }, completion) } - func fetchArticles(_ webFeedIDs: Set) throws -> Set
{ - return try fetchArticles{ self.fetchArticles(webFeedIDs, $0) } + func fetchArticles(_ feedIDs: Set) throws -> Set
{ + return try fetchArticles{ self.fetchArticles(feedIDs, $0) } } - func fetchArticlesAsync(_ webFeedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { - fetchArticlesAsync({ self.fetchArticles(webFeedIDs, $0) }, completion) + func fetchArticlesAsync(_ feedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { + fetchArticlesAsync({ self.fetchArticles(feedIDs, $0) }, completion) } // MARK: - Fetching Articles by articleID @@ -75,32 +75,32 @@ final class ArticlesTable: DatabaseTable { // MARK: - Fetching Unread Articles - func fetchUnreadArticles(_ webFeedIDs: Set, _ limit: Int?) throws -> Set
{ - return try fetchArticles{ self.fetchUnreadArticles(webFeedIDs, limit, $0) } + func fetchUnreadArticles(_ feedIDs: Set, _ limit: Int?) throws -> Set
{ + return try fetchArticles{ self.fetchUnreadArticles(feedIDs, limit, $0) } } - func fetchUnreadArticlesAsync(_ webFeedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - fetchArticlesAsync({ self.fetchUnreadArticles(webFeedIDs, limit, $0) }, completion) + func fetchUnreadArticlesAsync(_ feedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { + fetchArticlesAsync({ self.fetchUnreadArticles(feedIDs, limit, $0) }, completion) } // MARK: - Fetching Today Articles - func fetchArticlesSince(_ webFeedIDs: Set, _ cutoffDate: Date, _ limit: Int?) throws -> Set
{ - return try fetchArticles{ self.fetchArticlesSince(webFeedIDs, cutoffDate, limit, $0) } + func fetchArticlesSince(_ feedIDs: Set, _ cutoffDate: Date, _ limit: Int?) throws -> Set
{ + return try fetchArticles{ self.fetchArticlesSince(feedIDs, cutoffDate, limit, $0) } } - func fetchArticlesSinceAsync(_ webFeedIDs: Set, _ cutoffDate: Date, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - fetchArticlesAsync({ self.fetchArticlesSince(webFeedIDs, cutoffDate, limit, $0) }, completion) + func fetchArticlesSinceAsync(_ feedIDs: Set, _ cutoffDate: Date, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { + fetchArticlesAsync({ self.fetchArticlesSince(feedIDs, cutoffDate, limit, $0) }, completion) } // MARK: - Fetching Starred Articles - func fetchStarredArticles(_ webFeedIDs: Set, _ limit: Int?) throws -> Set
{ - return try fetchArticles{ self.fetchStarredArticles(webFeedIDs, limit, $0) } + func fetchStarredArticles(_ feedIDs: Set, _ limit: Int?) throws -> Set
{ + return try fetchArticles{ self.fetchStarredArticles(feedIDs, limit, $0) } } - func fetchStarredArticlesAsync(_ webFeedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { - fetchArticlesAsync({ self.fetchStarredArticles(webFeedIDs, limit, $0) }, completion) + func fetchStarredArticlesAsync(_ feedIDs: Set, _ limit: Int?, _ completion: @escaping ArticleSetResultBlock) { + fetchArticlesAsync({ self.fetchStarredArticles(feedIDs, limit, $0) }, completion) } // MARK: - Fetching Search Articles @@ -124,9 +124,9 @@ final class ArticlesTable: DatabaseTable { return articles } - func fetchArticlesMatching(_ searchString: String, _ webFeedIDs: Set) throws -> Set
{ + func fetchArticlesMatching(_ searchString: String, _ feedIDs: Set) throws -> Set
{ var articles = try fetchArticlesMatching(searchString) - articles = articles.filter{ webFeedIDs.contains($0.webFeedID) } + articles = articles.filter{ feedIDs.contains($0.feedID) } return articles } @@ -136,8 +136,8 @@ final class ArticlesTable: DatabaseTable { return articles } - func fetchArticlesMatchingAsync(_ searchString: String, _ webFeedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { - fetchArticlesAsync({ self.fetchArticlesMatching(searchString, webFeedIDs, $0) }, completion) + func fetchArticlesMatchingAsync(_ searchString: String, _ feedIDs: Set, _ completion: @escaping ArticleSetResultBlock) { + fetchArticlesAsync({ self.fetchArticlesMatching(searchString, feedIDs, $0) }, completion) } func fetchArticlesMatchingWithArticleIDsAsync(_ searchString: String, _ articleIDs: Set, _ completion: @escaping ArticleSetResultBlock) { @@ -190,7 +190,7 @@ final class ArticlesTable: DatabaseTable { // MARK: - Updating and Deleting - func update(_ parsedItems: Set, _ webFeedID: String, _ deleteOlder: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) { + func update(_ parsedItems: Set, _ feedID: String, _ deleteOlder: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) { precondition(retentionStyle == .feedBased) if parsedItems.isEmpty { callUpdateArticlesCompletionBlock(nil, nil, nil, completion) @@ -215,13 +215,13 @@ final class ArticlesTable: DatabaseTable { let (statusesDictionary, _) = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, false, database) //1 assert(statusesDictionary.count == articleIDs.count) - let incomingArticles = Article.articlesWithParsedItems(parsedItems, webFeedID, self.accountID, statusesDictionary) //2 + let incomingArticles = Article.articlesWithParsedItems(parsedItems, feedID, self.accountID, statusesDictionary) //2 if incomingArticles.isEmpty { self.callUpdateArticlesCompletionBlock(nil, nil, nil, completion) return } - let fetchedArticles = self.fetchArticlesForFeedID(webFeedID, database) //4 + let fetchedArticles = self.fetchArticlesForFeedID(feedID, database) //4 let fetchedArticlesDictionary = fetchedArticles.dictionary() let newArticles = self.findAndSaveNewArticles(incomingArticles, fetchedArticlesDictionary, database) //5 @@ -270,9 +270,9 @@ final class ArticlesTable: DatabaseTable { } } - func update(_ webFeedIDsAndItems: [String: Set], _ read: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) { + func update(_ feedIDsAndItems: [String: Set], _ read: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) { precondition(retentionStyle == .syncSystem) - if webFeedIDsAndItems.isEmpty { + if feedIDsAndItems.isEmpty { callUpdateArticlesCompletionBlock(nil, nil, nil, completion) return } @@ -290,14 +290,14 @@ final class ArticlesTable: DatabaseTable { func makeDatabaseCalls(_ database: FMDatabase) { var articleIDs = Set() - for (_, parsedItems) in webFeedIDsAndItems { + for (_, parsedItems) in feedIDsAndItems { articleIDs.formUnion(parsedItems.articleIDs()) } let (statusesDictionary, _) = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, read, database) //1 assert(statusesDictionary.count == articleIDs.count) - let allIncomingArticles = Article.articlesWithWebFeedIDsAndItems(webFeedIDsAndItems, self.accountID, statusesDictionary) //2 + let allIncomingArticles = Article.articlesWithFeedIDsAndItems(feedIDsAndItems, self.accountID, statusesDictionary) //2 if allIncomingArticles.isEmpty { self.callUpdateArticlesCompletionBlock(nil, nil, nil, completion) return @@ -366,9 +366,9 @@ final class ArticlesTable: DatabaseTable { // MARK: - Unread Counts - func fetchUnreadCount(_ webFeedIDs: Set, _ since: Date, _ completion: @escaping SingleUnreadCountCompletionBlock) { + func fetchUnreadCount(_ feedIDs: Set, _ since: Date, _ completion: @escaping SingleUnreadCountCompletionBlock) { // Get unread count for today, for instance. - if webFeedIDs.isEmpty { + if feedIDs.isEmpty { completion(.success(0)) return } @@ -376,11 +376,11 @@ final class ArticlesTable: DatabaseTable { queue.runInDatabase { databaseResult in func makeDatabaseCalls(_ database: FMDatabase) { - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! let sql = "select count(*) from articles natural join statuses where feedID in \(placeholders) and (datePublished > ? or (datePublished is null and dateArrived > ?)) and read=0;" var parameters = [Any]() - parameters += Array(webFeedIDs) as [Any] + parameters += Array(feedIDs) as [Any] parameters += [since] as [Any] parameters += [since] as [Any] @@ -402,8 +402,8 @@ final class ArticlesTable: DatabaseTable { } } - func fetchStarredAndUnreadCount(_ webFeedIDs: Set, _ completion: @escaping SingleUnreadCountCompletionBlock) { - if webFeedIDs.isEmpty { + func fetchStarredAndUnreadCount(_ feedIDs: Set, _ completion: @escaping SingleUnreadCountCompletionBlock) { + if feedIDs.isEmpty { completion(.success(0)) return } @@ -411,9 +411,9 @@ final class ArticlesTable: DatabaseTable { queue.runInDatabase { databaseResult in func makeDatabaseCalls(_ database: FMDatabase) { - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! let sql = "select count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 and starred=1;" - let parameters = Array(webFeedIDs) as [Any] + let parameters = Array(feedIDs) as [Any] let unreadCount = self.numberWithSQLAndParameters(sql, parameters, in: database) @@ -604,16 +604,16 @@ final class ArticlesTable: DatabaseTable { /// Delete articles from feeds that are no longer in the current set of subscribed-to feeds. /// This deletes from the articles and articleStatuses tables, /// and, via a trigger, it also deletes from the search index. - func deleteArticlesNotInSubscribedToFeedIDs(_ webFeedIDs: Set) { - if webFeedIDs.isEmpty { + func deleteArticlesNotInSubscribedToFeedIDs(_ feedIDs: Set) { + if feedIDs.isEmpty { return } queue.runInDatabase { databaseResult in func makeDatabaseCalls(_ database: FMDatabase) { - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! let sql = "select articleID from articles where feedID not in \(placeholders);" - let parameters = Array(webFeedIDs) as [Any] + let parameters = Array(feedIDs) as [Any] guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else { return } @@ -785,24 +785,24 @@ private extension ArticlesTable { return articlesWithResultSet(resultSet, database) } - func fetchArticles(_ webFeedIDs: Set, _ database: FMDatabase) -> Set
{ + func fetchArticles(_ feedIDs: Set, _ database: FMDatabase) -> Set
{ // select * from articles natural join statuses where feedID in ('http://ranchero.com/xml/rss.xml') and read=0 - if webFeedIDs.isEmpty { + if feedIDs.isEmpty { return Set
() } - let parameters = webFeedIDs.map { $0 as AnyObject } - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let parameters = feedIDs.map { $0 as AnyObject } + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! let whereClause = "feedID in \(placeholders)" return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters) } - func fetchUnreadArticles(_ webFeedIDs: Set, _ limit: Int?, _ database: FMDatabase) -> Set
{ + func fetchUnreadArticles(_ feedIDs: Set, _ limit: Int?, _ database: FMDatabase) -> Set
{ // select * from articles natural join statuses where feedID in ('http://ranchero.com/xml/rss.xml') and read=0 - if webFeedIDs.isEmpty { + if feedIDs.isEmpty { return Set
() } - let parameters = webFeedIDs.map { $0 as AnyObject } - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let parameters = feedIDs.map { $0 as AnyObject } + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! var whereClause = "feedID in \(placeholders) and read=0" if let limit = limit { whereClause.append(" order by coalesce(datePublished, dateModified, dateArrived) desc limit \(limit)") @@ -810,8 +810,8 @@ private extension ArticlesTable { return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters) } - func fetchArticlesForFeedID(_ webFeedID: String, _ database: FMDatabase) -> Set
{ - return fetchArticlesWithWhereClause(database, whereClause: "articles.feedID = ?", parameters: [webFeedID as AnyObject]) + func fetchArticlesForFeedID(_ feedID: String, _ database: FMDatabase) -> Set
{ + return fetchArticlesWithWhereClause(database, whereClause: "articles.feedID = ?", parameters: [feedID as AnyObject]) } func fetchArticles(articleIDs: Set, _ database: FMDatabase) -> Set
{ @@ -824,15 +824,15 @@ private extension ArticlesTable { return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters) } - func fetchArticlesSince(_ webFeedIDs: Set, _ cutoffDate: Date, _ limit: Int?, _ database: FMDatabase) -> Set
{ + func fetchArticlesSince(_ feedIDs: Set, _ cutoffDate: Date, _ limit: Int?, _ database: FMDatabase) -> Set
{ // select * from articles natural join statuses where feedID in ('http://ranchero.com/xml/rss.xml') and (datePublished > ? || (datePublished is null and dateArrived > ?) // // datePublished may be nil, so we fall back to dateArrived. - if webFeedIDs.isEmpty { + if feedIDs.isEmpty { return Set
() } - let parameters = webFeedIDs.map { $0 as AnyObject } + [cutoffDate as AnyObject, cutoffDate as AnyObject] - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let parameters = feedIDs.map { $0 as AnyObject } + [cutoffDate as AnyObject, cutoffDate as AnyObject] + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! var whereClause = "feedID in \(placeholders) and (datePublished > ? or (datePublished is null and dateArrived > ?))" if let limit = limit { whereClause.append(" order by coalesce(datePublished, dateModified, dateArrived) desc limit \(limit)") @@ -840,13 +840,13 @@ private extension ArticlesTable { return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters) } - func fetchStarredArticles(_ webFeedIDs: Set, _ limit: Int?, _ database: FMDatabase) -> Set
{ + func fetchStarredArticles(_ feedIDs: Set, _ limit: Int?, _ database: FMDatabase) -> Set
{ // select * from articles natural join statuses where feedID in ('http://ranchero.com/xml/rss.xml') and starred=1; - if webFeedIDs.isEmpty { + if feedIDs.isEmpty { return Set
() } - let parameters = webFeedIDs.map { $0 as AnyObject } - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let parameters = feedIDs.map { $0 as AnyObject } + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! var whereClause = "feedID in \(placeholders) and starred=1" if let limit = limit { whereClause.append(" order by coalesce(datePublished, dateModified, dateArrived) desc limit \(limit)") @@ -854,10 +854,10 @@ private extension ArticlesTable { return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters) } - func fetchArticlesMatching(_ searchString: String, _ webFeedIDs: Set, _ database: FMDatabase) -> Set
{ + func fetchArticlesMatching(_ searchString: String, _ feedIDs: Set, _ database: FMDatabase) -> Set
{ let articles = fetchArticlesMatching(searchString, database) // TODO: include the feedIDs in the SQL rather than filtering here. - return articles.filter{ webFeedIDs.contains($0.webFeedID) } + return articles.filter{ feedIDs.contains($0.feedID) } } func fetchArticlesMatchingWithArticleIDs(_ searchString: String, _ articleIDs: Set, _ database: FMDatabase) -> Set
{ diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/Article+Database.swift b/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/Article+Database.swift index 30ac2bfd3..4e42939d8 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/Article+Database.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/Article+Database.swift @@ -19,7 +19,7 @@ extension Article { assertionFailure("Expected articleID.") return nil } - guard let webFeedID = row.string(forColumn: DatabaseKey.feedID) else { + guard let feedID = row.string(forColumn: DatabaseKey.feedID) else { assertionFailure("Expected feedID.") return nil } @@ -38,10 +38,10 @@ extension Article { let datePublished = row.date(forColumn: DatabaseKey.datePublished) let dateModified = row.date(forColumn: DatabaseKey.dateModified) - self.init(accountID: accountID, articleID: articleID, webFeedID: webFeedID, uniqueID: uniqueID, title: title, contentHTML: contentHTML, contentText: contentText, url: url, externalURL: externalURL, summary: summary, imageURL: imageURL, datePublished: datePublished, dateModified: dateModified, authors: nil, status: status) + self.init(accountID: accountID, articleID: articleID, feedID: feedID, uniqueID: uniqueID, title: title, contentHTML: contentHTML, contentText: contentText, url: url, externalURL: externalURL, summary: summary, imageURL: imageURL, datePublished: datePublished, dateModified: dateModified, authors: nil, status: status) } - init(parsedItem: ParsedItem, maximumDateAllowed: Date, accountID: String, webFeedID: String, status: ArticleStatus) { + init(parsedItem: ParsedItem, maximumDateAllowed: Date, accountID: String, feedID: String, status: ArticleStatus) { let authors = Author.authorsWithParsedAuthors(parsedItem.authors) // Deal with future datePublished and dateModified dates. @@ -58,7 +58,7 @@ extension Article { dateModified = nil } - self.init(accountID: accountID, articleID: parsedItem.syncServiceID, webFeedID: webFeedID, uniqueID: parsedItem.uniqueID, title: parsedItem.title, contentHTML: parsedItem.contentHTML, contentText: parsedItem.contentText, url: parsedItem.url, externalURL: parsedItem.externalURL, summary: parsedItem.summary, imageURL: parsedItem.imageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, status: status) + self.init(accountID: accountID, articleID: parsedItem.syncServiceID, feedID: feedID, uniqueID: parsedItem.uniqueID, title: parsedItem.title, contentHTML: parsedItem.contentHTML, contentText: parsedItem.contentText, url: parsedItem.url, externalURL: parsedItem.externalURL, summary: parsedItem.summary, imageURL: parsedItem.imageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, status: status) } private func addPossibleStringChangeWithKeyPath(_ comparisonKeyPath: KeyPath, _ otherArticle: Article, _ key: String, _ dictionary: inout DatabaseDictionary) { @@ -71,7 +71,7 @@ extension Article { if authors.isEmpty { return self } - return Article(accountID: self.accountID, articleID: self.articleID, webFeedID: self.webFeedID, uniqueID: self.uniqueID, title: self.title, contentHTML: self.contentHTML, contentText: self.contentText, url: self.rawLink, externalURL: self.rawExternalLink, summary: self.summary, imageURL: self.rawImageLink, datePublished: self.datePublished, dateModified: self.dateModified, authors: authors, status: self.status) + return Article(accountID: self.accountID, articleID: self.articleID, feedID: self.feedID, uniqueID: self.uniqueID, title: self.title, contentHTML: self.contentHTML, contentText: self.contentText, url: self.rawLink, externalURL: self.rawExternalLink, summary: self.summary, imageURL: self.rawImageLink, datePublished: self.datePublished, dateModified: self.dateModified, authors: authors, status: self.status) } func changesFrom(_ existingArticle: Article) -> DatabaseDictionary? { @@ -117,22 +117,22 @@ extension Article { return Date().addingTimeInterval(60 * 60 * 24) // Allow dates up to about 24 hours ahead of now } - static func articlesWithWebFeedIDsAndItems(_ webFeedIDsAndItems: [String: Set], _ accountID: String, _ statusesDictionary: [String: ArticleStatus]) -> Set
{ + static func articlesWithFeedIDsAndItems(_ feedIDsAndItems: [String: Set], _ accountID: String, _ statusesDictionary: [String: ArticleStatus]) -> Set
{ let maximumDateAllowed = _maximumDateAllowed() var feedArticles = Set
() - for (webFeedID, parsedItems) in webFeedIDsAndItems { + for (feedID, parsedItems) in feedIDsAndItems { for parsedItem in parsedItems { let status = statusesDictionary[parsedItem.articleID]! - let article = Article(parsedItem: parsedItem, maximumDateAllowed: maximumDateAllowed, accountID: accountID, webFeedID: webFeedID, status: status) + let article = Article(parsedItem: parsedItem, maximumDateAllowed: maximumDateAllowed, accountID: accountID, feedID: feedID, status: status) feedArticles.insert(article) } } return feedArticles } - static func articlesWithParsedItems(_ parsedItems: Set, _ webFeedID: String, _ accountID: String, _ statusesDictionary: [String: ArticleStatus]) -> Set
{ + static func articlesWithParsedItems(_ parsedItems: Set, _ feedID: String, _ accountID: String, _ statusesDictionary: [String: ArticleStatus]) -> Set
{ let maximumDateAllowed = _maximumDateAllowed() - return Set(parsedItems.map{ Article(parsedItem: $0, maximumDateAllowed: maximumDateAllowed, accountID: accountID, webFeedID: webFeedID, status: statusesDictionary[$0.articleID]!) }) + return Set(parsedItems.map{ Article(parsedItem: $0, maximumDateAllowed: maximumDateAllowed, accountID: accountID, feedID: feedID, status: statusesDictionary[$0.articleID]!) }) } } @@ -142,7 +142,7 @@ extension Article: DatabaseObject { var d = DatabaseDictionary() d[DatabaseKey.articleID] = articleID - d[DatabaseKey.feedID] = webFeedID + d[DatabaseKey.feedID] = feedID d[DatabaseKey.uniqueID] = uniqueID if let title = title { diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/ParsedArticle+Database.swift b/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/ParsedArticle+Database.swift index e59539d11..271876057 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/ParsedArticle+Database.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/Extensions/ParsedArticle+Database.swift @@ -17,6 +17,6 @@ extension ParsedItem { return s } // Must be same calculation as for Article. - return Article.calculatedArticleID(webFeedID: feedURL, uniqueID: uniqueID) + return Article.calculatedArticleID(feedID: feedURL, uniqueID: uniqueID) } } diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift b/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift index bad3e2e1f..2b49db38f 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchAllUnreadCountsOperation.swift @@ -63,8 +63,8 @@ private extension FetchAllUnreadCountsOperation { return } let unreadCount = resultSet.long(forColumnIndex: 1) - if let webFeedID = resultSet.string(forColumnIndex: 0) { - unreadCountDictionary[webFeedID] = unreadCount + if let feedID = resultSet.string(forColumnIndex: 0) { + unreadCountDictionary[feedID] = unreadCount } } resultSet.close() diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift b/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift index 03c6cf793..d7728fb26 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchFeedUnreadCountOperation.swift @@ -25,10 +25,10 @@ public final class FetchFeedUnreadCountOperation: MainThreadOperation { private let queue: DatabaseQueue private let cutoffDate: Date - private let webFeedID: String + private let feedID: String - init(webFeedID: String, databaseQueue: DatabaseQueue, cutoffDate: Date) { - self.webFeedID = webFeedID + init(feedID: String, databaseQueue: DatabaseQueue, cutoffDate: Date) { + self.feedID = feedID self.queue = databaseQueue self.cutoffDate = cutoffDate } @@ -55,7 +55,7 @@ private extension FetchFeedUnreadCountOperation { func fetchUnreadCount(_ database: FMDatabase) { let sql = "select count(*) from articles natural join statuses where feedID=? and read=0;" - guard let resultSet = database.executeQuery(sql, withArgumentsIn: [webFeedID]) else { + guard let resultSet = database.executeQuery(sql, withArgumentsIn: [feedID]) else { informOperationDelegateOfCompletion() return } diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift b/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift index 3a560a94d..c3bcff808 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/Operations/FetchUnreadCountsForFeedsOperation.swift @@ -24,10 +24,10 @@ public final class FetchUnreadCountsForFeedsOperation: MainThreadOperation { public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock? private let queue: DatabaseQueue - private let webFeedIDs: Set + private let feedIDs: Set - init(webFeedIDs: Set, databaseQueue: DatabaseQueue) { - self.webFeedIDs = webFeedIDs + init(feedIDs: Set, databaseQueue: DatabaseQueue) { + self.feedIDs = feedIDs self.queue = databaseQueue } @@ -51,10 +51,10 @@ public final class FetchUnreadCountsForFeedsOperation: MainThreadOperation { private extension FetchUnreadCountsForFeedsOperation { func fetchUnreadCounts(_ database: FMDatabase) { - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! let sql = "select distinct feedID, count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 group by feedID;" - let parameters = Array(webFeedIDs) as [Any] + let parameters = Array(feedIDs) as [Any] guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else { informOperationDelegateOfCompletion() @@ -74,8 +74,8 @@ private extension FetchUnreadCountsForFeedsOperation { return } let unreadCount = resultSet.long(forColumnIndex: 1) - if let webFeedID = resultSet.string(forColumnIndex: 0) { - unreadCountDictionary[webFeedID] = unreadCount + if let feedID = resultSet.string(forColumnIndex: 0) { + unreadCountDictionary[feedID] = unreadCount } } resultSet.close() diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index d4b2ee784..72ba044ee 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -34,8 +34,8 @@ final class AppDefaults { static let subscribeToFeedsInDefaultBrowser = "subscribeToFeedsInDefaultBrowser" static let articleTextSize = "articleTextSize" static let refreshInterval = "refreshInterval" - static let addWebFeedAccountID = "addWebFeedAccountID" - static let addWebFeedFolderName = "addWebFeedFolderName" + static let addFeedAccountID = "addWebFeedAccountID" + static let addFeedFolderName = "addWebFeedFolderName" static let addFolderAccountID = "addFolderAccountID" static let importOPMLAccountID = "importOPMLAccountID" static let exportOPMLAccountID = "exportOPMLAccountID" @@ -149,21 +149,21 @@ final class AppDefaults { } } - var addWebFeedAccountID: String? { + var addFeedAccountID: String? { get { - return AppDefaults.string(for: Key.addWebFeedAccountID) + return AppDefaults.string(for: Key.addFeedAccountID) } set { - AppDefaults.setString(for: Key.addWebFeedAccountID, newValue) + AppDefaults.setString(for: Key.addFeedAccountID, newValue) } } - var addWebFeedFolderName: String? { + var addFeedFolderName: String? { get { - return AppDefaults.string(for: Key.addWebFeedFolderName) + return AppDefaults.string(for: Key.addFeedFolderName) } set { - AppDefaults.setString(for: Key.addWebFeedFolderName, newValue) + AppDefaults.setString(for: Key.addFeedFolderName, newValue) } } diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 39867913d..aa198c5b4 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -40,7 +40,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat var faviconDownloader: FaviconDownloader! var imageDownloader: ImageDownloader! var authorAvatarDownloader: AuthorAvatarDownloader! - var webFeedIconDownloader: WebFeedIconDownloader! + var feedIconDownloader: FeedIconDownloader! var extensionContainersFile: ExtensionContainersFile! var extensionFeedAddRequestFile: ExtensionFeedAddRequestFile! @@ -138,9 +138,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat addFolderWindowController!.runSheetOnWindow(window) } - func showAddWebFeedSheetOnWindow(_ window: NSWindow, urlString: String?, name: String?, account: Account?, folder: Folder?) { + func showAddFeedSheetOnWindow(_ window: NSWindow, urlString: String?, name: String?, account: Account?, folder: Folder?) { addFeedController = AddFeedController(hostWindow: window) - addFeedController?.showAddFeedSheet(.webFeed, urlString, name, account, folder) + addFeedController?.showAddFeedSheet(urlString, name, account, folder) } // MARK: - NSApplicationDelegate @@ -171,7 +171,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat imageDownloader = ImageDownloader(folder: imagesFolder) authorAvatarDownloader = AuthorAvatarDownloader(imageDownloader: imageDownloader) - webFeedIconDownloader = WebFeedIconDownloader(imageDownloader: imageDownloader, folder: cacheFolder) + feedIconDownloader = FeedIconDownloader(imageDownloader: imageDownloader, folder: cacheFolder) appName = (Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String) } @@ -220,7 +220,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat mainWindowController?.window?.center() } - NotificationCenter.default.addObserver(self, selector: #selector(webFeedSettingDidChange(_:)), name: .WebFeedSettingDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) DispatchQueue.main.async { @@ -348,11 +348,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat } } - @objc func webFeedSettingDidChange(_ note: Notification) { - guard let feed = note.object as? Feed, let key = note.userInfo?[Feed.WebFeedSettingUserInfoKey] as? String else { + @objc func feedSettingDidChange(_ note: Notification) { + guard let feed = note.object as? Feed, let key = note.userInfo?[Feed.FeedSettingUserInfoKey] as? String else { return } - if key == Feed.WebFeedSettingKey.homePageURL || key == Feed.WebFeedSettingKey.faviconURL { + if key == Feed.FeedSettingKey.homePageURL || key == Feed.FeedSettingKey.faviconURL { let _ = faviconDownloader.favicon(for: feed) } } @@ -464,7 +464,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat return mainWindowController?.isOpen ?? false } - if item.action == #selector(showAddWebFeedWindow(_:)) || item.action == #selector(showAddFolderWindow(_:)) { + if item.action == #selector(showAddFeedWindow(_:)) || item.action == #selector(showAddFolderWindow(_:)) { return !isDisplayingSheet && !AccountManager.shared.activeAccounts.isEmpty } @@ -499,14 +499,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat } // MARK: Add Feed - func addWebFeed(_ urlString: String?, name: String? = nil, account: Account? = nil, folder: Folder? = nil) { + func addFeed(_ urlString: String?, name: String? = nil, account: Account? = nil, folder: Folder? = nil) { createAndShowMainWindowIfNecessary() if mainWindowController!.isDisplayingSheet { return } - showAddWebFeedSheetOnWindow(mainWindowController!.window!, urlString: urlString, name: name, account: account, folder: folder) + showAddFeedSheetOnWindow(mainWindowController!.window!, urlString: urlString, name: name, account: account, folder: folder) } // MARK: - Dock Badge @@ -537,8 +537,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present) } - @IBAction func showAddWebFeedWindow(_ sender: Any?) { - addWebFeed(nil) + @IBAction func showAddFeedWindow(_ sender: Any?) { + addFeed(nil) } @IBAction func showAddFolderWindow(_ sender: Any?) { @@ -611,7 +611,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidat if AccountManager.shared.anyAccountHasNetNewsWireNewsSubscription() { return } - addWebFeed(AccountManager.netNewsWireNewsURL, name: "NetNewsWire News") + addFeed(AccountManager.netNewsWireNewsURL, name: "NetNewsWire News") } @IBAction func openWebsite(_ sender: Any?) { diff --git a/Mac/Base.lproj/AddWebFeedSheet.xib b/Mac/Base.lproj/AddFeedSheet.xib similarity index 86% rename from Mac/Base.lproj/AddWebFeedSheet.xib rename to Mac/Base.lproj/AddFeedSheet.xib index 812519436..d9742fcb9 100644 --- a/Mac/Base.lproj/AddWebFeedSheet.xib +++ b/Mac/Base.lproj/AddFeedSheet.xib @@ -1,11 +1,12 @@ - + - + + - + @@ -20,21 +21,21 @@ - - - + + + - - + + - - + + @@ -48,24 +49,24 @@ - - + + - - + + - - + + @@ -73,10 +74,10 @@ - + - + @@ -87,7 +88,7 @@ - + @@ -141,7 +140,7 @@ - + + +