Fix a bunch of build errors.
This commit is contained in:
parent
8c0c8db824
commit
4d677b2055
@ -1147,25 +1147,29 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
842E45CE1ED8C308000A8B52 /* AppNotifications.swift in Sources */,
|
||||
849C64641ED37A5D003D8FC0 /* AppDelegate.swift in Sources */,
|
||||
84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */,
|
||||
842E45CE1ED8C308000A8B52 /* AppNotifications.swift in Sources */,
|
||||
842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */,
|
||||
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */,
|
||||
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
|
||||
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
|
||||
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
||||
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
||||
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */,
|
||||
849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */,
|
||||
849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */,
|
||||
849A975B1ED9EB0D007D329B /* ArticleUtilities.swift in Sources */,
|
||||
849A97891ED9ECEF007D329B /* ArticleStyle.swift in Sources */,
|
||||
849A978A1ED9ECEF007D329B /* ArticleStylesManager.swift in Sources */,
|
||||
849A97791ED9EC04007D329B /* TimelineStringUtilities.swift in Sources */,
|
||||
849A979F1ED9F130007D329B /* SidebarCell.swift in Sources */,
|
||||
849A97981ED9EFAA007D329B /* Node-Extensions.swift in Sources */,
|
||||
849A97531ED9EAC0007D329B /* AddFeedController.swift in Sources */,
|
||||
849A97831ED9EC63007D329B /* StatusBarView.swift in Sources */,
|
||||
849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */,
|
||||
849A97921ED9EF65007D329B /* IndeterminateProgressWindowController.swift in Sources */,
|
||||
849A97801ED9EC42007D329B /* DetailViewController.swift in Sources */,
|
||||
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
|
||||
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
||||
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */,
|
||||
849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */,
|
||||
84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */,
|
||||
849A978D1ED9EE4D007D329B /* FeedListWindowController.swift in Sources */,
|
||||
849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */,
|
||||
849A975C1ED9EB0D007D329B /* DefaultFeedsImporter.swift in Sources */,
|
||||
@ -1173,16 +1177,12 @@
|
||||
849A976C1ED9EBC8007D329B /* TimelineTableRowView.swift in Sources */,
|
||||
849A977B1ED9EC04007D329B /* UnreadIndicatorView.swift in Sources */,
|
||||
849A97541ED9EAC0007D329B /* AddFeedWindowController.swift in Sources */,
|
||||
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
|
||||
849A976D1ED9EBC8007D329B /* TimelineTableView.swift in Sources */,
|
||||
849A97A31ED9F180007D329B /* FolderTreeControllerDelegate.swift in Sources */,
|
||||
849A97671ED9EB96007D329B /* UnreadCountView.swift in Sources */,
|
||||
849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */,
|
||||
849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */,
|
||||
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
||||
849A97761ED9EC04007D329B /* TimelineCellAppearance.swift in Sources */,
|
||||
849A97A21ED9F180007D329B /* FeedTitleDownloader.swift in Sources */,
|
||||
849A97651ED9EB96007D329B /* SidebarTreeControllerDelegate.swift in Sources */,
|
||||
849A977F1ED9EC42007D329B /* ArticleRenderer.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -19,7 +19,7 @@ final class AppDefaults {
|
||||
|
||||
static let shared = AppDefaults()
|
||||
|
||||
private struct Key {
|
||||
struct Key {
|
||||
static let firstRunDate = "firstRunDate"
|
||||
static let sidebarFontSize = "sidebarFontSize"
|
||||
static let timelineFontSize = "timelineFontSize"
|
||||
@ -27,6 +27,9 @@ final class AppDefaults {
|
||||
static let openInBrowserInBackground = "openInBrowserInBackground"
|
||||
}
|
||||
|
||||
private let smallestFontSizeRawValue = FontSize.small.rawValue
|
||||
private let largestFontSizeRawValue = FontSize.veryLarge.rawValue
|
||||
|
||||
let isFirstRun: Bool
|
||||
|
||||
var openInBrowserInBackground: Bool {
|
||||
@ -65,11 +68,12 @@ final class AppDefaults {
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
private init() {
|
||||
|
||||
registerDefaults()
|
||||
AppDefaults.registerDefaults()
|
||||
|
||||
if self.firstRunDate == nil {
|
||||
let firstRunDate = UserDefaults.standard.object(forKey: Key.firstRunDate) as? Date
|
||||
if firstRunDate == nil {
|
||||
self.isFirstRun = true
|
||||
self.firstRunDate = Date()
|
||||
}
|
||||
@ -86,11 +90,11 @@ private extension AppDefaults {
|
||||
return date(for: Key.firstRunDate)
|
||||
}
|
||||
set {
|
||||
setDate(for: key.firstRunDate, date)
|
||||
setDate(for: Key.firstRunDate, newValue)
|
||||
}
|
||||
}
|
||||
|
||||
func registerDefaults() {
|
||||
static func registerDefaults() {
|
||||
|
||||
let defaults = [Key.sidebarFontSize: FontSize.medium.rawValue, Key.timelineFontSize: FontSize.medium.rawValue, Key.detailFontSize: FontSize.medium.rawValue]
|
||||
|
||||
@ -99,9 +103,6 @@ private extension AppDefaults {
|
||||
|
||||
func fontSize(for key: String) -> FontSize {
|
||||
|
||||
static let smallestFontSizeRawValue = FontSize.small.rawValue
|
||||
static let largestFontSizeRawValue = FontSize.veryLarge.rawValue
|
||||
|
||||
var rawFontSize = int(for: key)
|
||||
if rawFontSize < smallestFontSizeRawValue {
|
||||
rawFontSize = smallestFontSizeRawValue
|
||||
@ -136,7 +137,7 @@ private extension AppDefaults {
|
||||
return UserDefaults.standard.object(forKey: key) as? Date
|
||||
}
|
||||
|
||||
func setDate(for key: String, _ date: Date) {
|
||||
func setDate(for key: String, _ date: Date?) {
|
||||
UserDefaults.standard.set(date, forKey: key)
|
||||
}
|
||||
}
|
||||
|
@ -47,12 +47,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations {
|
||||
func applicationDidFinishLaunching(_ note: Notification) {
|
||||
|
||||
let isFirstRun = AppDefaults.shared.isFirstRun
|
||||
let localAccount = AccountManager.shared.localAccount
|
||||
importDefaultFeedsIfNeeded(isFirstRun, account: localAccount)
|
||||
|
||||
currentTheme = themeLoader.defaultTheme
|
||||
|
||||
let _ = AccountManager.sharedInstance
|
||||
|
||||
importDefaultFeedsIfNeeded(isFirstRun, account: AccountManager.shared.localAccount)
|
||||
createAndShowMainWindow()
|
||||
|
||||
#if RELEASE
|
||||
@ -180,7 +179,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations {
|
||||
|
||||
@IBAction func refreshAll(_ sender: AnyObject) {
|
||||
|
||||
AccountManager.sharedInstance.refreshAll()
|
||||
AccountManager.shared.refreshAll()
|
||||
}
|
||||
|
||||
@IBAction func showAddFeedWindow(_ sender: AnyObject) {
|
||||
@ -219,7 +218,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations {
|
||||
let result = panel.runModal()
|
||||
if result == NSApplication.ModalResponse.OK, let url = panel.url {
|
||||
DispatchQueue.main.async {
|
||||
self.parseAndImportOPML(url, AccountManager.sharedInstance.localAccount)
|
||||
self.parseAndImportOPML(url, AccountManager.shared.localAccount)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,7 +242,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations {
|
||||
let result = panel.runModal()
|
||||
if result.rawValue == NSFileHandlingPanelOKButton, let url = panel.url {
|
||||
DispatchQueue.main.async {
|
||||
let opmlString = AccountManager.sharedInstance.localAccount.OPMLString(indentLevel: 0)
|
||||
let opmlString = AccountManager.shared.localAccount.OPMLString(indentLevel: 0)
|
||||
do {
|
||||
try opmlString.write(to: url, atomically: true, encoding: String.Encoding.utf8)
|
||||
}
|
||||
|
@ -6,7 +6,8 @@
|
||||
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Cocoa
|
||||
import Data
|
||||
|
||||
extension Notification.Name {
|
||||
|
||||
@ -16,16 +17,41 @@ extension Notification.Name {
|
||||
static let AppNavigationKeyPressed = Notification.Name("AppNavigationKeyPressedNotification")
|
||||
}
|
||||
|
||||
struct AppUserInfoKey {
|
||||
extension Notification {
|
||||
|
||||
static let view = "view"
|
||||
static let node = "node"
|
||||
static let objects = "objects"
|
||||
static let article = "article"
|
||||
static let articles = "articles"
|
||||
static let articleStatus = "status"
|
||||
static let appNavigation = "key"
|
||||
var appInfo: AppInfo? {
|
||||
get {
|
||||
return AppInfo.pullFromUserInfo(userInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typealias UserInfoDictionary = [AnyHashable: Any]
|
||||
|
||||
final class AppInfo {
|
||||
|
||||
// These are things commonly passed around in Evergreen notifications.
|
||||
// Rather than setting these things using strings, we have a single AppInfo class
|
||||
// that the userInfo dictionary may contain.
|
||||
|
||||
var view: NSView?
|
||||
var article: Article?
|
||||
var articles: Set<Article>?
|
||||
var navigationKey: Int?
|
||||
var objects: [AnyObject]?
|
||||
|
||||
static let appInfoKey = "appInfo"
|
||||
|
||||
var userInfo: UserInfoDictionary {
|
||||
get {
|
||||
return [AppInfo.appInfoKey: self] as UserInfoDictionary
|
||||
}
|
||||
}
|
||||
|
||||
static func pullFromUserInfo(_ userInfo: UserInfoDictionary?) -> AppInfo? {
|
||||
|
||||
return userInfo?[appInfoKey] as? AppInfo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ private func shouldImportDefaultFeeds(_ isFirstRun: Bool) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
for oneAccount in AccountManager.sharedInstance.accounts {
|
||||
for oneAccount in AccountManager.shared.accounts {
|
||||
if oneAccount.hasAtLeastOneFeed {
|
||||
return false
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class AddFeedController: AddFeedWindowControllerDelegate, FeedFinderDelegate {
|
||||
|
||||
let folderTreeControllerDelegate = FolderTreeControllerDelegate()
|
||||
|
||||
let rootNode = Node(representedObject: AccountManager.sharedInstance.localAccount, parent: nil)
|
||||
let rootNode = Node(representedObject: AccountManager.shared.localAccount, parent: nil)
|
||||
rootNode.canHaveChildNodes = true
|
||||
let folderTreeController = TreeController(delegate: folderTreeControllerDelegate, rootNode: rootNode)
|
||||
|
||||
@ -61,7 +61,7 @@ class AddFeedController: AddFeedWindowControllerDelegate, FeedFinderDelegate {
|
||||
closeAddFeedSheet(NSApplication.ModalResponse.OK)
|
||||
|
||||
assert(folder.account != nil, "Folder must have an account.")
|
||||
let account = folder.account ?? AccountManager.sharedInstance.localAccount
|
||||
let account = folder.account ?? AccountManager.shared.localAccount
|
||||
|
||||
if account.hasFeed(withURL: url.absoluteString) {
|
||||
showAlreadySubscribedError(url.absoluteString, folder)
|
||||
|
@ -10,6 +10,7 @@ import Foundation
|
||||
import RSCore
|
||||
import RSTree
|
||||
import Data
|
||||
import Account
|
||||
|
||||
final class FolderTreeControllerDelegate: TreeControllerDelegate {
|
||||
|
||||
@ -28,7 +29,7 @@ private extension FolderTreeControllerDelegate {
|
||||
|
||||
var folderNodes = [Node]()
|
||||
|
||||
let _ = AccountManager.sharedInstance.localAccount.visitChildren { (oneRepresentedObject) in
|
||||
let _ = AccountManager.shared.localAccount.visitChildren { (oneRepresentedObject) in
|
||||
|
||||
if let folder = oneRepresentedObject as? Folder {
|
||||
folderNodes += [createNode(folder, parent: node)]
|
||||
|
@ -45,7 +45,7 @@ class AddFolderWindowController : NSWindowController {
|
||||
|
||||
accountPopupButton.removeAllItems()
|
||||
let menu = NSMenu()
|
||||
for oneAccount in AccountManager.sharedInstance.sortedAccounts {
|
||||
for oneAccount in AccountManager.shared.sortedAccounts {
|
||||
let oneMenuItem = NSMenuItem()
|
||||
oneMenuItem.title = oneAccount.nameForDisplay
|
||||
oneMenuItem.representedObject = oneAccount
|
||||
|
@ -50,10 +50,9 @@ class DetailViewController: NSViewController, WKNavigationDelegate, WKUIDelegate
|
||||
|
||||
@objc func timelineSelectionDidChange(_ note: Notification) {
|
||||
|
||||
let timelineView = note.userInfo?[viewKey] as! NSView
|
||||
|
||||
if timelineView.window! === self.view.window {
|
||||
article = note.userInfo?[articleKey] as? Article
|
||||
let timelineView = note.appInfo?.view
|
||||
if timelineView?.window === self.view.window {
|
||||
article = note.appInfo?.article
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,14 +40,14 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
|
||||
|
||||
@objc func appNavigationKeyPressed(_ note: Notification) {
|
||||
|
||||
guard let key = note.userInfo?[AppKey.appNavigation] as? Int else {
|
||||
guard let navigationKey = note.appInfo?.navigationKey else {
|
||||
return
|
||||
}
|
||||
guard let contentView = window?.contentView, let view = note.object as? NSView, view.isDescendant(of: contentView) else {
|
||||
return
|
||||
}
|
||||
|
||||
print(key)
|
||||
print(navigationKey)
|
||||
}
|
||||
|
||||
@objc func refreshProgressDidChange(_ note: Notification) {
|
||||
|
@ -38,13 +38,13 @@ class SidebarOutlineView : NSOutlineView {
|
||||
|
||||
default:
|
||||
keyHandled = false
|
||||
|
||||
}
|
||||
|
||||
if keyHandled {
|
||||
NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self, userInfo: [appNavigationKey: ch])
|
||||
let appInfo = AppInfo()
|
||||
appInfo.navigationKey = ch
|
||||
NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self, userInfo: appInfo.userInfo)
|
||||
}
|
||||
|
||||
else {
|
||||
super.keyDown(with: event)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
import Foundation
|
||||
import RSTree
|
||||
import Data
|
||||
import Account
|
||||
|
||||
final class SidebarTreeControllerDelegate: TreeControllerDelegate {
|
||||
|
||||
@ -34,7 +35,7 @@ private extension SidebarTreeControllerDelegate {
|
||||
|
||||
var updatedChildNodes = [Node]()
|
||||
|
||||
let _ = AccountManager.sharedInstance.localAccount.visitChildren { (oneRepresentedObject) in
|
||||
let _ = AccountManager.shared.localAccount.visitChildren { (oneRepresentedObject) in
|
||||
|
||||
if let existingNode = node.childNodeRepresentingObject(oneRepresentedObject as AnyObject) {
|
||||
// Reuse nodes.
|
||||
|
@ -175,13 +175,13 @@ private extension SidebarViewController {
|
||||
|
||||
func postSidebarSelectionDidChangeNotification(_ selectedObjects: NSArray?) {
|
||||
|
||||
var userInfo = [AnyHashable: Any]()
|
||||
let appInfo = AppInfo()
|
||||
if let selectedObjects = selectedObjects {
|
||||
userInfo[AppKey.objects] = selectedObjects
|
||||
appInfo.objects = selectedObjects
|
||||
}
|
||||
userInfo[AppKey.view] = self.outlineView
|
||||
appInfo.view = outlineView
|
||||
|
||||
NotificationCenter.default.post(name: .SidebarSelectionDidChange, object: self, userInfo: userInfo)
|
||||
NotificationCenter.default.post(name: .SidebarSelectionDidChange, object: self, userInfo: appInfo.userInfo)
|
||||
}
|
||||
|
||||
func nodeForItem(_ item: AnyObject?) -> Node {
|
||||
|
@ -14,8 +14,8 @@ private let cornerRadius = currentTheme.float(forKey: "MainWindow.SourceList.unr
|
||||
private let backgroundColor = currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.backgroundColor")
|
||||
private let textColor = currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.color")
|
||||
private let textSize = currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.fontSize")
|
||||
private let textFont = NSFont.systemFont(ofSize: textSize, weight: NSFontWeightSemibold)
|
||||
private var textAttributes: [String: AnyObject] = [NSForegroundColorAttributeName: textColor, NSFontAttributeName: textFont, NSKernAttributeName: NSNull()]
|
||||
private let textFont = NSFont.systemFont(ofSize: textSize, weight: NSFont.Weight.semibold)
|
||||
private var textAttributes: [NSAttributedStringKey: AnyObject] = [NSAttributedStringKey.foregroundColor: textColor, NSAttributedStringKey.font: textFont, NSAttributedStringKey.kern: NSNull()]
|
||||
private var textSizeCache = [Int: NSSize]()
|
||||
|
||||
class UnreadCountView : NSView {
|
||||
|
@ -56,10 +56,9 @@ final class StatusBarView: NSView {
|
||||
|
||||
@objc dynamic func timelineSelectionDidChange(_ note: Notification) {
|
||||
|
||||
let timelineView = note.userInfo?[AppKey.view] as! NSView
|
||||
|
||||
if timelineView.window! === self.window {
|
||||
article = note.userInfo?[AppKey.article] as? Article
|
||||
let timelineView = note.appInfo?.view
|
||||
if timelineView?.window === self.window {
|
||||
article = note.appInfo?.article
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ struct TimelineCellAppearance {
|
||||
dateMarginLeft = theme.float(forKey: "MainWindow.Timeline.cell.dateMarginLeft")
|
||||
|
||||
titleColor = theme.color(forKey: "MainWindow.Timeline.cell.titleColor")
|
||||
titleFont = NSFont.systemFont(ofSize: actualFontSize, weight: NSFontWeightBold)
|
||||
titleFont = NSFont.systemFont(ofSize: actualFontSize, weight: NSFont.Weight.bold)
|
||||
titleBottomMargin = theme.float(forKey: "MainWindow.Timeline.cell.titleMarginBottom")
|
||||
|
||||
textColor = theme.color(forKey: "MainWindow.Timeline.cell.textColor")
|
||||
@ -69,7 +69,7 @@ struct TimelineCellAppearance {
|
||||
}
|
||||
}
|
||||
|
||||
private let smallFontSize = NSFont.systemFontSize()
|
||||
private let smallFontSize = NSFont.systemFontSize
|
||||
private let mediumFontSize = smallFontSize + 1.0
|
||||
private let largeFontSize = mediumFontSize + 4.0
|
||||
private let veryLargeFontSize = largeFontSize + 8.0
|
||||
|
@ -66,12 +66,7 @@ struct TimelineCellData {
|
||||
self.showFeedName = showFeedName
|
||||
|
||||
self.favicon = nil
|
||||
if let status = article.status {
|
||||
self.read = status.read
|
||||
}
|
||||
else {
|
||||
self.read = false
|
||||
}
|
||||
self.read = article.status.read
|
||||
}
|
||||
|
||||
init() { //Empty
|
||||
|
@ -13,13 +13,11 @@ import RSTree
|
||||
import Data
|
||||
import Account
|
||||
|
||||
let timelineFontSizeKVOKey = "values." + TimelineFontSizeKey
|
||||
|
||||
class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource, KeyboardDelegate {
|
||||
|
||||
@IBOutlet var tableView: TimelineTableView!
|
||||
var didRegisterForNotifications = false
|
||||
var fontSize: FontSize = timelineFontSize() {
|
||||
var fontSize: FontSize = AppDefaults.shared.timelineFontSize {
|
||||
didSet {
|
||||
fontSizeDidChange()
|
||||
}
|
||||
@ -53,7 +51,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
|
||||
var selectedArticles: [Article] {
|
||||
get {
|
||||
return articlesForIndexes(tableView.selectedRowIndexes)
|
||||
return Array(articlesForIndexes(tableView.selectedRowIndexes))
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +61,8 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
}
|
||||
}
|
||||
|
||||
private let timelineFontSizeKVOKey = "values.{AppDefaults.Key.timelineFontSize}"
|
||||
|
||||
override func viewDidLoad() {
|
||||
|
||||
cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize)
|
||||
@ -78,7 +78,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(sidebarSelectionDidChange(_:)), name: .SidebarSelectionDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(articleStatusesDidChange(_:)), name: .ArticleStatusesDidChange, object: nil)
|
||||
|
||||
NSUserDefaultsController.shared.addObserver(self, forKeyPath:timelineFontSizeKVOKey, options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
NSUserDefaultsController.shared.addObserver(self, forKeyPath: timelineFontSizeKVOKey, options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
|
||||
|
||||
didRegisterForNotifications = true
|
||||
}
|
||||
@ -144,12 +144,8 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
return
|
||||
}
|
||||
let articles = selectedArticles
|
||||
var markAsRead = true
|
||||
if let status = articles.first!.status {
|
||||
if status.read {
|
||||
markAsRead = false
|
||||
}
|
||||
}
|
||||
let status = articles.first!.status
|
||||
let markAsRead = !status.read
|
||||
|
||||
markArticles(Set(articles), statusKey: ArticleStatusKey.read.rawValue, flag: markAsRead)
|
||||
}
|
||||
@ -187,7 +183,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
func canMarkAllAsRead() -> Bool {
|
||||
|
||||
for article in articles {
|
||||
if !article.read {
|
||||
if !article.status.read {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -209,7 +205,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
break
|
||||
}
|
||||
let article = articleAtRow(ix)!
|
||||
if !article.read {
|
||||
if !article.status.read {
|
||||
return ix
|
||||
}
|
||||
}
|
||||
@ -221,20 +217,19 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
|
||||
@objc func sidebarSelectionDidChange(_ note: Notification) {
|
||||
|
||||
let sidebarView = note.userInfo?[viewKey] as! NSView
|
||||
let sidebarView = note.appInfo?.view
|
||||
|
||||
if sidebarView.window! === tableView.window {
|
||||
representedObjects = note.userInfo?[objectsKey] as? [AnyObject]
|
||||
if sidebarView?.window === tableView.window {
|
||||
representedObjects = note.appInfo?.objects
|
||||
}
|
||||
}
|
||||
|
||||
@objc func articleStatusesDidChange(_ note: Notification) {
|
||||
|
||||
guard let articles = note.userInfo?[articlesKey] as? NSSet else {
|
||||
guard let articles = note.appInfo?.articles else {
|
||||
return
|
||||
}
|
||||
|
||||
reloadCellsForArticles(articles.allObjects as! [Article])
|
||||
reloadCellsForArticles(articles)
|
||||
}
|
||||
|
||||
func fontSizeInDefaultsDidChange() {
|
||||
@ -243,7 +238,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
RSSingleLineRenderer.emptyCache()
|
||||
RSMultiLineRenderer.emptyCache()
|
||||
|
||||
let updatedFontSize = timelineFontSize()
|
||||
let updatedFontSize = AppDefaults.shared.timelineFontSize
|
||||
if updatedFontSize != self.fontSize {
|
||||
self.fontSize = updatedFontSize
|
||||
}
|
||||
@ -318,7 +313,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
return nil
|
||||
}
|
||||
|
||||
private func reloadCellsForArticles(_ articles: [Article]) {
|
||||
private func reloadCellsForArticles(_ articles: Set<Article>) {
|
||||
|
||||
let indexes = indexesForArticles(articles)
|
||||
tableView.reloadData(forRowIndexes: indexes, columnIndexes: NSIndexSet(index: 0) as IndexSet)
|
||||
@ -326,7 +321,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
|
||||
// MARK: Articles
|
||||
|
||||
private func indexesForArticles(_ articles: [Article]) -> IndexSet {
|
||||
private func indexesForArticles(_ articles: Set<Article>) -> IndexSet {
|
||||
|
||||
var indexes = IndexSet()
|
||||
|
||||
@ -340,11 +335,11 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
return indexes
|
||||
}
|
||||
|
||||
private func articlesForIndexes(_ indexes: IndexSet) -> [Article] {
|
||||
private func articlesForIndexes(_ indexes: IndexSet) -> Set<Article> {
|
||||
|
||||
return indexes.flatMap{ (oneIndex) -> Article? in
|
||||
return Set(indexes.flatMap{ (oneIndex) -> Article? in
|
||||
return articleAtRow(oneIndex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func articleAtRow(_ row: Int) -> Article? {
|
||||
@ -380,57 +375,57 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
|
||||
private func fetchArticles() {
|
||||
|
||||
guard let representedObjects = representedObjects else {
|
||||
if !articles.isEmpty {
|
||||
articles = [Article]()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var accountsDictionary = [String: [AnyObject]]()
|
||||
|
||||
func addToAccountArray(accountID: String, object: AnyObject) {
|
||||
|
||||
if let accountArray = accountsDictionary[accountID] {
|
||||
if !accountArray.contains(where: { $0 === object }) {
|
||||
accountsDictionary[accountID] = accountArray + [object]
|
||||
}
|
||||
}
|
||||
else {
|
||||
accountsDictionary[accountID] = [object]
|
||||
}
|
||||
}
|
||||
|
||||
for oneObject in representedObjects {
|
||||
|
||||
if let oneFeed = oneObject as? Feed {
|
||||
addToAccountArray(accountID: oneFeed.account.accountID, object: oneFeed)
|
||||
}
|
||||
else if let oneFolder = oneObject as? Folder, let accountID = oneFolder.account?.accountID {
|
||||
addToAccountArray(accountID: accountID, object: oneFolder)
|
||||
}
|
||||
}
|
||||
|
||||
var fetchedArticles = [Article]()
|
||||
for (accountID, objects) in accountsDictionary {
|
||||
|
||||
guard let oneAccount = accountWithID(accountID) else {
|
||||
continue
|
||||
}
|
||||
|
||||
let oneFetchedArticles = oneAccount.fetchArticles(for: objects)
|
||||
for oneFetchedArticle in oneFetchedArticles {
|
||||
if !fetchedArticles.contains(where: { $0 === oneFetchedArticle }) {
|
||||
fetchedArticles += [oneFetchedArticle]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchedArticles.sort(by: articleComparator)
|
||||
|
||||
if !articleArraysAreIdentical(array1: articles, array2: fetchedArticles) {
|
||||
articles = fetchedArticles
|
||||
}
|
||||
// guard let representedObjects = representedObjects else {
|
||||
// if !articles.isEmpty {
|
||||
// articles = [Article]()
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// var accountsDictionary = [String: [AnyObject]]()
|
||||
//
|
||||
// func addToAccountArray(accountID: String, object: AnyObject) {
|
||||
//
|
||||
// if let accountArray = accountsDictionary[accountID] {
|
||||
// if !accountArray.contains(where: { $0 === object }) {
|
||||
// accountsDictionary[accountID] = accountArray + [object]
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// accountsDictionary[accountID] = [object]
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for oneObject in representedObjects {
|
||||
//
|
||||
// if let oneFeed = oneObject as? Feed {
|
||||
// addToAccountArray(accountID: oneFeed.account.accountID, object: oneFeed)
|
||||
// }
|
||||
// else if let oneFolder = oneObject as? Folder, let accountID = oneFolder.account?.accountID {
|
||||
// addToAccountArray(accountID: accountID, object: oneFolder)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var fetchedArticles = [Article]()
|
||||
// for (accountID, objects) in accountsDictionary {
|
||||
//
|
||||
// guard let oneAccount = accountWithID(accountID) else {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// let oneFetchedArticles = oneAccount.fetchArticles(for: objects)
|
||||
// for oneFetchedArticle in oneFetchedArticles {
|
||||
// if !fetchedArticles.contains(where: { $0 === oneFetchedArticle }) {
|
||||
// fetchedArticles += [oneFetchedArticle]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fetchedArticles.sort(by: articleComparator)
|
||||
//
|
||||
// if articles != fetchedArticles {
|
||||
// articles = fetchedArticles
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: Cell Configuring
|
||||
@ -438,7 +433,9 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
private func calculateRowHeight() -> CGFloat {
|
||||
|
||||
let longTitle = "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
|
||||
let prototypeArticle = Article(accountID: "prototype", articleID: "prototype", feedID: "prototype", uniqueID: "prototype", title: longTitle, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: nil, dateModified: nil, authors: nil, tags: nil, attachments: nil)
|
||||
let prototypeID = "prototype"
|
||||
let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, userDeleted: false, dateArrived: Date())
|
||||
let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, feedID: prototypeID, uniqueID: prototypeID, title: longTitle, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: nil, dateModified: nil, authors: nil, tags: nil, attachments: nil, status: status)
|
||||
|
||||
let prototypeCellData = TimelineCellData(article: prototypeArticle, appearance: cellAppearance, showFeedName: false)
|
||||
let height = timelineCellHeight(100, cellData: prototypeCellData, appearance: cellAppearance)
|
||||
@ -495,13 +492,13 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
|
||||
private func postTimelineSelectionDidChangeNotification(_ selectedArticle: Article?) {
|
||||
|
||||
var userInfo = [String: AnyObject]()
|
||||
let appInfo = AppInfo()
|
||||
if let article = selectedArticle {
|
||||
userInfo[articleKey] = article as AnyObject
|
||||
appInfo.article = article
|
||||
}
|
||||
userInfo[viewKey] = self.tableView
|
||||
appInfo.view = tableView
|
||||
|
||||
NotificationCenter.default.post(name: .TimelineSelectionDidChange, object: self, userInfo: userInfo)
|
||||
NotificationCenter.default.post(name: .TimelineSelectionDidChange, object: self, userInfo: appInfo.userInfo)
|
||||
}
|
||||
|
||||
func tableViewSelectionDidChange(_ notification: Notification) {
|
||||
@ -516,7 +513,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView
|
||||
}
|
||||
|
||||
if let selectedArticle = articleAtRow(selectedRow) {
|
||||
if (!selectedArticle.read) {
|
||||
if (!selectedArticle.status.read) {
|
||||
markArticles(Set([selectedArticle]), statusKey: ArticleStatusKey.read.rawValue, flag: true)
|
||||
}
|
||||
postTimelineSelectionDidChangeNotification(selectedArticle)
|
||||
|
@ -47,23 +47,23 @@ class PreferencesWindowController : NSWindowController, NSToolbarDelegate {
|
||||
window?.showsToolbarButton = false
|
||||
window?.toolbar = toolbar
|
||||
|
||||
window?.setFrameAutosaveName(windowFrameName)
|
||||
window?.setFrameAutosaveName(NSWindow.FrameAutosaveName(rawValue: windowFrameName))
|
||||
|
||||
switchToViewAtIndex(0)
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
|
||||
func toolbarItemClicked(_ sender: AnyObject) {
|
||||
@objc func toolbarItemClicked(_ sender: AnyObject) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: NSToolbarDelegate
|
||||
|
||||
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: String, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
|
||||
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
|
||||
|
||||
guard let toolbarItemSpec = toolbarItemSpecs.first(where: { $0.identifier == itemIdentifier }) else {
|
||||
guard let toolbarItemSpec = toolbarItemSpecs.first(where: { $0.identifier.rawValue == itemIdentifier }) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ private extension PreferencesWindowController {
|
||||
return cachedViewController
|
||||
}
|
||||
|
||||
let storyboard = NSStoryboard(name: "Preferences", bundle: nil)
|
||||
let storyboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Preferences"), bundle: nil)
|
||||
guard let viewController = storyboard.instantiateController(withIdentifier: identifier) as? NSViewController else {
|
||||
assertionFailure("Unknown preferences view controller: \(identifier)")
|
||||
return nil
|
||||
|
@ -28,7 +28,7 @@ public final class AccountManager: UnreadCountProvider {
|
||||
}
|
||||
}
|
||||
|
||||
var accounts: [Account] {
|
||||
public var accounts: [Account] {
|
||||
get {
|
||||
return Array(accountsDictionary.values)
|
||||
}
|
||||
@ -194,7 +194,7 @@ private func accountFilePathWithFolder(_ folderPath: String) -> String {
|
||||
public func accountWithID(_ accountID: String) -> Account? {
|
||||
|
||||
// Shortcut.
|
||||
return AccountManager.sharedInstance.existingAccount(with: accountID)
|
||||
return AccountManager.shared.existingAccount(with: accountID)
|
||||
}
|
||||
|
||||
private struct AccountSpecifier {
|
||||
|
Loading…
x
Reference in New Issue
Block a user