Add code to process new article entries.
This commit is contained in:
parent
4418a4bb02
commit
983138366f
|
@ -801,16 +801,16 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
/// Mark articleIDs statuses based on statusKey and flag.
|
||||
/// Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
|
||||
/// Returns a set of new article statuses.
|
||||
func markAndFetchNew(articleIDs: Set<String>, statusKey: ArticleStatus.Key, flag: Bool, completion: ArticleStatusesResultBlock? = nil) {
|
||||
func markAndFetchNew(articleIDs: Set<String>, statusKey: ArticleStatus.Key, flag: Bool, completion: ArticleIDsCompletionBlock? = nil) {
|
||||
guard !articleIDs.isEmpty else {
|
||||
completion?(.success(Set<ArticleStatus>()))
|
||||
completion?(.success(Set<String>()))
|
||||
return
|
||||
}
|
||||
database.markAndFetchNew(articleIDs: articleIDs, statusKey: statusKey, flag: flag) { result in
|
||||
switch result {
|
||||
case .success(let newArticleStatuses):
|
||||
case .success(let newArticleStatusIDs):
|
||||
self.noteStatusesForArticleIDsDidChange(articleIDs)
|
||||
completion?(.success(newArticleStatuses))
|
||||
completion?(.success(newArticleStatusIDs))
|
||||
case .failure(let databaseError):
|
||||
completion?(.failure(databaseError))
|
||||
}
|
||||
|
@ -819,25 +819,25 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
|
||||
/// Mark articleIDs as read. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
|
||||
/// Returns a set of new article statuses.
|
||||
func markAsRead(_ articleIDs: Set<String>, completion: ArticleStatusesResultBlock? = nil) {
|
||||
func markAsRead(_ articleIDs: Set<String>, completion: ArticleIDsCompletionBlock? = nil) {
|
||||
markAndFetchNew(articleIDs: articleIDs, statusKey: .read, flag: true, completion: completion)
|
||||
}
|
||||
|
||||
/// Mark articleIDs as unread. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
|
||||
/// Returns a set of new article statuses.
|
||||
func markAsUnread(_ articleIDs: Set<String>, completion: ArticleStatusesResultBlock? = nil) {
|
||||
func markAsUnread(_ articleIDs: Set<String>, completion: ArticleIDsCompletionBlock? = nil) {
|
||||
markAndFetchNew(articleIDs: articleIDs, statusKey: .read, flag: false, completion: completion)
|
||||
}
|
||||
|
||||
/// Mark articleIDs as starred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
|
||||
/// Returns a set of new article statuses.
|
||||
func markAsStarred(_ articleIDs: Set<String>, completion: ArticleStatusesResultBlock? = nil) {
|
||||
func markAsStarred(_ articleIDs: Set<String>, completion: ArticleIDsCompletionBlock? = nil) {
|
||||
markAndFetchNew(articleIDs: articleIDs, statusKey: .starred, flag: true, completion: completion)
|
||||
}
|
||||
|
||||
/// Mark articleIDs as unstarred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification.
|
||||
/// Returns a set of new article statuses.
|
||||
func markAsUnstarred(_ articleIDs: Set<String>, completion: ArticleStatusesResultBlock? = nil) {
|
||||
func markAsUnstarred(_ articleIDs: Set<String>, completion: ArticleIDsCompletionBlock? = nil) {
|
||||
markAndFetchNew(articleIDs: articleIDs, statusKey: .starred, flag: false, completion: completion)
|
||||
}
|
||||
|
||||
|
@ -893,7 +893,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
|
||||
public func debugDropConditionalGetInfo() {
|
||||
#if DEBUG
|
||||
flattenedWebFeeds().forEach{ $0.debugDropConditionalGetInfo() }
|
||||
flattenedWebFeeds().forEach{ $0.dropConditionalGetInfo() }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -481,7 +481,11 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||
self.account = account
|
||||
|
||||
accountZone.delegate = CloudKitAcountZoneDelegate(account: account, refreshProgress: refreshProgress)
|
||||
articlesZone.delegate = CloudKitArticlesZoneDelegate(account: account, database: database, articlesZone: articlesZone)
|
||||
articlesZone.delegate = CloudKitArticlesZoneDelegate(account: account,
|
||||
database: database,
|
||||
articlesZone: articlesZone,
|
||||
refresher: refresher,
|
||||
refreshProgress: refreshProgress)
|
||||
|
||||
// Check to see if this is a new account and initialize anything we need
|
||||
if account.externalID == nil {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import Foundation
|
||||
import os.log
|
||||
import RSParser
|
||||
import RSWeb
|
||||
import CloudKit
|
||||
import SyncDatabase
|
||||
|
||||
|
@ -19,11 +20,15 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
|||
weak var account: Account?
|
||||
var database: SyncDatabase
|
||||
weak var articlesZone: CloudKitArticlesZone?
|
||||
weak var refresher: LocalAccountRefresher?
|
||||
weak var refreshProgress: DownloadProgress?
|
||||
|
||||
init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone) {
|
||||
init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone, refresher: LocalAccountRefresher?, refreshProgress: DownloadProgress?) {
|
||||
self.account = account
|
||||
self.database = database
|
||||
self.articlesZone = articlesZone
|
||||
self.refresher = refresher
|
||||
self.refreshProgress = refreshProgress
|
||||
}
|
||||
|
||||
func cloudKitDidChange(record: CKRecord) {
|
||||
|
@ -82,8 +87,37 @@ private extension CloudKitArticlesZoneDelegate {
|
|||
let group = DispatchGroup()
|
||||
|
||||
group.enter()
|
||||
account?.markAsUnread(updateableUnreadArticleIDs) { _ in
|
||||
account?.markAsUnread(updateableUnreadArticleIDs) { result in
|
||||
switch result {
|
||||
case .success(let newArticleStatusIDs):
|
||||
|
||||
if newArticleStatusIDs.isEmpty {
|
||||
group.leave()
|
||||
} else {
|
||||
self.account?.fetchArticlesAsync(FetchType.articleIDs(newArticleStatusIDs)) { result in
|
||||
switch result {
|
||||
case .success(let articles):
|
||||
|
||||
if articles.isEmpty {
|
||||
group.leave()
|
||||
} else {
|
||||
let webFeeds = Set(articles.compactMap({ $0.webFeed }))
|
||||
webFeeds.forEach { $0.dropConditionalGetInfo() }
|
||||
self.refreshProgress?.addToNumberOfTasksAndRemaining(webFeeds.count)
|
||||
self.refresher?.refreshFeeds(webFeeds) {
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
|
||||
case .failure:
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case .failure:
|
||||
group.leave()
|
||||
}
|
||||
}
|
||||
|
||||
group.enter()
|
||||
|
@ -119,7 +153,6 @@ private extension CloudKitArticlesZoneDelegate {
|
|||
|
||||
}
|
||||
|
||||
|
||||
func makeParsedItem(_ articleRecord: CKRecord) -> ParsedItem? {
|
||||
var parsedAuthors = Set<ParsedAuthor>()
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ protocol LocalAccountRefresherDelegate {
|
|||
|
||||
final class LocalAccountRefresher {
|
||||
|
||||
private var completions = [() -> Void]()
|
||||
private var isSuspended = false
|
||||
var delegate: LocalAccountRefresherDelegate?
|
||||
|
||||
|
@ -26,7 +27,10 @@ final class LocalAccountRefresher {
|
|||
return DownloadSession(delegate: self)
|
||||
}()
|
||||
|
||||
public func refreshFeeds(_ feeds: Set<WebFeed>) {
|
||||
public func refreshFeeds(_ feeds: Set<WebFeed>, completion: (() -> Void)? = nil) {
|
||||
if let completion = completion {
|
||||
completions.append(completion)
|
||||
}
|
||||
downloadSession.downloadObjects(feeds as NSSet)
|
||||
}
|
||||
|
||||
|
@ -154,6 +158,8 @@ extension LocalAccountRefresher: DownloadSessionDelegate {
|
|||
|
||||
func downloadSessionDidCompleteDownloadObjects(_ downloadSession: DownloadSession) {
|
||||
delegate?.localAccountRefresherDidFinish(self)
|
||||
completions.forEach({ $0() })
|
||||
completions = [() -> Void]()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -221,9 +221,9 @@ public final class WebFeed: Feed, Renamable, Hashable {
|
|||
self.metadata = metadata
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
// MARK: - API
|
||||
|
||||
public func debugDropConditionalGetInfo() {
|
||||
public func dropConditionalGetInfo() {
|
||||
conditionalGetInfo = nil
|
||||
contentHash = nil
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ public final class ArticlesDatabase {
|
|||
return try articlesTable.mark(articles, statusKey, flag)
|
||||
}
|
||||
|
||||
public func markAndFetchNew(articleIDs: Set<String>, statusKey: ArticleStatus.Key, flag: Bool, completion: @escaping ArticleStatusesResultBlock) {
|
||||
public func markAndFetchNew(articleIDs: Set<String>, statusKey: ArticleStatus.Key, flag: Bool, completion: @escaping ArticleIDsCompletionBlock) {
|
||||
articlesTable.markAndFetchNew(articleIDs, statusKey, flag, completion)
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,7 @@ final class ArticlesTable: DatabaseTable {
|
|||
return statuses
|
||||
}
|
||||
|
||||
func markAndFetchNew(_ articleIDs: Set<String>, _ statusKey: ArticleStatus.Key, _ flag: Bool, _ completion: @escaping ArticleStatusesResultBlock) {
|
||||
func markAndFetchNew(_ articleIDs: Set<String>, _ statusKey: ArticleStatus.Key, _ flag: Bool, _ completion: @escaping ArticleIDsCompletionBlock) {
|
||||
queue.runInTransaction { databaseResult in
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
|
|
|
@ -85,11 +85,11 @@ final class StatusesTable: DatabaseTable {
|
|||
return updatedStatuses
|
||||
}
|
||||
|
||||
func markAndFetchNew(_ articleIDs: Set<String>, _ statusKey: ArticleStatus.Key, _ flag: Bool, _ database: FMDatabase) -> Set<ArticleStatus> {
|
||||
func markAndFetchNew(_ articleIDs: Set<String>, _ statusKey: ArticleStatus.Key, _ flag: Bool, _ database: FMDatabase) -> Set<String> {
|
||||
let (statusesDictionary, newStatusIDs) = ensureStatusesForArticleIDs(articleIDs, flag, database)
|
||||
let statuses = Set(statusesDictionary.values)
|
||||
mark(statuses, statusKey, flag, database)
|
||||
return Set(newStatusIDs.compactMap({ statusesDictionary[$0] }))
|
||||
return newStatusIDs
|
||||
}
|
||||
|
||||
// MARK: - Fetching
|
||||
|
|
Loading…
Reference in New Issue