Implement mark-everywhere-as-read.
This commit is contained in:
parent
9c2dd9251f
commit
ffaa55c50c
@ -86,6 +86,28 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||||||
panicButtonWindowController!.runSheetOnWindow(window)
|
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
|
// MARK: - NSApplicationDelegate
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ note: Notification) {
|
func applicationDidFinishLaunching(_ note: Notification) {
|
||||||
@ -377,6 +399,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||||||
createAndShowMainWindow()
|
createAndShowMainWindow()
|
||||||
markOlderArticlesAsRead(with: mainWindowController!.window!)
|
markOlderArticlesAsRead(with: mainWindowController!.window!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func markEverywhereAsRead(_ sender: Any?) {
|
||||||
|
|
||||||
|
createAndShowMainWindow()
|
||||||
|
markEverywhereAsRead(with: mainWindowController!.window!)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension AppDelegate {
|
private extension AppDelegate {
|
||||||
|
@ -438,6 +438,9 @@
|
|||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Mark All Everywhere as Read…" id="vfn-M4-V9E">
|
<menuItem title="Mark All Everywhere as Read…" id="vfn-M4-V9E">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="markEverywhereAsRead:" target="Ady-hI-5gd" id="Sq7-ak-Jaa"/>
|
||||||
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -164,6 +164,11 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
|
|||||||
|
|
||||||
appDelegate.markOlderArticlesAsRead(with: window!)
|
appDelegate.markOlderArticlesAsRead(with: window!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction func markEverywhereAsRead(_ sender: Any?) {
|
||||||
|
|
||||||
|
appDelegate.markEverywhereAsRead(with: window!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
@ -88,7 +88,7 @@ private extension SmartFeed {
|
|||||||
timer = nil
|
timer = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private static let fetchCoalescingDelay: TimeInterval = 0.2
|
private static let fetchCoalescingDelay: TimeInterval = 0.1
|
||||||
|
|
||||||
func startTimer() {
|
func startTimer() {
|
||||||
|
|
||||||
|
@ -335,6 +335,14 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||||||
database.fetchStarredAndUnreadCount(for: flattenedFeeds(), callback: callback)
|
database.fetchStarredAndUnreadCount(for: flattenedFeeds(), callback: callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func markEverywhereAsRead() {
|
||||||
|
|
||||||
|
// Does not support undo.
|
||||||
|
|
||||||
|
database.markEverywhereAsRead()
|
||||||
|
flattenedFeeds().forEach { $0.unreadCount = 0 }
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Notifications
|
// MARK: - Notifications
|
||||||
|
|
||||||
@objc func downloadProgressDidChange(_ note: Notification) {
|
@objc func downloadProgressDidChange(_ note: Notification) {
|
||||||
|
@ -187,6 +187,11 @@ final class ArticlesTable: DatabaseTable {
|
|||||||
|
|
||||||
return statusesTable.mark(articles.statuses(), statusKey, flag)
|
return statusesTable.mark(articles.statuses(), statusKey, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func markEverywhereAsRead() {
|
||||||
|
|
||||||
|
return statusesTable.markEverywhereAsRead()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
@ -84,5 +84,10 @@ public final class Database {
|
|||||||
|
|
||||||
return articlesTable.mark(articles, statusKey, flag)
|
return articlesTable.mark(articles, statusKey, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func markEverywhereAsRead() {
|
||||||
|
|
||||||
|
articlesTable.markEverywhereAsRead()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,20 @@ final class StatusesTable: DatabaseTable {
|
|||||||
return updatedStatuses
|
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
|
// MARK: Fetching
|
||||||
|
|
||||||
func statusWithRow(_ row: FMResultSet) -> ArticleStatus? {
|
func statusWithRow(_ row: FMResultSet) -> ArticleStatus? {
|
||||||
@ -164,6 +178,11 @@ private final class StatusCache {
|
|||||||
// Serial database queue only.
|
// Serial database queue only.
|
||||||
|
|
||||||
var dictionary = [String: ArticleStatus]()
|
var dictionary = [String: ArticleStatus]()
|
||||||
|
var cachedStatuses: Set<ArticleStatus> {
|
||||||
|
get {
|
||||||
|
return Set(dictionary.values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func add(_ statuses: Set<ArticleStatus>) {
|
func add(_ statuses: Set<ArticleStatus>) {
|
||||||
|
|
||||||
@ -191,7 +210,7 @@ private final class StatusCache {
|
|||||||
self[articleID] = status
|
self[articleID] = status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subscript(_ articleID: String) -> ArticleStatus? {
|
subscript(_ articleID: String) -> ArticleStatus? {
|
||||||
get {
|
get {
|
||||||
return dictionary[articleID]
|
return dictionary[articleID]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user