From 92a60d8f06ae8bc697b030043e91a62ac00f5dde Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 17 Sep 2017 17:03:58 -0700 Subject: [PATCH] Continue fixing build errors. --- Evergreen/Data/ArticleUtilities.swift | 27 +++++++++++++++++- .../Timeline/Cell/TimelineCellData.swift | 12 ++------ .../Timeline/TimelineViewController.swift | 28 +++++++++---------- Frameworks/Account/Account.swift | 27 ++++++++++++------ Frameworks/Database/ArticlesTable.swift | 10 +++++++ Frameworks/Database/Database.swift | 14 ++++++++-- Frameworks/Database/StatusesTable.swift | 14 ++++++++++ 7 files changed, 97 insertions(+), 35 deletions(-) diff --git a/Evergreen/Data/ArticleUtilities.swift b/Evergreen/Data/ArticleUtilities.swift index 5521fd2f6..24a16ec6c 100644 --- a/Evergreen/Data/ArticleUtilities.swift +++ b/Evergreen/Data/ArticleUtilities.swift @@ -43,9 +43,19 @@ private func accountAndArticlesDictionary(_ articles: Set
) -> [String: extension Article { + var feed: Feed? { + get { + return account?.existingFeed(with: feedID) + } + } + var status: ArticleStatus? { get { - return account?.articleStatus(for: self) + guard let status = account?.articleStatus(for: self) else { + assertionFailure("Expected ArticleStatus for article.status.") + return nil + } + return status } } @@ -60,4 +70,19 @@ extension Article { return contentHTML ?? contentText ?? summary } } + + var logicalDatePublished: Date { + get { + return datePublished ?? dateModified ?? status?.dateArrived ?? Date.distantPast + } + } + + var read: Bool { + get { + if let status = status { + return status.read + } + return false + } + } } diff --git a/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift b/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift index eab863415..0ea06ea66 100644 --- a/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift +++ b/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift @@ -45,7 +45,7 @@ struct TimelineCellData { self.attributedDateString = s } else { - self.attributedDateString = NSAttributedString(string: self.dateString, attributes: [NSForegroundColorAttributeName: appearance.dateColor, NSFontAttributeName: appearance.dateFont]) + self.attributedDateString = NSAttributedString(string: self.dateString, attributes: [NSAttributedStringKey.foregroundColor: appearance.dateColor, NSAttributedStringKey.font: appearance.dateFont]) attributedDateCache[self.dateString] = self.attributedDateString } @@ -59,20 +59,14 @@ struct TimelineCellData { self.attributedFeedName = s } else { - self.attributedFeedName = NSAttributedString(string: self.feedName, attributes: [NSForegroundColorAttributeName: appearance.feedNameColor, NSFontAttributeName: appearance.feedNameFont]) + self.attributedFeedName = NSAttributedString(string: self.feedName, attributes: [NSAttributedStringKey.foregroundColor: appearance.feedNameColor, NSAttributedStringKey.font: appearance.feedNameFont]) attributedFeedNameCache[self.feedName] = self.attributedFeedName } self.showFeedName = showFeedName self.favicon = nil - - if let status = article.status { - self.read = status.read - } - else { - self.read = false - } + self.read = article.read } init() { //Empty diff --git a/Evergreen/MainWindow/Timeline/TimelineViewController.swift b/Evergreen/MainWindow/Timeline/TimelineViewController.swift index 026688bd3..eef85a408 100644 --- a/Evergreen/MainWindow/Timeline/TimelineViewController.swift +++ b/Evergreen/MainWindow/Timeline/TimelineViewController.swift @@ -124,9 +124,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView return } - let articlesSet = NSMutableSet() - articlesSet.addObjects(from: articles) - markArticles(articlesSet, statusKey: .read, flag: true) + markArticles(Set(articles), statusKey: ArticleStatusKey.read.rawValue, flag: true) reloadCellsForArticles(articles) } @@ -147,21 +145,23 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView } let articles = selectedArticles var markAsRead = true - if articles.first!.status.read { - markAsRead = false + if let status = articles.first!.status { + if status.read { + markAsRead = false + } } - markArticles(NSSet(array: articles), statusKey: .read, flag: markAsRead) + markArticles(Set(articles), statusKey: ArticleStatusKey.read.rawValue, flag: markAsRead) } @IBAction func markSelectedArticlesAsRead(_ sender: AnyObject) { - markArticles(NSSet(array: selectedArticles), statusKey: .read, flag: true) + markArticles(Set(selectedArticles), statusKey: ArticleStatusKey.read.rawValue, flag: true) } @IBAction func markSelectedArticlesAsUnread(_ sender: AnyObject) { - markArticles(NSSet(array: selectedArticles), statusKey: .read, flag: false) + markArticles(Set(selectedArticles), statusKey: ArticleStatusKey.read.rawValue, flag: false) } // MARK: Navigation @@ -186,11 +186,12 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView func canMarkAllAsRead() -> Bool { - for oneArticle in articles { - if !oneArticle.status.read { + for article in articles { + if !article.read { return true } } + return false } @@ -208,7 +209,7 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView break } let article = articleAtRow(ix)! - if !article.status.read { + if !article.read { return ix } } @@ -520,9 +521,8 @@ class TimelineViewController: NSViewController, NSTableViewDelegate, NSTableView } if let selectedArticle = articleAtRow(selectedRow) { - let articleSet = NSSet(array: [selectedArticle]) - if (!selectedArticle.status.read) { - markArticles(articleSet, statusKey: .read, flag: true) + if (!selectedArticle.read) { + markArticles(Set([selectedArticle]), statusKey: ArticleStatusKey.read.rawValue, flag: true) } postTimelineSelectionDidChangeNotification(selectedArticle) } diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 98f587993..d85cff6bf 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -10,6 +10,7 @@ import Foundation import RSCore import Data import RSParser +import Database public enum AccountType: Int { @@ -31,6 +32,7 @@ public final class Account: DisplayNameProvider, Hashable { public let hashValue: Int let settingsFile: String let dataFolder: String + let database: Database var topLevelObjects = [AnyObject]() var feedIDDictionary = [String: Feed]() var username: String? @@ -38,19 +40,22 @@ public final class Account: DisplayNameProvider, Hashable { init?(dataFolder: String, settingsFile: String, type: AccountType, accountID: String) { - self.accountID = accountID - self.type = type - self.settingsFile = settingsFile - self.dataFolder = dataFolder - self.hashValue = accountID.hashValue - switch type { - + case .onMyMac: self.delegate = LocalAccountDelegate() default: return nil } + + self.accountID = accountID + self.type = type + self.settingsFile = settingsFile + self.dataFolder = dataFolder + self.hashValue = accountID.hashValue + + let databaseFilePath = (dataFolder as NSString).appendingPathComponent("DB.sqlite3") + self.database = Database(databaseFilePath: databaseFilePath, accountID: accountID) } // MARK: - API @@ -67,12 +72,16 @@ public final class Account: DisplayNameProvider, Hashable { public func markArticles(_ articles: Set
, statusKey: String, flag: Bool) { - // TODO + let statuses = database.statuses(for: articles) + if statuses.isEmpty { + return + } + database.mark(statuses, statusKey: statusKey, flag: flag) } public func articleStatus(for article: Article) -> ArticleStatus? { - // TODO + return database.status(for: article) } public func ensureFolder(with name: String) -> Folder? { diff --git a/Frameworks/Database/ArticlesTable.swift b/Frameworks/Database/ArticlesTable.swift index 9cfe9b056..668ca4f18 100644 --- a/Frameworks/Database/ArticlesTable.swift +++ b/Frameworks/Database/ArticlesTable.swift @@ -131,6 +131,16 @@ final class ArticlesTable: DatabaseTable { // MARK: Status + func status(for article: Article) -> ArticleStatus? { + + return statusesTable.cachedStatus(for: article.articleID) + } + + func statuses(for articles: Set
) -> Set { + + return statusesTable.cachedStatuses(for: articles.articleIDs()) + } + func mark(_ statuses: Set, _ statusKey: String, _ flag: Bool) { statusesTable.mark(statuses, statusKey, flag) diff --git a/Frameworks/Database/Database.swift b/Frameworks/Database/Database.swift index 282b747bd..e100ae07d 100644 --- a/Frameworks/Database/Database.swift +++ b/Frameworks/Database/Database.swift @@ -24,11 +24,11 @@ public final class Database { private let accountID: String private let articlesTable: ArticlesTable - public init(databaseFile: String, accountID: String) { + public init(databaseFilePath: String, accountID: String) { self.accountID = accountID - let queue = RSDatabaseQueue(filepath: databaseFile, excludeFromBackup: false) + let queue = RSDatabaseQueue(filepath: databaseFilePath, excludeFromBackup: false) self.articlesTable = ArticlesTable(name: DatabaseTableName.articles, accountID: accountID, queue: queue) let createStatementsPath = Bundle(for: type(of: self)).path(forResource: "CreateStatements", ofType: "sql")! @@ -70,6 +70,16 @@ public final class Database { // MARK: - Status + public func status(for article: Article) -> ArticleStatus? { + + return articlesTable.status(for: article) + } + + public func statuses(for articles: Set
) -> Set { + + return articlesTable.statuses(for: articles) + } + public func mark(_ statuses: Set, statusKey: String, flag: Bool) { articlesTable.mark(statuses, statusKey, flag) diff --git a/Frameworks/Database/StatusesTable.swift b/Frameworks/Database/StatusesTable.swift index c232653b8..f3d7a911d 100644 --- a/Frameworks/Database/StatusesTable.swift +++ b/Frameworks/Database/StatusesTable.swift @@ -37,6 +37,20 @@ final class StatusesTable: DatabaseTable { return cache[articleID] } + func cachedStatuses(for articleIDs: Set) -> Set { + + assert(Thread.isMainThread) + + var statuses = Set() + for articleID in articleIDs { + if let articleStatus = cache[articleID] { + statuses.insert(articleStatus) + } + } + + return statuses + } + func addIfNotCached(_ statuses: Set) { if statuses.isEmpty {