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>
</button>
<connections>
<action selector="markRead:" target="Oky-zY-oP4" id="fYI-jM-htG"/>
<action selector="toggleStarred:" target="Oky-zY-oP4" id="44J-UK-89l"/>
</connections>
</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">

View File

@ -12,6 +12,11 @@ import Account
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 {
var isOpen: Bool {
@ -152,6 +157,10 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
return canMarkRead()
}
if item.action == #selector(toggleStarred(_:)) {
return validateToggleStarred(item)
}
if item.action == #selector(markOlderArticlesAsRead(_:)) {
return canMarkOlderArticlesAsRead()
}
@ -178,6 +187,31 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
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
@IBAction func scrollOrGoToNextUnread(_ sender: Any?) {
@ -267,6 +301,11 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
timelineViewController?.markSelectedArticlesAsUnread(sender)
}
@IBAction func toggleStarred(_ sender: Any?) {
timelineViewController?.toggleStarredStatusForSelectedArticles()
}
@IBAction func markAllAsReadAndGoToNextUnread(_ sender: Any?) {
markAllAsRead(sender)

View File

@ -12,6 +12,19 @@ import RSTextDrawing
import Data
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 {
@IBOutlet var tableView: TimelineTableView!
@ -191,7 +204,7 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
markSelectedArticlesAsUnread(sender)
}
}
@IBAction func markSelectedArticlesAsRead(_ sender: Any?) {
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)
}
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() {
// Mark articles the same age or older than the selected article(s) as read.