diff --git a/Evergreen/AppDelegate.swift b/Evergreen/AppDelegate.swift
index 8267b949c..6d7744d77 100644
--- a/Evergreen/AppDelegate.swift
+++ b/Evergreen/AppDelegate.swift
@@ -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("Don’t 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 {
diff --git a/Evergreen/Base.lproj/Main.storyboard b/Evergreen/Base.lproj/Main.storyboard
index 1a31ca9c3..c1237e996 100644
--- a/Evergreen/Base.lproj/Main.storyboard
+++ b/Evergreen/Base.lproj/Main.storyboard
@@ -438,6 +438,9 @@
diff --git a/Evergreen/MainWindow/MainWindowController.swift b/Evergreen/MainWindow/MainWindowController.swift
index 33a7487c6..26214a4b1 100644
--- a/Evergreen/MainWindow/MainWindowController.swift
+++ b/Evergreen/MainWindow/MainWindowController.swift
@@ -164,6 +164,11 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
appDelegate.markOlderArticlesAsRead(with: window!)
}
+
+ @IBAction func markEverywhereAsRead(_ sender: Any?) {
+
+ appDelegate.markEverywhereAsRead(with: window!)
+ }
}
// MARK: - Private
diff --git a/Evergreen/PseudoFeeds/SmartFeed.swift b/Evergreen/PseudoFeeds/SmartFeed.swift
index 8635b5a53..e623399b0 100644
--- a/Evergreen/PseudoFeeds/SmartFeed.swift
+++ b/Evergreen/PseudoFeeds/SmartFeed.swift
@@ -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() {
diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift
index 034db558b..dcdee16ed 100644
--- a/Frameworks/Account/Account.swift
+++ b/Frameworks/Account/Account.swift
@@ -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) {
diff --git a/Frameworks/Database/ArticlesTable.swift b/Frameworks/Database/ArticlesTable.swift
index 1f0d8eb0f..7d6bd1af1 100644
--- a/Frameworks/Database/ArticlesTable.swift
+++ b/Frameworks/Database/ArticlesTable.swift
@@ -187,6 +187,11 @@ final class ArticlesTable: DatabaseTable {
return statusesTable.mark(articles.statuses(), statusKey, flag)
}
+
+ func markEverywhereAsRead() {
+
+ return statusesTable.markEverywhereAsRead()
+ }
}
// MARK: - Private
diff --git a/Frameworks/Database/Database.swift b/Frameworks/Database/Database.swift
index 2365274bf..c312cce2e 100644
--- a/Frameworks/Database/Database.swift
+++ b/Frameworks/Database/Database.swift
@@ -84,5 +84,10 @@ public final class Database {
return articlesTable.mark(articles, statusKey, flag)
}
+
+ public func markEverywhereAsRead() {
+
+ articlesTable.markEverywhereAsRead()
+ }
}
diff --git a/Frameworks/Database/StatusesTable.swift b/Frameworks/Database/StatusesTable.swift
index bda6a63d4..421911294 100644
--- a/Frameworks/Database/StatusesTable.swift
+++ b/Frameworks/Database/StatusesTable.swift
@@ -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 {
+ get {
+ return Set(dictionary.values)
+ }
+ }
func add(_ statuses: Set) {
@@ -191,7 +210,7 @@ private final class StatusCache {
self[articleID] = status
}
}
-
+
subscript(_ articleID: String) -> ArticleStatus? {
get {
return dictionary[articleID]