Use the fetch filter option to speed up timeline rendering

This commit is contained in:
Maurice Parker 2020-07-18 16:12:10 -05:00
parent 6a33060473
commit 3899fe7fd9
1 changed files with 8 additions and 22 deletions

View File

@ -91,10 +91,11 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
self?.groupByFeed = AppDefaults.shared.timelineGroupByFeed self?.groupByFeed = AppDefaults.shared.timelineGroupByFeed
}.store(in: &cancellables) }.store(in: &cancellables)
// TODO: This should be rewritten to use Combine correctly // TODO: This should be rewritten to use Combine correctly (including fixing the read filter toggle to work as a published bool)
delegate?.selectedFeeds.sink { [weak self] feeds in delegate?.selectedFeeds.sink { [weak self] feeds in
guard let self = self else { return } guard let self = self else { return }
self.fetchArticles(feeds: feeds) self.feeds = feeds
self.fetchArticles()
}.store(in: &cancellables) }.store(in: &cancellables)
// TODO: This should be rewritten to use Combine correctly // TODO: This should be rewritten to use Combine correctly
@ -128,7 +129,7 @@ class TimelineModel: ObservableObject, UndoableCommandRunner {
guard let filter = isReadFiltered, let feedID = feeds.first?.feedID else { return } guard let filter = isReadFiltered, let feedID = feeds.first?.feedID else { return }
readFilterEnabledTable[feedID] = !filter readFilterEnabledTable[feedID] = !filter
isReadFiltered = !filter isReadFiltered = !filter
rebuildTimelineItems() self.fetchArticles()
} }
func toggleReadStatusForSelectedArticles() { func toggleReadStatusForSelectedArticles() {
@ -378,9 +379,7 @@ private extension TimelineModel {
// MARK: Article Fetching // MARK: Article Fetching
func fetchArticles(feeds: [Feed]) { func fetchArticles() {
self.feeds = feeds
if feeds.count == 1 { if feeds.count == 1 {
nameForDisplay = feeds.first!.nameForDisplay nameForDisplay = feeds.first!.nameForDisplay
} else { } else {
@ -414,12 +413,8 @@ private extension TimelineModel {
precondition(Thread.isMainThread) precondition(Thread.isMainThread)
cancelPendingAsyncFetches() cancelPendingAsyncFetches()
// Right now we are pulling all the records and filtering them in the UI. This is because the async let filtered = isReadFiltered ?? false
// change of the timeline times doesn't trigger an animation because it isn't in a withAnimation block. let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: filtered, representedObjects: representedObjects) { [weak self] (articles, operation) in
// Ideally this would be done in the database tier with a query, but if you look, we always pull everything
// from SQLite and filter it programmatically at that level currently. So no big deal.
// We should change this as soon as we figure out how to trigger animations on Lists with async tasks.
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: false, representedObjects: representedObjects) { [weak self] (articles, operation) in
precondition(Thread.isMainThread) precondition(Thread.isMainThread)
guard !operation.isCanceled, let strongSelf = self, operation.id == strongSelf.fetchSerialNumber else { guard !operation.isCanceled, let strongSelf = self, operation.id == strongSelf.fetchSerialNumber else {
return return
@ -439,16 +434,7 @@ private extension TimelineModel {
} }
func rebuildTimelineItems() { func rebuildTimelineItems() {
let filtered = isReadFiltered ?? false timelineItems = articles.map { TimelineItem(article: $0) }
let selectedArticleIDs = selectedArticles.map { $0.articleID }
timelineItems = articles.compactMap { article in
if filtered && article.status.read && !selectedArticleIDs.contains(article.articleID) {
return nil
} else {
return TimelineItem(article: article)
}
}
} }
} }