Improve scrolling performance with very large timelines. Reload visible cells only, and minimize the amount of looping through articles in the array.
This commit is contained in:
parent
9ad468781d
commit
3fdf8b3728
|
@ -50,20 +50,6 @@ extension Array where Element == Article {
|
|||
})
|
||||
}
|
||||
|
||||
func indexesForArticleIDs(_ articleIDs: Set<String>) -> IndexSet {
|
||||
|
||||
var indexes = IndexSet()
|
||||
|
||||
articleIDs.forEach { (articleID) in
|
||||
let oneIndex = rowForArticleID(articleID)
|
||||
if oneIndex != NSNotFound {
|
||||
indexes.insert(oneIndex)
|
||||
}
|
||||
}
|
||||
|
||||
return indexes
|
||||
}
|
||||
|
||||
func sortedByDate(_ sortDirection: ComparisonResult) -> ArticleArray {
|
||||
|
||||
let articles = sorted { (article1, article2) -> Bool in
|
||||
|
@ -118,19 +104,3 @@ extension Array where Element == Article {
|
|||
}
|
||||
}
|
||||
|
||||
private extension Array where Element == Article {
|
||||
|
||||
func rowForArticleID(_ articleID: String) -> Int {
|
||||
|
||||
if let index = index(where: { $0.articleID == articleID }) {
|
||||
return index
|
||||
}
|
||||
|
||||
return NSNotFound
|
||||
}
|
||||
|
||||
func rowForArticle(_ article: Article) -> Int {
|
||||
|
||||
return rowForArticleID(article.articleID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -361,7 +361,7 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
|
|||
guard let articles = note.userInfo?[Account.UserInfoKey.articles] as? Set<Article> else {
|
||||
return
|
||||
}
|
||||
reloadCellsForArticleIDs(articles.articleIDs())
|
||||
reloadVisibleCells(for: articles)
|
||||
}
|
||||
|
||||
@objc func feedIconDidBecomeAvailable(_ note: Notification) {
|
||||
|
@ -369,10 +369,15 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
|
|||
guard let feed = note.userInfo?[UserInfoKey.feed] as? Feed else {
|
||||
return
|
||||
}
|
||||
let articlesToReload = articles.filter { (article) -> Bool in
|
||||
let indexesToReload = tableView.indexesOfAvailableRowsPassingTest { (row) -> Bool in
|
||||
guard let article = articles.articleAtRow(row) else {
|
||||
return false
|
||||
}
|
||||
return feed == article.feed
|
||||
}
|
||||
reloadCellsForArticles(articlesToReload)
|
||||
if let indexesToReload = indexesToReload {
|
||||
reloadCells(for: indexesToReload)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func avatarDidBecomeAvailable(_ note: Notification) {
|
||||
|
@ -432,22 +437,32 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
|
|||
return nil
|
||||
}
|
||||
|
||||
private func reloadCellsForArticles(_ articles: [Article]) {
|
||||
|
||||
reloadCellsForArticleIDs(Set(articles.articleIDs()))
|
||||
private func reloadVisibleCells(for articles: [Article]) {
|
||||
reloadVisibleCells(for: Set(articles.articleIDs()))
|
||||
}
|
||||
|
||||
private func reloadVisibleCells(for articles: Set<Article>) {
|
||||
reloadVisibleCells(for: articles.articleIDs())
|
||||
}
|
||||
|
||||
private func reloadCellsForArticleIDs(_ articleIDs: Set<String>) {
|
||||
|
||||
private func reloadVisibleCells(for articleIDs: Set<String>) {
|
||||
if articleIDs.isEmpty {
|
||||
return
|
||||
}
|
||||
let indexes = articles.indexesForArticleIDs(articleIDs)
|
||||
reloadCells(for: indexes)
|
||||
let indexes = indexesForArticleIDs(articleIDs)
|
||||
reloadVisibleCells(for: indexes)
|
||||
}
|
||||
|
||||
private func reloadVisibleCells(for indexes: IndexSet) {
|
||||
let indexesToReload = tableView.indexesOfAvailableRowsPassingTest { (row) -> Bool in
|
||||
return indexes.contains(row)
|
||||
}
|
||||
if let indexesToReload = indexesToReload {
|
||||
reloadCells(for: indexesToReload)
|
||||
}
|
||||
}
|
||||
|
||||
private func reloadCells(for indexes: IndexSet) {
|
||||
|
||||
if indexes.isEmpty {
|
||||
return
|
||||
}
|
||||
|
@ -776,7 +791,7 @@ private extension TimelineViewController {
|
|||
|
||||
func selectArticles(_ articleIDs: [String]) {
|
||||
|
||||
let indexesToSelect = articles.indexesForArticleIDs(Set(articleIDs))
|
||||
let indexesToSelect = indexesForArticleIDs(Set(articleIDs))
|
||||
if indexesToSelect.isEmpty {
|
||||
tableView.deselectAll(self)
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue