diff --git a/Frameworks/Account/Feed.swift b/Frameworks/Account/Feed.swift index 4a14a43af..958b25106 100644 --- a/Frameworks/Account/Feed.swift +++ b/Frameworks/Account/Feed.swift @@ -20,3 +20,19 @@ public protocol Feed: FeedIdentifiable, ArticleFetcher, DisplayNameProvider, Unr var defaultReadFilterType: ReadFilterType { get } } + +public extension Feed { + + func readFiltered(readFilterEnabledTable: [FeedIdentifier: Bool]) -> Bool { + guard defaultReadFilterType != .alwaysRead else { + return true + } + if let feedID = feedID, let readFilterEnabled = readFilterEnabledTable[feedID] { + return readFilterEnabled + } else { + return defaultReadFilterType == .read + } + + } + +} diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index a73a34495..d3e6f8fb4 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -1129,19 +1129,19 @@ private extension TimelineViewController { func fetchUnsortedArticlesSync(for representedObjects: [Any]) -> Set
{ cancelPendingAsyncFetches() - let articleFetchers = representedObjects.compactMap{ $0 as? ArticleFetcher } - if articleFetchers.isEmpty { + let feeds = representedObjects.compactMap{ $0 as? Feed } + if feeds.isEmpty { return Set
() } var fetchedArticles = Set
() - for articleFetcher in articleFetchers { - if isReadFiltered ?? true { - if let articles = try? articleFetcher.fetchUnreadArticles() { + for feed in feeds { + if feed.readFiltered(readFilterEnabledTable: readFilterEnabledTable) { + if let articles = try? feed.fetchUnreadArticles() { fetchedArticles.formUnion(articles) } } else { - if let articles = try? articleFetcher.fetchArticles() { + if let articles = try? feed.fetchArticles() { fetchedArticles.formUnion(articles) } } @@ -1154,7 +1154,8 @@ private extension TimelineViewController { // if it’s been superseded by a newer fetch, or the timeline was emptied, etc., it won’t get called. precondition(Thread.isMainThread) cancelPendingAsyncFetches() - let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: isReadFiltered ?? true, representedObjects: representedObjects) { [weak self] (articles, operation) in + let feeds = representedObjects.compactMap { $0 as? Feed } + let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilterEnabledTable: readFilterEnabledTable, feeds: feeds) { [weak self] (articles, operation) in precondition(Thread.isMainThread) guard !operation.isCanceled, let strongSelf = self, operation.id == strongSelf.fetchSerialNumber else { return diff --git a/Shared/Timeline/FetchRequestOperation.swift b/Shared/Timeline/FetchRequestOperation.swift index ad3d0b729..e4b8cfbbd 100644 --- a/Shared/Timeline/FetchRequestOperation.swift +++ b/Shared/Timeline/FetchRequestOperation.swift @@ -19,17 +19,17 @@ typealias FetchRequestOperationResultBlock = (Set
, FetchRequestOperatio final class FetchRequestOperation { let id: Int - let readFilter: Bool + let readFilterEnabledTable: [FeedIdentifier: Bool] let resultBlock: FetchRequestOperationResultBlock var isCanceled = false var isFinished = false - private let representedObjects: [Any] + private let feeds: [Feed] - init(id: Int, readFilter: Bool, representedObjects: [Any], resultBlock: @escaping FetchRequestOperationResultBlock) { + init(id: Int, readFilterEnabledTable: [FeedIdentifier: Bool], feeds: [Feed], resultBlock: @escaping FetchRequestOperationResultBlock) { precondition(Thread.isMainThread) self.id = id - self.readFilter = readFilter - self.representedObjects = representedObjects + self.readFilterEnabledTable = readFilterEnabledTable + self.feeds = feeds self.resultBlock = resultBlock } @@ -51,15 +51,14 @@ final class FetchRequestOperation { return } - let articleFetchers = representedObjects.compactMap{ $0 as? ArticleFetcher } - if articleFetchers.isEmpty { + if feeds.isEmpty { isFinished = true resultBlock(Set
(), self) callCompletionIfNeeded() return } - let numberOfFetchers = articleFetchers.count + let numberOfFetchers = feeds.count var fetchersReturned = 0 var fetchedArticles = Set
() @@ -81,15 +80,15 @@ final class FetchRequestOperation { } } - for articleFetcher in articleFetchers { - if readFilter { - articleFetcher.fetchUnreadArticlesAsync { articleSetResult in + for feed in feeds { + if feed.readFiltered(readFilterEnabledTable: readFilterEnabledTable) { + feed.fetchUnreadArticlesAsync { articleSetResult in let articles = (try? articleSetResult.get()) ?? Set
() process(articles) } } else { - articleFetcher.fetchArticlesAsync { articleSetResult in + feed.fetchArticlesAsync { articleSetResult in let articles = (try? articleSetResult.get()) ?? Set
() process(articles) } diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index 2183cb4f5..0ad3a900d 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -1906,7 +1906,8 @@ private extension SceneCoordinator { precondition(Thread.isMainThread) cancelPendingAsyncFetches() - let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: isReadArticlesFiltered, representedObjects: representedObjects) { [weak self] (articles, operation) in + let feeds = representedObjects.compactMap { $0 as? Feed } + let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilterEnabledTable: readFilterEnabledTable, feeds: feeds) { [weak self] (articles, operation) in precondition(Thread.isMainThread) guard !operation.isCanceled, let strongSelf = self, operation.id == strongSelf.fetchSerialNumber else { return