Make progress on the star/unstar command and on updating its toolbar item.

This commit is contained in:
Brent Simmons 2018-02-16 22:35:04 -08:00
parent e1a51b8acd
commit 1603d0b3f2
3 changed files with 86 additions and 2 deletions

View File

@ -134,7 +134,7 @@
</buttonCell> </buttonCell>
</button> </button>
<connections> <connections>
<action selector="markRead:" target="Oky-zY-oP4" id="fYI-jM-htG"/> <action selector="toggleStarred:" target="Oky-zY-oP4" id="44J-UK-89l"/>
</connections> </connections>
</toolbarItem> </toolbarItem>
<toolbarItem implicitItemIdentifier="4DED27B7-8961-48F3-A995-9C961E2C0257" label="Open in Browser" paletteLabel="Open in Browser" toolTip="Open in Browser" image="openInBrowser" id="tid-SB-me3" customClass="RSToolbarItem" customModule="RSCore"> <toolbarItem implicitItemIdentifier="4DED27B7-8961-48F3-A995-9C961E2C0257" label="Open in Browser" paletteLabel="Open in Browser" toolTip="Open in Browser" image="openInBrowser" id="tid-SB-me3" customClass="RSToolbarItem" customModule="RSCore">

View File

@ -12,6 +12,11 @@ import Account
private let kWindowFrameKey = "MainWindow" private let kWindowFrameKey = "MainWindow"
extension NSImage.Name {
static let star = NSImage.Name(rawValue: "star")
static let unstar = NSImage.Name(rawValue: "unstar")
}
class MainWindowController : NSWindowController, NSUserInterfaceValidations { class MainWindowController : NSWindowController, NSUserInterfaceValidations {
var isOpen: Bool { var isOpen: Bool {
@ -152,6 +157,10 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
return canMarkRead() return canMarkRead()
} }
if item.action == #selector(toggleStarred(_:)) {
return validateToggleStarred(item)
}
if item.action == #selector(markOlderArticlesAsRead(_:)) { if item.action == #selector(markOlderArticlesAsRead(_:)) {
return canMarkOlderArticlesAsRead() return canMarkOlderArticlesAsRead()
} }
@ -178,6 +187,31 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
return true return true
} }
private func validateToggleStarred(_ item: NSValidatedUserInterfaceItem) -> Bool {
let validationStatus = timelineViewController?.markStarredCommandStatus() ?? .canDoNothing
let showStar: Bool
let result: Bool
switch validationStatus {
case .canMark:
showStar = true
result = true
case .canUnmark:
showStar = false
result = true
case .canDoNothing:
showStar = true
result = false
}
if let button = (item as? NSToolbarItem)?.view as? NSButton {
button.image = NSImage(named: showStar ? .star : .unstar)
}
return result
}
// MARK: - Actions // MARK: - Actions
@IBAction func scrollOrGoToNextUnread(_ sender: Any?) { @IBAction func scrollOrGoToNextUnread(_ sender: Any?) {
@ -267,6 +301,11 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
timelineViewController?.markSelectedArticlesAsUnread(sender) timelineViewController?.markSelectedArticlesAsUnread(sender)
} }
@IBAction func toggleStarred(_ sender: Any?) {
timelineViewController?.toggleStarredStatusForSelectedArticles()
}
@IBAction func markAllAsReadAndGoToNextUnread(_ sender: Any?) { @IBAction func markAllAsReadAndGoToNextUnread(_ sender: Any?) {
markAllAsRead(sender) markAllAsRead(sender)

View File

@ -12,6 +12,19 @@ import RSTextDrawing
import Data import Data
import Account import Account
enum MarkCommandValidationStatus {
case canMark, canUnmark, canDoNothing
static func statusFor(_ articles: ArticleArray, _ canMarkTest: ((ArticleArray) -> Bool)) -> MarkCommandValidationStatus {
if articles.isEmpty {
return .canDoNothing
}
return canMarkTest(articles) ? .canMark : .canUnmark
}
}
class TimelineViewController: NSViewController, UndoableCommandRunner { class TimelineViewController: NSViewController, UndoableCommandRunner {
@IBOutlet var tableView: TimelineTableView! @IBOutlet var tableView: TimelineTableView!
@ -191,7 +204,7 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
markSelectedArticlesAsUnread(sender) markSelectedArticlesAsUnread(sender)
} }
} }
@IBAction func markSelectedArticlesAsRead(_ sender: Any?) { @IBAction func markSelectedArticlesAsRead(_ sender: Any?) {
guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: selectedArticles, markingRead: true, undoManager: undoManager) else { guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: selectedArticles, markingRead: true, undoManager: undoManager) else {
@ -213,6 +226,38 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
NSPasteboard.general.copyObjects(selectedArticles) NSPasteboard.general.copyObjects(selectedArticles)
} }
func toggleStarredStatusForSelectedArticles() {
// If any one of the selected articles is not starred, then star them.
// If all articles are starred, then unstar them.
let commandStatus = markStarredCommandStatus()
let starring: Bool
switch commandStatus {
case .canMark:
starring = true
case .canUnmark:
starring = false
case .canDoNothing:
return
}
guard let undoManager = undoManager, let markStarredCommand = MarkStatusCommand(initialArticles: selectedArticles, markingStarred: starring, undoManager: undoManager) else {
return
}
runCommand(markStarredCommand)
}
func markStarredCommandStatus() -> MarkCommandValidationStatus {
return MarkCommandValidationStatus.statusFor(selectedArticles) { $0.anyArticleIsUnstarred() }
}
func markReadCommandStatus() -> MarkCommandValidationStatus {
return MarkCommandValidationStatus.statusFor(selectedArticles) { $0.anyArticleIsUnread() }
}
func markOlderArticlesAsRead() { func markOlderArticlesAsRead() {
// Mark articles the same age or older than the selected article(s) as read. // Mark articles the same age or older than the selected article(s) as read.