Filter async requests based on ReadFilter.

This commit is contained in:
Maurice Parker 2019-11-21 19:54:35 -06:00
parent adbb5b6392
commit 6d8fca01ea
8 changed files with 49 additions and 28 deletions

View File

@ -11,8 +11,8 @@ import RSCore
public enum ReadFilter {
case read
case all
case none
case unavailable
}
public protocol Feed: FeedIdentifiable, ArticleFetcher, DisplayNameProvider, UnreadCountProvider {

View File

@ -14,7 +14,7 @@ import Articles
public final class WebFeed: Feed, Renamable, Hashable {
public var defaultReadFilter: ReadFilter {
return .all
return .none
}
public var feedID: FeedIdentifier? {

View File

@ -1000,7 +1000,7 @@ private extension TimelineViewController {
// if its been superseded by a newer fetch, or the timeline was emptied, etc., it wont get called.
precondition(Thread.isMainThread)
cancelPendingAsyncFetches()
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, representedObjects: representedObjects) { [weak self] (articles, operation) in
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: .none, representedObjects: representedObjects) { [weak self] (articles, operation) in
precondition(Thread.isMainThread)
guard !operation.isCanceled, let strongSelf = self, operation.id == strongSelf.fetchSerialNumber else {
return

View File

@ -14,7 +14,7 @@ import Account
final class SmartFeed: PseudoFeed {
public var defaultReadFilter: ReadFilter {
return .all
return .none
}
var feedID: FeedIdentifier? {

View File

@ -20,7 +20,7 @@ import Articles
final class UnreadFeed: PseudoFeed {
public var defaultReadFilter: ReadFilter {
return .none
return .unavailable
}
var feedID: FeedIdentifier? {

View File

@ -19,14 +19,16 @@ typealias FetchRequestOperationResultBlock = (Set<Article>, FetchRequestOperatio
final class FetchRequestOperation {
let id: Int
let readFilter: ReadFilter
let resultBlock: FetchRequestOperationResultBlock
var isCanceled = false
var isFinished = false
private let representedObjects: [Any]
init(id: Int, representedObjects: [Any], resultBlock: @escaping FetchRequestOperationResultBlock) {
init(id: Int, readFilter: ReadFilter, representedObjects: [Any], resultBlock: @escaping FetchRequestOperationResultBlock) {
precondition(Thread.isMainThread)
self.id = id
self.readFilter = readFilter
self.representedObjects = representedObjects
self.resultBlock = resultBlock
}
@ -60,25 +62,38 @@ final class FetchRequestOperation {
let numberOfFetchers = articleFetchers.count
var fetchersReturned = 0
var fetchedArticles = Set<Article>()
for articleFetcher in articleFetchers {
articleFetcher.fetchArticlesAsync { (articles) in
precondition(Thread.isMainThread)
guard !self.isCanceled else {
callCompletionIfNeeded()
return
}
assert(!self.isFinished)
func process(articles: Set<Article>) {
precondition(Thread.isMainThread)
guard !self.isCanceled else {
callCompletionIfNeeded()
return
}
assert(!self.isFinished)
fetchedArticles.formUnion(articles)
fetchersReturned += 1
if fetchersReturned == numberOfFetchers {
self.isFinished = true
self.resultBlock(fetchedArticles, self)
callCompletionIfNeeded()
fetchedArticles.formUnion(articles)
fetchersReturned += 1
if fetchersReturned == numberOfFetchers {
self.isFinished = true
self.resultBlock(fetchedArticles, self)
callCompletionIfNeeded()
}
}
for articleFetcher in articleFetchers {
if readFilter == .read {
articleFetcher.fetchUnreadArticlesAsync { (articles) in
process(articles: articles)
}
} else {
articleFetcher.fetchArticlesAsync { (articles) in
process(articles: articles)
}
}
}
}
}

View File

@ -90,7 +90,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
// MARK: Actions
@IBAction func toggleFilter(_ sender: Any) {
switch coordinator.articleReadFilter {
case .all:
case .none:
filterButton.image = AppAssets.filterActiveImage
coordinator.hideUnreadArticles()
case .read:
@ -497,7 +497,7 @@ private extension MasterTimelineViewController {
}
switch coordinator.articleReadFilter {
case .all:
case .none:
filterButton.isHidden = false
filterButton.image = AppAssets.filterInactiveImage
case .read:
@ -548,7 +548,7 @@ private extension MasterTimelineViewController {
self?.configure(cell, article: article)
return cell
})
dataSource.defaultRowAnimation = .left
dataSource.defaultRowAnimation = .middle
return dataSource
}

View File

@ -116,7 +116,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
return treeControllerDelegate.isUnreadFiltered
}
var articleReadFilter: ReadFilter = .all
var articleReadFilter: ReadFilter = .none
var rootNode: Node {
return treeController.rootNode
@ -473,11 +473,17 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
func showAllArticles() {
articleReadFilter = .all
articleReadFilter = .none
fetchAndReplaceArticlesAsync {
self.rebuildBackingStores()
}
}
func hideUnreadArticles() {
articleReadFilter = .read
fetchAndReplaceArticlesAsync {
self.rebuildBackingStores()
}
}
func expand(_ node: Node) {
@ -1139,7 +1145,7 @@ private extension SceneCoordinator {
func setTimelineFeed(_ feed: Feed?, completion: (() -> Void)? = nil) {
timelineFeed = feed
timelineMiddleIndexPath = nil
articleReadFilter = feed?.defaultReadFilter ?? .all
articleReadFilter = feed?.defaultReadFilter ?? .none
fetchAndReplaceArticlesAsync {
self.masterTimelineViewController?.reinitializeArticles()
@ -1480,7 +1486,7 @@ private extension SceneCoordinator {
precondition(Thread.isMainThread)
cancelPendingAsyncFetches()
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, representedObjects: representedObjects) { [weak self] (articles, operation) in
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: articleReadFilter, representedObjects: representedObjects) { [weak self] (articles, operation) in
precondition(Thread.isMainThread)
guard !operation.isCanceled, let strongSelf = self, operation.id == strongSelf.fetchSerialNumber else {
return