diff --git a/Mac/AppAssets.swift b/Mac/AppAssets.swift index 038dcfa39..c537ee21b 100644 --- a/Mac/AppAssets.swift +++ b/Mac/AppAssets.swift @@ -17,10 +17,6 @@ extension NSImage.Name { struct AppAssets { - static var timelineStar: RSImage! = { - return RSImage(named: .timelineStar) - }() - static var accountCloudKit: RSImage! = { return RSImage(named: "accountCloudKit") }() @@ -81,6 +77,14 @@ struct AppAssets { return RSImage(named: "faviconTemplateImage")! }() + static var filterActive: RSImage = { + return RSImage(named: "filterActive")! + }() + + static var filterInactive: RSImage = { + return RSImage(named: "filterInactive")! + }() + static var iconLightBackgroundColor: NSColor = { return NSColor(named: NSColor.Name("iconLightBackgroundColor"))! }() @@ -101,6 +105,10 @@ struct AppAssets { return IconImage(RSImage(named: NSImage.smartBadgeTemplateName)!) }() + static var timelineStar: RSImage! = { + return RSImage(named: .timelineStar) + }() + static var todayFeedImage: IconImage = { return IconImage(RSImage(named: NSImage.smartBadgeTemplateName)!) }() diff --git a/Mac/Base.lproj/MainWindow.storyboard b/Mac/Base.lproj/MainWindow.storyboard index c25cc2cbd..48694b502 100644 --- a/Mac/Base.lproj/MainWindow.storyboard +++ b/Mac/Base.lproj/MainWindow.storyboard @@ -273,17 +273,42 @@ - + + + + + + + + + + + + - + - + - + @@ -389,18 +414,22 @@ + + + - + + @@ -426,18 +455,93 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + @@ -503,6 +607,7 @@ + diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index 17c2f5562..c07f13a92 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -20,6 +20,7 @@ protocol SidebarDelegate: class { @objc class SidebarViewController: NSViewController, NSOutlineViewDelegate, NSMenuDelegate, UndoableCommandRunner { + @IBOutlet weak var readFilteredButton: NSButton! @IBOutlet var outlineView: SidebarOutlineView! weak var delegate: SidebarDelegate? @@ -129,6 +130,8 @@ protocol SidebarDelegate: class { if let readFeedsFilterState = state[UserInfoKey.readFeedsFilterState] as? Bool { isReadFiltered = readFeedsFilterState } + + updateReadFilterButton() } // MARK: - Notifications @@ -446,6 +449,7 @@ protocol SidebarDelegate: class { } delegate?.sidebarInvalidatedRestorationState(self) rebuildTreeAndRestoreSelection() + updateReadFilterButton() } func cleanUp() { @@ -815,6 +819,14 @@ private extension SidebarViewController { func revealAndSelectRepresentedObject(_ representedObject: AnyObject) -> Bool { return outlineView.revealAndSelectRepresentedObject(representedObject, treeController) } + + func updateReadFilterButton() { + if isReadFiltered { + readFilteredButton.image = AppAssets.filterActive + } else { + readFilteredButton.image = AppAssets.filterInactive + } + } } private extension Node { diff --git a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift index 778c196cf..09008682b 100644 --- a/Mac/MainWindow/Timeline/TimelineContainerViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineContainerViewController.swift @@ -19,6 +19,12 @@ protocol TimelineContainerViewControllerDelegate: class { final class TimelineContainerViewController: NSViewController { + @IBOutlet weak var viewOptionsPopUpButton: NSPopUpButton! + @IBOutlet weak var newestToOldestMenuItem: NSMenuItem! + @IBOutlet weak var oldestToNewestMenuItem: NSMenuItem! + @IBOutlet weak var groupByFeedMenuItem: NSMenuItem! + + @IBOutlet weak var readFilteredButton: NSButton! @IBOutlet var containerView: TimelineContainerView! var currentTimelineViewController: TimelineViewController? { @@ -52,12 +58,22 @@ final class TimelineContainerViewController: NSViewController { super.viewDidLoad() setRepresentedObjects(nil, mode: .regular) showTimeline(for: .regular) + updateViewOptionsPopUpButton() + + NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) } - + + // MARK: - Notifications + + @objc func userDefaultsDidChange(_ note: Notification) { + updateViewOptionsPopUpButton() + } + // MARK: - API func setRepresentedObjects(_ objects: [AnyObject]?, mode: TimelineSourceMode) { timelineViewController(for: mode).representedObjects = objects + updateReadFilterButton() } func showTimeline(for mode: TimelineSourceMode) { @@ -95,6 +111,7 @@ final class TimelineContainerViewController: NSViewController { func toggleReadFilter() { regularTimelineViewController.toggleReadFilter() + updateReadFilterButton() } // MARK: State Restoration @@ -105,6 +122,7 @@ final class TimelineContainerViewController: NSViewController { func restoreState(from state: [AnyHashable : Any]) { regularTimelineViewController.restoreState(from: state) + updateReadFilterButton() } } @@ -145,4 +163,42 @@ private extension TimelineContainerViewController { assertionFailure("Expected timelineViewController to match either regular or search timelineViewController, but it doesn’t.") return .regular // Should never get here. } + + func updateViewOptionsPopUpButton() { + let localizedTitle = NSLocalizedString("Sort %@", comment: "Sort") + + if AppDefaults.timelineSortDirection == .orderedAscending { + newestToOldestMenuItem.state = .off + oldestToNewestMenuItem.state = .on + let title = NSString.localizedStringWithFormat(localizedTitle as NSString, oldestToNewestMenuItem.title) as String + viewOptionsPopUpButton.setTitle(title) + } else { + newestToOldestMenuItem.state = .on + oldestToNewestMenuItem.state = .off + let title = NSString.localizedStringWithFormat(localizedTitle as NSString, newestToOldestMenuItem.title) as String + viewOptionsPopUpButton.setTitle(title) + } + + if AppDefaults.timelineGroupByFeed == true { + groupByFeedMenuItem.state = .on + } else { + groupByFeedMenuItem.state = .off + } + } + + func updateReadFilterButton() { + guard let isReadFiltered = regularTimelineViewController.isReadFiltered else { + readFilteredButton.isHidden = true + return + } + + readFilteredButton.isHidden = false + + if isReadFiltered { + readFilteredButton.image = AppAssets.filterActive + } else { + readFilteredButton.image = AppAssets.filterInactive + } + } + } diff --git a/Mac/Resources/Assets.xcassets/filterActive.imageset/Contents.json b/Mac/Resources/Assets.xcassets/filterActive.imageset/Contents.json new file mode 100644 index 000000000..6d8907a7a --- /dev/null +++ b/Mac/Resources/Assets.xcassets/filterActive.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "filterActive.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Mac/Resources/Assets.xcassets/filterActive.imageset/filterActive.pdf b/Mac/Resources/Assets.xcassets/filterActive.imageset/filterActive.pdf new file mode 100644 index 000000000..68eb230b5 Binary files /dev/null and b/Mac/Resources/Assets.xcassets/filterActive.imageset/filterActive.pdf differ diff --git a/Mac/Resources/Assets.xcassets/filterInactive.imageset/Contents.json b/Mac/Resources/Assets.xcassets/filterInactive.imageset/Contents.json new file mode 100644 index 000000000..93ba12c1b --- /dev/null +++ b/Mac/Resources/Assets.xcassets/filterInactive.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "filterInactive.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Mac/Resources/Assets.xcassets/filterInactive.imageset/filterInactive.pdf b/Mac/Resources/Assets.xcassets/filterInactive.imageset/filterInactive.pdf new file mode 100644 index 000000000..0d6b6c9b2 Binary files /dev/null and b/Mac/Resources/Assets.xcassets/filterInactive.imageset/filterInactive.pdf differ