diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index 751767700..7a5ce7774 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -55,6 +55,7 @@ 5165D72922835F7A00D9D53D /* FeedSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5165D71D22835E9800D9D53D /* FeedSpecifier.swift */; }; 5165D72A22835F7D00D9D53D /* HTMLFeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5165D71E22835E9800D9D53D /* HTMLFeedFinder.swift */; }; 5165D73122837F3400D9D53D /* InitialFeedDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5165D73022837F3400D9D53D /* InitialFeedDownloader.swift */; }; + 516896352448EBEA00185AC5 /* FeedProviderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516896342448EBEA00185AC5 /* FeedProviderManager.swift */; }; 5170743C232AEDB500A461A3 /* OPMLFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5170743B232AEDB500A461A3 /* OPMLFile.swift */; }; 519E84A62433D49000D238B0 /* OPMLNormalizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E84A52433D49000D238B0 /* OPMLNormalizer.swift */; }; 519E84A82434C5EF00D238B0 /* CloudKitArticlesZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E84A72434C5EF00D238B0 /* CloudKitArticlesZone.swift */; }; @@ -292,6 +293,7 @@ 5165D71D22835E9800D9D53D /* FeedSpecifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedSpecifier.swift; sourceTree = ""; }; 5165D71E22835E9800D9D53D /* HTMLFeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLFeedFinder.swift; sourceTree = ""; }; 5165D73022837F3400D9D53D /* InitialFeedDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitialFeedDownloader.swift; sourceTree = ""; }; + 516896342448EBEA00185AC5 /* FeedProviderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedProviderManager.swift; sourceTree = ""; }; 5170743B232AEDB500A461A3 /* OPMLFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLFile.swift; sourceTree = ""; }; 518B2EA52351306200400001 /* Account_project_test.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Account_project_test.xcconfig; sourceTree = ""; }; 519E84A52433D49000D238B0 /* OPMLNormalizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLNormalizer.swift; sourceTree = ""; }; @@ -551,6 +553,7 @@ isa = PBXGroup; children = ( 5132AAC12448BAD90077840A /* FeedProvider.swift */, + 516896342448EBEA00185AC5 /* FeedProviderManager.swift */, 5132AAC22448BAD90077840A /* Twitter */, ); path = FeedProvider; @@ -1114,6 +1117,7 @@ 846E77451F6EF9B900A165E2 /* Container.swift in Sources */, 9EA643D3239305680018A28C /* FeedlySearchOperation.swift in Sources */, 5150FFFE243823B800C1A442 /* CloudKitError.swift in Sources */, + 516896352448EBEA00185AC5 /* FeedProviderManager.swift in Sources */, 9E5EC15D23E0D58500A4E503 /* FeedlyFeedParser.swift in Sources */, 9E1D15532334304B00F4944C /* FeedlyGetStreamContentsOperation.swift in Sources */, 9E12B0202334696A00ADE5A0 /* FeedlyCreateFeedsForCollectionFoldersOperation.swift in Sources */, diff --git a/Frameworks/Account/FeedProvider/FeedProviderManager.swift b/Frameworks/Account/FeedProvider/FeedProviderManager.swift new file mode 100644 index 000000000..486c232c1 --- /dev/null +++ b/Frameworks/Account/FeedProvider/FeedProviderManager.swift @@ -0,0 +1,42 @@ +// +// FeedProviderManager.swift +// Account +// +// Created by Maurice Parker on 4/16/20. +// Copyright © 2020 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +public protocol FeedProviderManagerDelegate: class { + var activeFeedProviders: [FeedProvider] { get } +} + +public final class FeedProviderManager { + + public static let shared = FeedProviderManager() + public weak var delegate: FeedProviderManagerDelegate? + + public func best(for offered: URLComponents, with username: String?) -> FeedProvider? { + if let owner = feedProviderMatching(offered, forUsername: username, ability: .owner) { + return owner + } + return feedProviderMatching(offered, forUsername: username, ability: .available) + } + +} + +private extension FeedProviderManager { + + func feedProviderMatching(_ offered: URLComponents, forUsername username: String?, ability: FeedProviderAbility) -> FeedProvider? { + if let delegate = delegate { + for feedProvider in delegate.activeFeedProviders { + if feedProvider.ability(offered, forUsername: username) == ability { + return feedProvider + } + } + } + return nil + } + +} diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 09e6682ab..4de0e011d 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -104,7 +104,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, super.init() AccountManager.shared = AccountManager(accountsFolder: Platform.dataSubfolder(forApplication: nil, folderName: "Accounts")!) - + FeedProviderManager.shared.delegate = ExtensionPointManager.shared + NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(inspectableObjectsDidChange(_:)), name: .InspectableObjectsDidChange, object: nil) NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(didWakeNotification(_:)), name: NSWorkspace.didWakeNotification, object: nil) diff --git a/Shared/ExtensionPoints/ExtensionPointManager.swift b/Shared/ExtensionPoints/ExtensionPointManager.swift index f620a5b04..ee87e1c89 100644 --- a/Shared/ExtensionPoints/ExtensionPointManager.swift +++ b/Shared/ExtensionPoints/ExtensionPointManager.swift @@ -15,7 +15,7 @@ public extension Notification.Name { static let ActiveExtensionPointsDidChange = Notification.Name(rawValue: "ActiveExtensionPointsDidChange") } -final class ExtensionPointManager { +final class ExtensionPointManager: FeedProviderManagerDelegate { static let shared = ExtensionPointManager() @@ -75,13 +75,6 @@ final class ExtensionPointManager { saveExtensionPointIDs() } - func bestFeedProvider(for offered: URLComponents, with username: String?) -> FeedProvider? { - if let owner = feedProviderMatching(offered, forUsername: username, ability: .owner) { - return owner - } - return feedProviderMatching(offered, forUsername: username, ability: .available) - } - } private extension ExtensionPointManager { diff --git a/Shared/Images/WebFeedIconDownloader.swift b/Shared/Images/WebFeedIconDownloader.swift index cb476b7cb..f3148570d 100644 --- a/Shared/Images/WebFeedIconDownloader.swift +++ b/Shared/Images/WebFeedIconDownloader.swift @@ -118,7 +118,7 @@ public final class WebFeedIconDownloader { return nil } - if let components = URLComponents(string: feed.url), let feedProvider = ExtensionPointManager.shared.bestFeedProvider(for: components, with: nil) { + if let components = URLComponents(string: feed.url), let feedProvider = FeedProviderManager.shared.best(for: components, with: nil) { feedProvider.iconURL(components) { result in switch result { case .success(let feedProviderURL): diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index a16e92ab2..66e21f46e 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -64,6 +64,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD let documentAccountsFolder = documentAccountURL.appendingPathComponent("Accounts").absoluteString let documentAccountsFolderPath = String(documentAccountsFolder.suffix(from: documentAccountsFolder.index(documentAccountsFolder.startIndex, offsetBy: 7))) AccountManager.shared = AccountManager(accountsFolder: documentAccountsFolderPath) + FeedProviderManager.shared.delegate = ExtensionPointManager.shared NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(accountRefreshDidFinish(_:)), name: .AccountRefreshDidFinish, object: nil)