Mark bottom items in feed as read after 2 seconds on Mac
In case markArticlesAsReadOnScroll is set
This commit is contained in:
parent
3b6a3cf4e7
commit
5364b4f384
@ -70,6 +70,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
if showsSearchResults {
|
if showsSearchResults {
|
||||||
fetchAndReplaceArticlesAsync()
|
fetchAndReplaceArticlesAsync()
|
||||||
} else {
|
} else {
|
||||||
|
resetMarkAsReadOnScroll()
|
||||||
fetchAndReplaceArticlesSync()
|
fetchAndReplaceArticlesSync()
|
||||||
if articles.count > 0 {
|
if articles.count > 0 {
|
||||||
tableView.scrollRowToVisible(0)
|
tableView.scrollRowToVisible(0)
|
||||||
@ -195,6 +196,8 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
private var timelineShowsSeparatorsObserver: NSKeyValueObservation?
|
private var timelineShowsSeparatorsObserver: NSKeyValueObservation?
|
||||||
|
|
||||||
private let scrollPositionQueue = CoalescingQueue(name: "Timeline Scroll Position", interval: 0.3, maxInterval: 1.0)
|
private let scrollPositionQueue = CoalescingQueue(name: "Timeline Scroll Position", interval: 0.3, maxInterval: 1.0)
|
||||||
|
|
||||||
|
private var markBottomArticlesAsReadWorkItem: DispatchWorkItem?
|
||||||
|
|
||||||
convenience init(delegate: TimelineDelegate) {
|
convenience init(delegate: TimelineDelegate) {
|
||||||
self.init(nibName: "TimelineTableView", bundle: nil)
|
self.init(nibName: "TimelineTableView", bundle: nil)
|
||||||
@ -292,6 +295,8 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func restoreState(from state: [AnyHashable : Any]) {
|
func restoreState(from state: [AnyHashable : Any]) {
|
||||||
|
resetMarkAsReadOnScroll()
|
||||||
|
|
||||||
guard let readArticlesFilterStateKeys = state[UserInfoKey.readArticlesFilterStateKeys] as? [[AnyHashable: AnyHashable]],
|
guard let readArticlesFilterStateKeys = state[UserInfoKey.readArticlesFilterStateKeys] as? [[AnyHashable: AnyHashable]],
|
||||||
let readArticlesFilterStateValues = state[UserInfoKey.readArticlesFilterStateValues] as? [Bool] else {
|
let readArticlesFilterStateValues = state[UserInfoKey.readArticlesFilterStateValues] as? [Bool] else {
|
||||||
return
|
return
|
||||||
@ -343,6 +348,32 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
if !AppDefaults.shared.markArticlesAsReadOnScroll {
|
if !AppDefaults.shared.markArticlesAsReadOnScroll {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark all articles as read when the bottom of the feed is reached
|
||||||
|
let lastRowIndex = articles.count - 1
|
||||||
|
let atBottom = tableView.rows(in: tableView.visibleRect).contains(lastRowIndex)
|
||||||
|
|
||||||
|
if atBottom && markBottomArticlesAsReadWorkItem == nil {
|
||||||
|
let task = DispatchWorkItem {
|
||||||
|
let articlesToMarkAsRead = self.articles.filter { !$0.status.read && !self.articlesWithManuallyChangedReadStatus.contains($0) }
|
||||||
|
|
||||||
|
if articlesToMarkAsRead.isEmpty { return }
|
||||||
|
guard let undoManager = self.undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articlesToMarkAsRead, markingRead: true, undoManager: undoManager) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.runCommand(markReadCommand)
|
||||||
|
self.markBottomArticlesAsReadWorkItem = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
markBottomArticlesAsReadWorkItem = task
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: task)
|
||||||
|
} else if !atBottom, let task = markBottomArticlesAsReadWorkItem {
|
||||||
|
task.cancel()
|
||||||
|
markBottomArticlesAsReadWorkItem = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mark articles scrolled out of sight at the top as read
|
||||||
let firstVisibleRowIndex = tableView.rows(in: tableView.visibleRect).location
|
let firstVisibleRowIndex = tableView.rows(in: tableView.visibleRect).location
|
||||||
let unreadArticlesScrolledAway = articles.articlesAbove(position: firstVisibleRowIndex).filter { !$0.status.read && !articlesWithManuallyChangedReadStatus.contains($0) }
|
let unreadArticlesScrolledAway = articles.articlesAbove(position: firstVisibleRowIndex).filter { !$0.status.read && !articlesWithManuallyChangedReadStatus.contains($0) }
|
||||||
|
|
||||||
@ -354,6 +385,11 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr
|
|||||||
runCommand(markReadCommand)
|
runCommand(markReadCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resetMarkAsReadOnScroll() {
|
||||||
|
articlesWithManuallyChangedReadStatus.removeAll()
|
||||||
|
markBottomArticlesAsReadWorkItem?.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@IBAction func toggleStatusOfSelectedArticles(_ sender: Any?) {
|
@IBAction func toggleStatusOfSelectedArticles(_ sender: Any?) {
|
||||||
guard !selectedArticles.isEmpty else {
|
guard !selectedArticles.isEmpty else {
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user