Persist and restore per window per feed timeline filter state.
This commit is contained in:
parent
ae8f36d300
commit
ceef6116f9
@ -849,7 +849,7 @@ private extension MainWindowController {
|
|||||||
menuItem.title = isReadFiltered ? showCommand : hideCommand
|
menuItem.title = isReadFiltered ? showCommand : hideCommand
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
menuItem.title = hideCommand
|
menuItem.title = showCommand
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,19 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
|
|
||||||
@IBOutlet var tableView: TimelineTableView!
|
@IBOutlet var tableView: TimelineTableView!
|
||||||
|
|
||||||
private var articleReadFilterType: ReadFilterType?
|
private var readFilterEnabledTable = [FeedIdentifier: Bool]()
|
||||||
var isReadFiltered: Bool? {
|
var isReadFiltered: Bool? {
|
||||||
guard let articleReadFilterType = articleReadFilterType, articleReadFilterType != .alwaysRead else { return nil}
|
guard representedObjects?.count == 1, let timelineFeed = representedObjects?.first as? Feed else {
|
||||||
return articleReadFilterType != .none
|
return nil
|
||||||
|
}
|
||||||
|
guard timelineFeed.defaultReadFilterType != .alwaysRead else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if let feedID = timelineFeed.feedID, let readFilterEnabled = readFilterEnabledTable[feedID] {
|
||||||
|
return readFilterEnabled
|
||||||
|
} else {
|
||||||
|
return timelineFeed.defaultReadFilterType == .read
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var representedObjects: [AnyObject]? {
|
var representedObjects: [AnyObject]? {
|
||||||
@ -44,7 +53,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
showFeedNames = false
|
showFeedNames = false
|
||||||
}
|
}
|
||||||
|
|
||||||
determineReadFilterType()
|
|
||||||
selectionDidChange(nil)
|
selectionDidChange(nil)
|
||||||
if showsSearchResults {
|
if showsSearchResults {
|
||||||
fetchAndReplaceArticlesAsync()
|
fetchAndReplaceArticlesAsync()
|
||||||
@ -224,16 +232,9 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toggleReadFilter() {
|
func toggleReadFilter() {
|
||||||
guard let filterType = articleReadFilterType else { return }
|
guard let filter = isReadFiltered, let feedID = (representedObjects?.first as? Feed)?.feedID else { return }
|
||||||
|
readFilterEnabledTable[feedID] = !filter
|
||||||
switch filterType {
|
delegate?.timelineInvalidatedRestorationState(self)
|
||||||
case .alwaysRead:
|
|
||||||
break
|
|
||||||
case .read:
|
|
||||||
articleReadFilterType = ReadFilterType.none
|
|
||||||
case .none:
|
|
||||||
articleReadFilterType = ReadFilterType.read
|
|
||||||
}
|
|
||||||
|
|
||||||
if let article = oneSelectedArticle, let account = article.account {
|
if let article = oneSelectedArticle, let account = article.account {
|
||||||
exceptionArticleFetcher = SingleArticleFetcher(account: account, articleID: article.articleID)
|
exceptionArticleFetcher = SingleArticleFetcher(account: account, articleID: article.articleID)
|
||||||
@ -247,11 +248,21 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
// MARK: State Restoration
|
// MARK: State Restoration
|
||||||
|
|
||||||
func saveState(to coder: NSCoder) {
|
func saveState(to coder: NSCoder) {
|
||||||
|
var readArticlesFilterState = [[AnyHashable: AnyHashable]: Bool]()
|
||||||
|
for key in readFilterEnabledTable.keys {
|
||||||
|
readArticlesFilterState[key.userInfo] = readFilterEnabledTable[key]
|
||||||
|
}
|
||||||
|
coder.encode(readArticlesFilterState, forKey: UserInfoKey.readArticlesFilterState)
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreState(from coder: NSCoder) {
|
func restoreState(from coder: NSCoder) {
|
||||||
|
if let readArticlesFilterState = try? coder.decodeTopLevelObject(forKey: UserInfoKey.readArticlesFilterState) as? [[AnyHashable: AnyHashable]: Bool] {
|
||||||
|
for key in readArticlesFilterState.keys {
|
||||||
|
if let feedIdentifier = FeedIdentifier(userInfo: key) {
|
||||||
|
readFilterEnabledTable[feedIdentifier] = readArticlesFilterState[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Actions
|
// MARK: - Actions
|
||||||
@ -1006,14 +1017,6 @@ private extension TimelineViewController {
|
|||||||
|
|
||||||
// MARK: - Fetching Articles
|
// MARK: - Fetching Articles
|
||||||
|
|
||||||
func determineReadFilterType() {
|
|
||||||
if representedObjects?.count ?? 0 == 1, let feed = representedObjects?.first as? Feed {
|
|
||||||
articleReadFilterType = feed.defaultReadFilterType
|
|
||||||
} else {
|
|
||||||
articleReadFilterType = .read
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchAndReplaceArticlesSync() {
|
func fetchAndReplaceArticlesSync() {
|
||||||
// To be called when the user has made a change of selection in the sidebar.
|
// To be called when the user has made a change of selection in the sidebar.
|
||||||
// It blocks the main thread, so that there’s no async delay,
|
// It blocks the main thread, so that there’s no async delay,
|
||||||
@ -1071,7 +1074,7 @@ private extension TimelineViewController {
|
|||||||
|
|
||||||
var fetchedArticles = Set<Article>()
|
var fetchedArticles = Set<Article>()
|
||||||
for articleFetcher in articleFetchers {
|
for articleFetcher in articleFetchers {
|
||||||
if articleReadFilterType != ReadFilterType.none {
|
if isReadFiltered ?? true {
|
||||||
if let articles = try? articleFetcher.fetchUnreadArticles() {
|
if let articles = try? articleFetcher.fetchUnreadArticles() {
|
||||||
fetchedArticles.formUnion(articles)
|
fetchedArticles.formUnion(articles)
|
||||||
}
|
}
|
||||||
@ -1089,8 +1092,7 @@ private extension TimelineViewController {
|
|||||||
// if it’s been superseded by a newer fetch, or the timeline was emptied, etc., it won’t get called.
|
// if it’s been superseded by a newer fetch, or the timeline was emptied, etc., it won’t get called.
|
||||||
precondition(Thread.isMainThread)
|
precondition(Thread.isMainThread)
|
||||||
cancelPendingAsyncFetches()
|
cancelPendingAsyncFetches()
|
||||||
let readFilter = articleReadFilterType != ReadFilterType.none
|
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: isReadFiltered ?? true, representedObjects: representedObjects) { [weak self] (articles, operation) in
|
||||||
let fetchOperation = FetchRequestOperation(id: fetchSerialNumber, readFilter: readFilter, 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user