Add download syncing of article statuses
This commit is contained in:
parent
3dc2bc2c49
commit
62d154d0f2
@ -448,6 +448,10 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
||||
}
|
||||
}
|
||||
|
||||
public func fetchArticles(forArticleIDs articleIDs: Set<String>) -> Set<Article> {
|
||||
return database.fetchArticles(forArticleIDs: articleIDs)
|
||||
}
|
||||
|
||||
public func fetchArticles(for feed: Feed) -> Set<Article> {
|
||||
|
||||
let articles = database.fetchArticles(for: feed.feedID)
|
||||
@ -535,6 +539,14 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
||||
database.fetchStarredAndUnreadCount(for: flattenedFeeds().feedIDs(), callback: callback)
|
||||
}
|
||||
|
||||
public func fetchUnreadArticleIDs() -> Set<String> {
|
||||
return database.fetchUnreadArticleIDs()
|
||||
}
|
||||
|
||||
public func fetchStarredArticleIDs() -> Set<String> {
|
||||
return database.fetchStarredArticleIDs()
|
||||
}
|
||||
|
||||
public func opmlDocument() -> String {
|
||||
let escapedTitle = nameForDisplay.rs_stringByEscapingSpecialXMLCharacters()
|
||||
let openingText =
|
||||
|
@ -103,9 +103,8 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
caller.retrieveUnreadEntries() { [weak self] result in
|
||||
switch result {
|
||||
case .success(let articleIDs):
|
||||
self?.syncArticleReadState(account: account, articleIDs: articleIDs) {
|
||||
self?.syncArticleReadState(account: account, articleIDs: articleIDs)
|
||||
group.leave()
|
||||
}
|
||||
case .failure(let error):
|
||||
guard let self = self else { return }
|
||||
os_log(.info, log: self.log, "Retrieving unread entries failed: %@.", error.localizedDescription)
|
||||
@ -117,9 +116,8 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||
caller.retrieveStarredEntries() { [weak self] result in
|
||||
switch result {
|
||||
case .success(let articleIDs):
|
||||
self?.syncArticleStarredState(account: account, articleIDs: articleIDs) {
|
||||
self?.syncArticleStarredState(account: account, articleIDs: articleIDs)
|
||||
group.leave()
|
||||
}
|
||||
case .failure(let error):
|
||||
guard let self = self else { return }
|
||||
os_log(.info, log: self.log, "Retrieving starred entries failed: %@.", error.localizedDescription)
|
||||
@ -1013,29 +1011,49 @@ private extension FeedbinAccountDelegate {
|
||||
|
||||
}
|
||||
|
||||
func syncArticleReadState(account: Account, articleIDs: [Int]?, completion: (() -> Void)) {
|
||||
func syncArticleReadState(account: Account, articleIDs: [Int]?) {
|
||||
|
||||
guard let articleIDs = articleIDs, !articleIDs.isEmpty else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
let ids = Set(articleIDs.map { String($0) } )
|
||||
let feedbinUnreadArticleIDs = Set(articleIDs.map { String($0) } )
|
||||
let currentUnreadArticleIDs = account.fetchUnreadArticleIDs()
|
||||
|
||||
completion()
|
||||
let deltaUnreadArticleIDs = feedbinUnreadArticleIDs.subtracting(currentUnreadArticleIDs)
|
||||
let markUnreadArticles = account.fetchArticles(forArticleIDs: deltaUnreadArticleIDs)
|
||||
DispatchQueue.main.async {
|
||||
_ = account.markArticles(markUnreadArticles, statusKey: .read, flag: false)
|
||||
}
|
||||
|
||||
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(feedbinUnreadArticleIDs)
|
||||
let markReadArticles = account.fetchArticles(forArticleIDs: deltaReadArticleIDs)
|
||||
DispatchQueue.main.async {
|
||||
_ = account.markArticles(markReadArticles, statusKey: .read, flag: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func syncArticleStarredState(account: Account, articleIDs: [Int]?, completion: (() -> Void)) {
|
||||
func syncArticleStarredState(account: Account, articleIDs: [Int]?) {
|
||||
|
||||
guard let articleIDs = articleIDs, !articleIDs.isEmpty else {
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
let ids = Set(articleIDs.map { String($0) } )
|
||||
let feedbinStarredArticleIDs = Set(articleIDs.map { String($0) } )
|
||||
let currentStarredArticleIDs = account.fetchStarredArticleIDs()
|
||||
|
||||
completion()
|
||||
let deltaStarredArticleIDs = feedbinStarredArticleIDs.subtracting(currentStarredArticleIDs)
|
||||
let markStarredArticles = account.fetchArticles(forArticleIDs: deltaStarredArticleIDs)
|
||||
DispatchQueue.main.async {
|
||||
_ = account.markArticles(markStarredArticles, statusKey: .starred, flag: true)
|
||||
}
|
||||
|
||||
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(feedbinStarredArticleIDs)
|
||||
let markUnstarredArticles = account.fetchArticles(forArticleIDs: deltaUnstarredArticleIDs)
|
||||
DispatchQueue.main.async {
|
||||
_ = account.markArticles(markUnstarredArticles, statusKey: .starred, flag: false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,10 @@ public final class ArticlesDatabase {
|
||||
return articlesTable.fetchArticles(feedID)
|
||||
}
|
||||
|
||||
public func fetchArticles(forArticleIDs articleIDs: Set<String>) -> Set<Article> {
|
||||
return articlesTable.fetchArticles(forArticleIDs: articleIDs)
|
||||
}
|
||||
|
||||
public func fetchArticlesAsync(for feedID: String, _ resultBlock: @escaping ArticleResultBlock) {
|
||||
articlesTable.fetchArticlesAsync(feedID, withLimits: true, resultBlock)
|
||||
}
|
||||
@ -96,6 +100,14 @@ public final class ArticlesDatabase {
|
||||
|
||||
// MARK: - Status
|
||||
|
||||
public func fetchUnreadArticleIDs() -> Set<String> {
|
||||
return articlesTable.fetchUnreadArticleIDs()
|
||||
}
|
||||
|
||||
public func fetchStarredArticleIDs() -> Set<String> {
|
||||
return articlesTable.fetchStarredArticleIDs()
|
||||
}
|
||||
|
||||
public func mark(_ articles: Set<Article>, statusKey: ArticleStatus.Key, flag: Bool) -> Set<ArticleStatus>? {
|
||||
return articlesTable.mark(articles, statusKey, flag)
|
||||
}
|
||||
|
@ -56,6 +56,11 @@ final class ArticlesTable: DatabaseTable {
|
||||
return articles
|
||||
}
|
||||
|
||||
public func fetchArticles(forArticleIDs articleIDs: Set<String>) -> Set<Article> {
|
||||
|
||||
return fetchArticlesForIDs(articleIDs)
|
||||
}
|
||||
|
||||
func fetchArticlesAsync(_ feedID: String, withLimits: Bool, _ resultBlock: @escaping ArticleResultBlock) {
|
||||
|
||||
queue.fetch { (database) in
|
||||
@ -284,6 +289,14 @@ final class ArticlesTable: DatabaseTable {
|
||||
|
||||
// MARK: Status
|
||||
|
||||
func fetchUnreadArticleIDs() -> Set<String> {
|
||||
return statusesTable.fetchUnreadArticleIDs()
|
||||
}
|
||||
|
||||
func fetchStarredArticleIDs() -> Set<String> {
|
||||
return statusesTable.fetchStarredArticleIDs()
|
||||
}
|
||||
|
||||
func mark(_ articles: Set<Article>, _ statusKey: ArticleStatus.Key, _ flag: Bool) -> Set<ArticleStatus>? {
|
||||
|
||||
return statusesTable.mark(articles.statuses(), statusKey, flag)
|
||||
@ -428,6 +441,25 @@ private extension ArticlesTable {
|
||||
return fetchArticlesWithWhereClause(database, whereClause: "articles.feedID = ?", parameters: [feedID as AnyObject], withLimits: withLimits)
|
||||
}
|
||||
|
||||
func fetchArticlesForIDs(_ articleIDs: Set<String>) -> Set<Article> {
|
||||
|
||||
if articleIDs.isEmpty {
|
||||
return Set<Article>()
|
||||
}
|
||||
|
||||
var articles = Set<Article>()
|
||||
|
||||
queue.fetchSync { (database) in
|
||||
|
||||
let parameters = articleIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
||||
let whereClause = "articleID in \(placeholders)"
|
||||
articles = self.fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: false)
|
||||
}
|
||||
|
||||
return articles
|
||||
}
|
||||
|
||||
func fetchUnreadArticles(_ feedIDs: Set<String>) -> Set<Article> {
|
||||
|
||||
if feedIDs.isEmpty {
|
||||
|
@ -78,6 +78,33 @@ final class StatusesTable: DatabaseTable {
|
||||
|
||||
// MARK: Fetching
|
||||
|
||||
func fetchUnreadArticleIDs() -> Set<String> {
|
||||
return fetchArticleIDs("select articleID from statuses where read=0 and userDeleted=0;")
|
||||
}
|
||||
|
||||
func fetchStarredArticleIDs() -> Set<String> {
|
||||
return fetchArticleIDs("select articleID from statuses where starred=1 and userDeleted=0;")
|
||||
}
|
||||
|
||||
func fetchArticleIDs(_ sql: String) -> Set<String> {
|
||||
|
||||
var statuses: Set<String>? = nil
|
||||
|
||||
queue.fetchSync { (database) in
|
||||
if let resultSet = database.executeQuery(sql, withArgumentsIn: nil) {
|
||||
statuses = resultSet.mapToSet(self.articleIDWithRow)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return statuses != nil ? statuses! : Set<String>()
|
||||
|
||||
}
|
||||
|
||||
func articleIDWithRow(_ row: FMResultSet) -> String? {
|
||||
return row.string(forColumn: DatabaseKey.articleID)
|
||||
}
|
||||
|
||||
func statusWithRow(_ row: FMResultSet) -> ArticleStatus? {
|
||||
|
||||
guard let articleID = row.string(forColumn: DatabaseKey.articleID) else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user