Add article exception fetcher to always restore article to timeline regardless of timeline state.
This commit is contained in:
parent
d62ff04c64
commit
7d39933ba4
|
@ -29,6 +29,7 @@
|
|||
5133230C2281088A00C30F19 /* subscriptions_add.json in Resources */ = {isa = PBXBuildFile; fileRef = 5133230B2281088A00C30F19 /* subscriptions_add.json */; };
|
||||
5144EA49227B497600D19003 /* FeedbinAPICaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA48227B497600D19003 /* FeedbinAPICaller.swift */; };
|
||||
5144EA4E227B829A00D19003 /* FeedbinAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4D227B829A00D19003 /* FeedbinAccountDelegate.swift */; };
|
||||
514BF5202391B0DB00902FE8 /* SingleArticleFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514BF51F2391B0DB00902FE8 /* SingleArticleFetcher.swift */; };
|
||||
5154367B228EEB28005E1CDF /* FeedbinImportResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5154367A228EEB28005E1CDF /* FeedbinImportResult.swift */; };
|
||||
515E4EB52324FF8C0057B0E7 /* CredentialsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515E4EB22324FF8C0057B0E7 /* CredentialsManager.swift */; };
|
||||
515E4EB62324FF8C0057B0E7 /* URLRequest+RSWeb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515E4EB32324FF8C0057B0E7 /* URLRequest+RSWeb.swift */; };
|
||||
|
@ -242,6 +243,7 @@
|
|||
5133230B2281088A00C30F19 /* subscriptions_add.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscriptions_add.json; sourceTree = "<group>"; };
|
||||
5144EA48227B497600D19003 /* FeedbinAPICaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAPICaller.swift; sourceTree = "<group>"; };
|
||||
5144EA4D227B829A00D19003 /* FeedbinAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAccountDelegate.swift; sourceTree = "<group>"; };
|
||||
514BF51F2391B0DB00902FE8 /* SingleArticleFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleArticleFetcher.swift; sourceTree = "<group>"; };
|
||||
5154367A228EEB28005E1CDF /* FeedbinImportResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinImportResult.swift; sourceTree = "<group>"; };
|
||||
515E4EB22324FF8C0057B0E7 /* CredentialsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CredentialsManager.swift; sourceTree = "<group>"; };
|
||||
515E4EB32324FF8C0057B0E7 /* URLRequest+RSWeb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URLRequest+RSWeb.swift"; sourceTree = "<group>"; };
|
||||
|
@ -575,6 +577,7 @@
|
|||
84AF4EA3222CFDD100F6A800 /* AccountMetadata.swift */,
|
||||
510BD110232C3801002692E4 /* AccountMetadataFile.swift */,
|
||||
84F73CF0202788D80000BCEF /* ArticleFetcher.swift */,
|
||||
514BF51F2391B0DB00902FE8 /* SingleArticleFetcher.swift */,
|
||||
84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */,
|
||||
8419740D1F6DD25F006346C4 /* Container.swift */,
|
||||
51BFDECD238B508D00216323 /* ContainerIdentifier.swift */,
|
||||
|
@ -963,6 +966,7 @@
|
|||
9EEAE071235D019B00E3FEE4 /* FeedlyGetStreamContentsService.swift in Sources */,
|
||||
9E7299D9235062A200DAEFB7 /* FeedlyResourceProviding.swift in Sources */,
|
||||
9E672394236F7CA0000BE141 /* FeedlyRefreshAccessTokenOperation.swift in Sources */,
|
||||
514BF5202391B0DB00902FE8 /* SingleArticleFetcher.swift in Sources */,
|
||||
9EC688EC232C583300A8D0A2 /* FeedlyAccountDelegate+OAuth.swift in Sources */,
|
||||
8469F81C1F6DD15E0084783E /* Account.swift in Sources */,
|
||||
9EAEC60E2332FEC20085D7C9 /* FeedlyFeed.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// SingleArticleFetcher.swift
|
||||
// Account
|
||||
//
|
||||
// Created by Maurice Parker on 11/29/19.
|
||||
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Articles
|
||||
|
||||
public struct SingleArticleFetcher: ArticleFetcher {
|
||||
|
||||
private let account: Account
|
||||
private let articleID: String
|
||||
|
||||
public init(account: Account, articleID: String) {
|
||||
self.account = account
|
||||
self.articleID = articleID
|
||||
}
|
||||
|
||||
public func fetchArticles() -> Set<Article> {
|
||||
return account.fetchArticles(.articleIDs(Set([articleID])))
|
||||
}
|
||||
|
||||
public func fetchArticlesAsync(_ callback: @escaping ArticleSetBlock) {
|
||||
return account.fetchArticlesAsync(.articleIDs(Set([articleID])), callback)
|
||||
}
|
||||
|
||||
public func fetchUnreadArticles() -> Set<Article> {
|
||||
return account.fetchArticles(.articleIDs(Set([articleID])))
|
||||
}
|
||||
|
||||
public func fetchUnreadArticlesAsync(_ callback: @escaping ArticleSetBlock) {
|
||||
return account.fetchArticlesAsync(.articleIDs(Set([articleID])), callback)
|
||||
}
|
||||
|
||||
}
|
|
@ -157,6 +157,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
|||
return (timelineFeed as? SmallIconProvider)?.smallIcon
|
||||
}
|
||||
|
||||
private var exceptionArticleFetcher: ArticleFetcher?
|
||||
private(set) var timelineFeed: Feed?
|
||||
|
||||
var timelineMiddleIndexPath: IndexPath?
|
||||
|
@ -1596,13 +1597,20 @@ private extension SceneCoordinator {
|
|||
// To be called when we need to do an entire fetch, but an async delay is okay.
|
||||
// Example: we have the Today feed selected, and the calendar day just changed.
|
||||
cancelPendingAsyncFetches()
|
||||
guard let timelineFetcher = timelineFeed else {
|
||||
guard let timelineFeed = timelineFeed else {
|
||||
emptyTheTimeline()
|
||||
completion()
|
||||
return
|
||||
}
|
||||
|
||||
fetchUnsortedArticlesAsync(for: [timelineFetcher]) { [weak self] (articles) in
|
||||
var fetchers = [ArticleFetcher]()
|
||||
fetchers.append(timelineFeed)
|
||||
if exceptionArticleFetcher != nil {
|
||||
fetchers.append(exceptionArticleFetcher!)
|
||||
exceptionArticleFetcher = nil
|
||||
}
|
||||
|
||||
fetchUnsortedArticlesAsync(for: fetchers) { [weak self] (articles) in
|
||||
self?.replaceArticles(with: articles, animated: animated)
|
||||
completion()
|
||||
}
|
||||
|
@ -1862,16 +1870,19 @@ private extension SceneCoordinator {
|
|||
let accountID = articlePathUserInfo[ArticlePathKey.accountID] as? String,
|
||||
let accountName = articlePathUserInfo[ArticlePathKey.accountName] as? String,
|
||||
let webFeedID = articlePathUserInfo[ArticlePathKey.webFeedID] as? String,
|
||||
let articleID = articlePathUserInfo[ArticlePathKey.articleID] as? String else {
|
||||
let articleID = articlePathUserInfo[ArticlePathKey.articleID] as? String,
|
||||
let accountNode = findAccountNode(accountID: accountID, accountName: accountName),
|
||||
let account = accountNode.representedObject as? Account else {
|
||||
return
|
||||
}
|
||||
|
||||
exceptionArticleFetcher = SingleArticleFetcher(account: account, articleID: articleID)
|
||||
|
||||
if restoreFeedSelection(userInfo, accountID: accountID, webFeedID: webFeedID, articleID: articleID) {
|
||||
return
|
||||
}
|
||||
|
||||
guard let accountNode = findAccountNode(accountID: accountID, accountName: accountName),
|
||||
let webFeedNode = findWebFeedNode(webFeedID: webFeedID, beginningAt: accountNode),
|
||||
guard let webFeedNode = findWebFeedNode(webFeedID: webFeedID, beginningAt: accountNode),
|
||||
let webFeed = webFeedNode.representedObject as? WebFeed,
|
||||
let webFeedFeedID = webFeed.feedID else {
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue