Implement mark-everywhere-as-read.

This commit is contained in:
Brent Simmons 2017-11-19 16:28:26 -08:00
parent 9c2dd9251f
commit ffaa55c50c
8 changed files with 76 additions and 2 deletions

View File

@ -86,6 +86,28 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
panicButtonWindowController!.runSheetOnWindow(window)
}
func markEverywhereAsRead(with window: NSWindow) {
let alert = NSAlert()
alert.messageText = NSLocalizedString("Mark All Articles as Read Everywhere?", comment: "Mark Everywhere alert messageText")
alert.informativeText = NSLocalizedString("This will mark every single article as read. All of them. The unread count will be zero.\n\nNote: this operation cannot be undone.", comment: "Mark Everywhere informativeText.")
alert.addButton(withTitle: NSLocalizedString("Mark All Articles as Read", comment: "Mark Everywhere alert button."))
alert.addButton(withTitle: NSLocalizedString("Dont Mark as Read", comment: "Mark Everywhere alert button."))
alert.beginSheetModal(for: window) { (returnCode) in
if returnCode == .alertFirstButtonReturn {
self.markEverywhereAsRead()
}
}
}
func markEverywhereAsRead() {
AccountManager.shared.accounts.forEach { $0.markEverywhereAsRead() }
}
// MARK: - NSApplicationDelegate
func applicationDidFinishLaunching(_ note: Notification) {
@ -377,6 +399,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
createAndShowMainWindow()
markOlderArticlesAsRead(with: mainWindowController!.window!)
}
@IBAction func markEverywhereAsRead(_ sender: Any?) {
createAndShowMainWindow()
markEverywhereAsRead(with: mainWindowController!.window!)
}
}
private extension AppDelegate {

View File

@ -438,6 +438,9 @@
</menuItem>
<menuItem title="Mark All Everywhere as Read…" id="vfn-M4-V9E">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="markEverywhereAsRead:" target="Ady-hI-5gd" id="Sq7-ak-Jaa"/>
</connections>
</menuItem>
</items>
</menu>

View File

@ -164,6 +164,11 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
appDelegate.markOlderArticlesAsRead(with: window!)
}
@IBAction func markEverywhereAsRead(_ sender: Any?) {
appDelegate.markEverywhereAsRead(with: window!)
}
}
// MARK: - Private

View File

@ -88,7 +88,7 @@ private extension SmartFeed {
timer = nil
}
private static let fetchCoalescingDelay: TimeInterval = 0.2
private static let fetchCoalescingDelay: TimeInterval = 0.1
func startTimer() {

View File

@ -335,6 +335,14 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
database.fetchStarredAndUnreadCount(for: flattenedFeeds(), callback: callback)
}
public func markEverywhereAsRead() {
// Does not support undo.
database.markEverywhereAsRead()
flattenedFeeds().forEach { $0.unreadCount = 0 }
}
// MARK: - Notifications
@objc func downloadProgressDidChange(_ note: Notification) {

View File

@ -187,6 +187,11 @@ final class ArticlesTable: DatabaseTable {
return statusesTable.mark(articles.statuses(), statusKey, flag)
}
func markEverywhereAsRead() {
return statusesTable.markEverywhereAsRead()
}
}
// MARK: - Private

View File

@ -84,5 +84,10 @@ public final class Database {
return articlesTable.mark(articles, statusKey, flag)
}
public func markEverywhereAsRead() {
articlesTable.markEverywhereAsRead()
}
}

View File

@ -76,6 +76,20 @@ final class StatusesTable: DatabaseTable {
return updatedStatuses
}
func markEverywhereAsRead() {
queue.update { (database) in
let _ = database.executeUpdate("update statuses set read=1;", withArgumentsIn: nil)
let cachedStatuses = self.cache.cachedStatuses
DispatchQueue.main.async {
cachedStatuses.forEach { $0.read = true }
}
}
}
// MARK: Fetching
func statusWithRow(_ row: FMResultSet) -> ArticleStatus? {
@ -164,6 +178,11 @@ private final class StatusCache {
// Serial database queue only.
var dictionary = [String: ArticleStatus]()
var cachedStatuses: Set<ArticleStatus> {
get {
return Set(dictionary.values)
}
}
func add(_ statuses: Set<ArticleStatus>) {
@ -191,7 +210,7 @@ private final class StatusCache {
self[articleID] = status
}
}
subscript(_ articleID: String) -> ArticleStatus? {
get {
return dictionary[articleID]