Add CloudKit syncing add account UI.
This commit is contained in:
parent
770206df60
commit
e3d46960fd
@ -36,6 +36,7 @@ public extension Notification.Name {
|
|||||||
public enum AccountType: Int, Codable {
|
public enum AccountType: Int, Codable {
|
||||||
// Raw values should not change since they’re stored on disk.
|
// Raw values should not change since they’re stored on disk.
|
||||||
case onMyMac = 1
|
case onMyMac = 1
|
||||||
|
case cloudKit = 2
|
||||||
case feedly = 16
|
case feedly = 16
|
||||||
case feedbin = 17
|
case feedbin = 17
|
||||||
case feedWrangler = 18
|
case feedWrangler = 18
|
||||||
@ -232,6 +233,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||||||
switch type {
|
switch type {
|
||||||
case .onMyMac:
|
case .onMyMac:
|
||||||
self.delegate = LocalAccountDelegate()
|
self.delegate = LocalAccountDelegate()
|
||||||
|
case .cloudKit:
|
||||||
|
self.delegate = CloudKitAccountDelegate()
|
||||||
case .feedbin:
|
case .feedbin:
|
||||||
self.delegate = FeedbinAccountDelegate(dataFolder: dataFolder, transport: transport)
|
self.delegate = FeedbinAccountDelegate(dataFolder: dataFolder, transport: transport)
|
||||||
case .freshRSS:
|
case .freshRSS:
|
||||||
@ -256,6 +259,8 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||||||
switch type {
|
switch type {
|
||||||
case .onMyMac:
|
case .onMyMac:
|
||||||
defaultName = Account.defaultLocalAccountName
|
defaultName = Account.defaultLocalAccountName
|
||||||
|
case .cloudKit:
|
||||||
|
defaultName = "iCloud"
|
||||||
case .feedly:
|
case .feedly:
|
||||||
defaultName = "Feedly"
|
defaultName = "Feedly"
|
||||||
case .feedbin:
|
case .feedbin:
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
3B826DAE2385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DA52385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift */; };
|
3B826DAE2385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DA52385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift */; };
|
||||||
3B826DAF2385C81C00FC1ADB /* FeedWranglerGenericResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DA62385C81C00FC1ADB /* FeedWranglerGenericResult.swift */; };
|
3B826DAF2385C81C00FC1ADB /* FeedWranglerGenericResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826DA62385C81C00FC1ADB /* FeedWranglerGenericResult.swift */; };
|
||||||
3BC23AB92385ECB100371CBA /* FeedWranglerSubscriptionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC23AB82385ECB100371CBA /* FeedWranglerSubscriptionResult.swift */; };
|
3BC23AB92385ECB100371CBA /* FeedWranglerSubscriptionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC23AB82385ECB100371CBA /* FeedWranglerSubscriptionResult.swift */; };
|
||||||
|
5103A9D92422546800410853 /* CloudKitAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5103A9D82422546800410853 /* CloudKitAppDelegate.swift */; };
|
||||||
5107A09B227DE49500C7C3C5 /* TestAccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5107A09A227DE49500C7C3C5 /* TestAccountManager.swift */; };
|
5107A09B227DE49500C7C3C5 /* TestAccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5107A09A227DE49500C7C3C5 /* TestAccountManager.swift */; };
|
||||||
5107A09D227DE77700C7C3C5 /* TestTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5107A09C227DE77700C7C3C5 /* TestTransport.swift */; };
|
5107A09D227DE77700C7C3C5 /* TestTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5107A09C227DE77700C7C3C5 /* TestTransport.swift */; };
|
||||||
510BD111232C3801002692E4 /* AccountMetadataFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510BD110232C3801002692E4 /* AccountMetadataFile.swift */; };
|
510BD111232C3801002692E4 /* AccountMetadataFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510BD110232C3801002692E4 /* AccountMetadataFile.swift */; };
|
||||||
@ -230,6 +231,7 @@
|
|||||||
3B826DA52385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerSubscriptionsRequest.swift; sourceTree = "<group>"; };
|
3B826DA52385C81C00FC1ADB /* FeedWranglerSubscriptionsRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerSubscriptionsRequest.swift; sourceTree = "<group>"; };
|
||||||
3B826DA62385C81C00FC1ADB /* FeedWranglerGenericResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerGenericResult.swift; sourceTree = "<group>"; };
|
3B826DA62385C81C00FC1ADB /* FeedWranglerGenericResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerGenericResult.swift; sourceTree = "<group>"; };
|
||||||
3BC23AB82385ECB100371CBA /* FeedWranglerSubscriptionResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedWranglerSubscriptionResult.swift; sourceTree = "<group>"; };
|
3BC23AB82385ECB100371CBA /* FeedWranglerSubscriptionResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedWranglerSubscriptionResult.swift; sourceTree = "<group>"; };
|
||||||
|
5103A9D82422546800410853 /* CloudKitAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudKitAppDelegate.swift; sourceTree = "<group>"; };
|
||||||
5107A098227DE42E00C7C3C5 /* AccountCredentialsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCredentialsTest.swift; sourceTree = "<group>"; };
|
5107A098227DE42E00C7C3C5 /* AccountCredentialsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCredentialsTest.swift; sourceTree = "<group>"; };
|
||||||
5107A09A227DE49500C7C3C5 /* TestAccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestAccountManager.swift; sourceTree = "<group>"; };
|
5107A09A227DE49500C7C3C5 /* TestAccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestAccountManager.swift; sourceTree = "<group>"; };
|
||||||
5107A09C227DE77700C7C3C5 /* TestTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestTransport.swift; sourceTree = "<group>"; };
|
5107A09C227DE77700C7C3C5 /* TestTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestTransport.swift; sourceTree = "<group>"; };
|
||||||
@ -450,6 +452,14 @@
|
|||||||
path = FeedWrangler;
|
path = FeedWrangler;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5103A9D7242253DC00410853 /* CloudKit */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5103A9D82422546800410853 /* CloudKitAppDelegate.swift */,
|
||||||
|
);
|
||||||
|
path = CloudKit;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
5111D71C2357534700737D45 /* Feedbin */ = {
|
5111D71C2357534700737D45 /* Feedbin */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -606,6 +616,7 @@
|
|||||||
3B826D9D2385C81C00FC1ADB /* FeedWrangler */,
|
3B826D9D2385C81C00FC1ADB /* FeedWrangler */,
|
||||||
552032EA229D5D5A009559E0 /* ReaderAPI */,
|
552032EA229D5D5A009559E0 /* ReaderAPI */,
|
||||||
9EA31339231E368100268BA0 /* Feedly */,
|
9EA31339231E368100268BA0 /* Feedly */,
|
||||||
|
5103A9D7242253DC00410853 /* CloudKit */,
|
||||||
848935031F62484F00CEBD24 /* AccountTests */,
|
848935031F62484F00CEBD24 /* AccountTests */,
|
||||||
848934F71F62484F00CEBD24 /* Products */,
|
848934F71F62484F00CEBD24 /* Products */,
|
||||||
8469F80F1F6DC3C10084783E /* Frameworks */,
|
8469F80F1F6DC3C10084783E /* Frameworks */,
|
||||||
@ -844,11 +855,11 @@
|
|||||||
848934F51F62484F00CEBD24 = {
|
848934F51F62484F00CEBD24 = {
|
||||||
CreatedOnToolsVersion = 9.0;
|
CreatedOnToolsVersion = 9.0;
|
||||||
LastSwiftMigration = 0900;
|
LastSwiftMigration = 0900;
|
||||||
ProvisioningStyle = Manual;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
848934FE1F62484F00CEBD24 = {
|
848934FE1F62484F00CEBD24 = {
|
||||||
CreatedOnToolsVersion = 9.0;
|
CreatedOnToolsVersion = 9.0;
|
||||||
ProvisioningStyle = Manual;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -1008,6 +1019,7 @@
|
|||||||
84F73CF1202788D90000BCEF /* ArticleFetcher.swift in Sources */,
|
84F73CF1202788D90000BCEF /* ArticleFetcher.swift in Sources */,
|
||||||
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */,
|
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */,
|
||||||
510BD113232C3E9D002692E4 /* WebFeedMetadataFile.swift in Sources */,
|
510BD113232C3E9D002692E4 /* WebFeedMetadataFile.swift in Sources */,
|
||||||
|
5103A9D92422546800410853 /* CloudKitAppDelegate.swift in Sources */,
|
||||||
5165D73122837F3400D9D53D /* InitialFeedDownloader.swift in Sources */,
|
5165D73122837F3400D9D53D /* InitialFeedDownloader.swift in Sources */,
|
||||||
9E784EBE237E890600099B1B /* FeedlyLogoutOperation.swift in Sources */,
|
9E784EBE237E890600099B1B /* FeedlyLogoutOperation.swift in Sources */,
|
||||||
9EEEF71F23545CB4009E9D80 /* FeedlySendArticleStatusesOperation.swift in Sources */,
|
9EEEF71F23545CB4009E9D80 /* FeedlySendArticleStatusesOperation.swift in Sources */,
|
||||||
|
@ -120,7 +120,7 @@ public final class AccountManager: UnreadCountProvider {
|
|||||||
// MARK: - API
|
// MARK: - API
|
||||||
|
|
||||||
public func createAccount(type: AccountType) -> Account {
|
public func createAccount(type: AccountType) -> Account {
|
||||||
let accountID = UUID().uuidString
|
let accountID = type == .cloudKit ? "iCloud" : UUID().uuidString
|
||||||
let accountFolder = (accountsFolder as NSString).appendingPathComponent("\(type.rawValue)_\(accountID)")
|
let accountFolder = (accountsFolder as NSString).appendingPathComponent("\(type.rawValue)_\(accountID)")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
216
Frameworks/Account/CloudKit/CloudKitAppDelegate.swift
Normal file
216
Frameworks/Account/CloudKit/CloudKitAppDelegate.swift
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
//
|
||||||
|
// CloudKitAppDelegate.swift
|
||||||
|
// Account
|
||||||
|
//
|
||||||
|
// Created by Maurice Parker on 3/18/20.
|
||||||
|
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import RSCore
|
||||||
|
import RSParser
|
||||||
|
import Articles
|
||||||
|
import RSWeb
|
||||||
|
|
||||||
|
public enum CloudKitAccountDelegateError: String, Error {
|
||||||
|
case invalidParameter = "An invalid parameter was used."
|
||||||
|
}
|
||||||
|
|
||||||
|
final class CloudKitAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
|
let behaviors: AccountBehaviors = []
|
||||||
|
let isOPMLImportInProgress = false
|
||||||
|
|
||||||
|
let server: String? = nil
|
||||||
|
var credentials: Credentials?
|
||||||
|
var accountMetadata: AccountMetadata?
|
||||||
|
|
||||||
|
private let refresher = LocalAccountRefresher()
|
||||||
|
|
||||||
|
var refreshProgress: DownloadProgress {
|
||||||
|
return refresher.progress
|
||||||
|
}
|
||||||
|
|
||||||
|
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
refresher.refreshFeeds(account.flattenedWebFeeds()) {
|
||||||
|
account.metadata.lastArticleFetchEndTime = Date()
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
var fileData: Data?
|
||||||
|
|
||||||
|
do {
|
||||||
|
fileData = try Data(contentsOf: opmlFile)
|
||||||
|
} catch {
|
||||||
|
completion(.failure(error))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let opmlData = fileData else {
|
||||||
|
completion(.success(()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let parserData = ParserData(url: opmlFile.absoluteString, data: opmlData)
|
||||||
|
var opmlDocument: RSOPMLDocument?
|
||||||
|
|
||||||
|
do {
|
||||||
|
opmlDocument = try RSOPMLParser.parseOPML(with: parserData)
|
||||||
|
} catch {
|
||||||
|
completion(.failure(error))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let loadDocument = opmlDocument else {
|
||||||
|
completion(.success(()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let children = loadDocument.children else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
BatchUpdate.shared.perform {
|
||||||
|
account.loadOPMLItems(children, parentFolder: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(.success(()))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func createWebFeed(for account: Account, url urlString: String, name: String?, container: Container, completion: @escaping (Result<WebFeed, Error>) -> Void) {
|
||||||
|
guard let url = URL(string: urlString) else {
|
||||||
|
completion(.failure(LocalAccountDelegateError.invalidParameter))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||||
|
FeedFinder.find(url: url) { result in
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success(let feedSpecifiers):
|
||||||
|
guard let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers),
|
||||||
|
let url = URL(string: bestFeedSpecifier.urlString) else {
|
||||||
|
self.refreshProgress.completeTask()
|
||||||
|
completion(.failure(AccountError.createErrorNotFound))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if account.hasWebFeed(withURL: bestFeedSpecifier.urlString) {
|
||||||
|
self.refreshProgress.completeTask()
|
||||||
|
completion(.failure(AccountError.createErrorAlreadySubscribed))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
|
||||||
|
|
||||||
|
InitialFeedDownloader.download(url) { parsedFeed in
|
||||||
|
self.refreshProgress.completeTask()
|
||||||
|
|
||||||
|
if let parsedFeed = parsedFeed {
|
||||||
|
account.update(feed, with: parsedFeed, {_ in})
|
||||||
|
}
|
||||||
|
|
||||||
|
feed.editedName = name
|
||||||
|
|
||||||
|
container.addWebFeed(feed)
|
||||||
|
completion(.success(feed))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure:
|
||||||
|
self.refreshProgress.completeTask()
|
||||||
|
completion(.failure(AccountError.createErrorNotFound))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func renameWebFeed(for account: Account, with feed: WebFeed, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
feed.editedName = name
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeWebFeed(for account: Account, with feed: WebFeed, from container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
container.removeWebFeed(feed)
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func moveWebFeed(for account: Account, with feed: WebFeed, from: Container, to: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
from.removeWebFeed(feed)
|
||||||
|
to.addWebFeed(feed)
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func addWebFeed(for account: Account, with feed: WebFeed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
container.addWebFeed(feed)
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreWebFeed(for account: Account, feed: WebFeed, container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
container.addWebFeed(feed)
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func addFolder(for account: Account, name: String, completion: @escaping (Result<Folder, Error>) -> Void) {
|
||||||
|
if let folder = account.ensureFolder(with: name) {
|
||||||
|
completion(.success(folder))
|
||||||
|
} else {
|
||||||
|
completion(.failure(FeedbinAccountDelegateError.invalidParameter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
folder.name = name
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
account.removeFolder(folder)
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
account.addFolder(folder)
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func markArticles(for account: Account, articles: Set<Article>, statusKey: ArticleStatus.Key, flag: Bool) -> Set<Article>? {
|
||||||
|
return try? account.update(articles, statusKey: statusKey, flag: flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func accountDidInitialize(_ account: Account) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func accountWillBeDeleted(_ account: Account) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: (Result<Credentials?, Error>) -> Void) {
|
||||||
|
return completion(.success(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Suspend and Resume (for iOS)
|
||||||
|
|
||||||
|
func suspendNetwork() {
|
||||||
|
refresher.suspend()
|
||||||
|
}
|
||||||
|
|
||||||
|
func suspendDatabase() {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
func resume() {
|
||||||
|
refresher.resume()
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,10 @@ struct AppAssets {
|
|||||||
return RSImage(named: .timelineStar)
|
return RSImage(named: .timelineStar)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
static var accountCloudKit: RSImage! = {
|
||||||
|
return RSImage(named: "accountCloudKit")
|
||||||
|
}()
|
||||||
|
|
||||||
static var accountLocal: RSImage! = {
|
static var accountLocal: RSImage! = {
|
||||||
return RSImage(named: "accountLocal")
|
return RSImage(named: "accountLocal")
|
||||||
}()
|
}()
|
||||||
@ -129,6 +133,8 @@ struct AppAssets {
|
|||||||
switch accountType {
|
switch accountType {
|
||||||
case .onMyMac:
|
case .onMyMac:
|
||||||
return AppAssets.accountLocal
|
return AppAssets.accountLocal
|
||||||
|
case .cloudKit:
|
||||||
|
return AppAssets.accountCloudKit
|
||||||
case .feedbin:
|
case .feedbin:
|
||||||
return AppAssets.accountFeedbin
|
return AppAssets.accountFeedbin
|
||||||
case .feedly:
|
case .feedly:
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// AccountsAddCloudKitWindowController.swift
|
||||||
|
// NetNewsWire
|
||||||
|
//
|
||||||
|
// Created by Maurice Parker on 3/18/20.
|
||||||
|
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Account
|
||||||
|
|
||||||
|
class AccountsAddCloudKitWindowController: NSWindowController {
|
||||||
|
|
||||||
|
private weak var hostWindow: NSWindow?
|
||||||
|
|
||||||
|
convenience init() {
|
||||||
|
self.init(windowNibName: NSNib.Name("AccountsAddCloudKit"))
|
||||||
|
}
|
||||||
|
|
||||||
|
override func windowDidLoad() {
|
||||||
|
super.windowDidLoad()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: API
|
||||||
|
|
||||||
|
func runSheetOnWindow(_ hostWindow: NSWindow, completion: ((NSApplication.ModalResponse) -> Void)? = nil) {
|
||||||
|
self.hostWindow = hostWindow
|
||||||
|
hostWindow.beginSheet(window!, completionHandler: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Actions
|
||||||
|
|
||||||
|
@IBAction func cancel(_ sender: Any) {
|
||||||
|
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.cancel)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func create(_ sender: Any) {
|
||||||
|
_ = AccountManager.shared.createAccount(type: .cloudKit)
|
||||||
|
hostWindow!.endSheet(window!, returnCode: NSApplication.ModalResponse.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,7 +16,11 @@ class AccountsAddViewController: NSViewController {
|
|||||||
|
|
||||||
private var accountsAddWindowController: NSWindowController?
|
private var accountsAddWindowController: NSWindowController?
|
||||||
|
|
||||||
private let addableAccountTypes: [AccountType] = [.onMyMac, .feedbin, .feedly, .feedWrangler, .freshRSS]
|
#if DEBUG
|
||||||
|
private var addableAccountTypes: [AccountType] = [.onMyMac, .cloudKit, .feedbin, .feedly, .feedWrangler, .freshRSS]
|
||||||
|
#else
|
||||||
|
private var addableAccountTypes: [AccountType] = [.onMyMac, .feedbin, .feedly]
|
||||||
|
#endif
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
super.init(nibName: "AccountsAdd", bundle: nil)
|
super.init(nibName: "AccountsAdd", bundle: nil)
|
||||||
@ -27,12 +31,10 @@ class AccountsAddViewController: NSViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
tableView.dataSource = self
|
tableView.dataSource = self
|
||||||
tableView.delegate = self
|
tableView.delegate = self
|
||||||
|
removeCloudKitIfNecessary()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -63,6 +65,9 @@ extension AccountsAddViewController: NSTableViewDelegate {
|
|||||||
case .onMyMac:
|
case .onMyMac:
|
||||||
cell.accountNameLabel?.stringValue = Account.defaultLocalAccountName
|
cell.accountNameLabel?.stringValue = Account.defaultLocalAccountName
|
||||||
cell.accountImageView?.image = AppAssets.accountLocal
|
cell.accountImageView?.image = AppAssets.accountLocal
|
||||||
|
case .cloudKit:
|
||||||
|
cell.accountNameLabel?.stringValue = NSLocalizedString("iCloud", comment: "iCloud")
|
||||||
|
cell.accountImageView?.image = AppAssets.accountCloudKit
|
||||||
case .feedbin:
|
case .feedbin:
|
||||||
cell.accountNameLabel?.stringValue = NSLocalizedString("Feedbin", comment: "Feedbin")
|
cell.accountNameLabel?.stringValue = NSLocalizedString("Feedbin", comment: "Feedbin")
|
||||||
cell.accountImageView?.image = AppAssets.accountFeedbin
|
cell.accountImageView?.image = AppAssets.accountFeedbin
|
||||||
@ -95,6 +100,15 @@ extension AccountsAddViewController: NSTableViewDelegate {
|
|||||||
let accountsAddLocalWindowController = AccountsAddLocalWindowController()
|
let accountsAddLocalWindowController = AccountsAddLocalWindowController()
|
||||||
accountsAddLocalWindowController.runSheetOnWindow(self.view.window!)
|
accountsAddLocalWindowController.runSheetOnWindow(self.view.window!)
|
||||||
accountsAddWindowController = accountsAddLocalWindowController
|
accountsAddWindowController = accountsAddLocalWindowController
|
||||||
|
case .cloudKit:
|
||||||
|
let accountsAddCloudKitWindowController = AccountsAddCloudKitWindowController()
|
||||||
|
accountsAddCloudKitWindowController.runSheetOnWindow(self.view.window!) { response in
|
||||||
|
if response == NSApplication.ModalResponse.OK {
|
||||||
|
self.removeCloudKitIfNecessary()
|
||||||
|
self.tableView.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accountsAddWindowController = accountsAddCloudKitWindowController
|
||||||
case .feedbin:
|
case .feedbin:
|
||||||
let accountsFeedbinWindowController = AccountsFeedbinWindowController()
|
let accountsFeedbinWindowController = AccountsFeedbinWindowController()
|
||||||
accountsFeedbinWindowController.runSheetOnWindow(self.view.window!)
|
accountsFeedbinWindowController.runSheetOnWindow(self.view.window!)
|
||||||
@ -142,3 +156,13 @@ extension AccountsAddViewController: OAuthAccountAuthorizationOperationDelegate
|
|||||||
view.window?.presentError(error)
|
view.window?.presentError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private extension AccountsAddViewController {
|
||||||
|
func removeCloudKitIfNecessary() {
|
||||||
|
if let index = AccountManager.shared.activeAccounts.firstIndex(where: { $0.type == .cloudKit }) {
|
||||||
|
addableAccountTypes.remove(at: index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
15
Mac/Resources/Assets.xcassets/accountCloudKit.imageset/Contents.json
vendored
Normal file
15
Mac/Resources/Assets.xcassets/accountCloudKit.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "icloud.pdf"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
BIN
Mac/Resources/Assets.xcassets/accountCloudKit.imageset/icloud.pdf
vendored
Normal file
BIN
Mac/Resources/Assets.xcassets/accountCloudKit.imageset/icloud.pdf
vendored
Normal file
Binary file not shown.
@ -159,6 +159,8 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
|
|||||||
switch self.account.type {
|
switch self.account.type {
|
||||||
case .onMyMac:
|
case .onMyMac:
|
||||||
osType = "Locl"
|
osType = "Locl"
|
||||||
|
case .cloudKit:
|
||||||
|
osType = "Clkt"
|
||||||
case .feedly:
|
case .feedly:
|
||||||
osType = "Fdly"
|
osType = "Fdly"
|
||||||
case .feedbin:
|
case .feedbin:
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
5103A9982421643300410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9972421643300410853 /* blank.html */; };
|
5103A9982421643300410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9972421643300410853 /* blank.html */; };
|
||||||
5103A9992421643300410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9972421643300410853 /* blank.html */; };
|
5103A9992421643300410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9972421643300410853 /* blank.html */; };
|
||||||
5103A9B424216A4200410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9B324216A4200410853 /* blank.html */; };
|
5103A9B424216A4200410853 /* blank.html in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9B324216A4200410853 /* blank.html */; };
|
||||||
|
5103A9F4242258C600410853 /* AccountsAddCloudKit.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9DA242258C600410853 /* AccountsAddCloudKit.xib */; };
|
||||||
|
5103A9F5242258C600410853 /* AccountsAddCloudKit.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5103A9DA242258C600410853 /* AccountsAddCloudKit.xib */; };
|
||||||
|
5103A9F724225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5103A9F624225E4C00410853 /* AccountsAddCloudKitWindowController.swift */; };
|
||||||
|
5103A9F824225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5103A9F624225E4C00410853 /* AccountsAddCloudKitWindowController.swift */; };
|
||||||
5108F6B62375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
5108F6B62375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
||||||
5108F6B72375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
5108F6B72375E612001ABC45 /* CacheCleaner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6B52375E612001ABC45 /* CacheCleaner.swift */; };
|
||||||
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
|
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
|
||||||
@ -1255,6 +1259,8 @@
|
|||||||
49F40DEF2335B71000552BF4 /* newsfoot.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = newsfoot.js; sourceTree = "<group>"; };
|
49F40DEF2335B71000552BF4 /* newsfoot.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = newsfoot.js; sourceTree = "<group>"; };
|
||||||
5103A9972421643300410853 /* blank.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = blank.html; sourceTree = "<group>"; };
|
5103A9972421643300410853 /* blank.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = blank.html; sourceTree = "<group>"; };
|
||||||
5103A9B324216A4200410853 /* blank.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = blank.html; sourceTree = "<group>"; };
|
5103A9B324216A4200410853 /* blank.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = blank.html; sourceTree = "<group>"; };
|
||||||
|
5103A9DA242258C600410853 /* AccountsAddCloudKit.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountsAddCloudKit.xib; sourceTree = "<group>"; };
|
||||||
|
5103A9F624225E4C00410853 /* AccountsAddCloudKitWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddCloudKitWindowController.swift; sourceTree = "<group>"; };
|
||||||
5108F6B52375E612001ABC45 /* CacheCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheCleaner.swift; sourceTree = "<group>"; };
|
5108F6B52375E612001ABC45 /* CacheCleaner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheCleaner.swift; sourceTree = "<group>"; };
|
||||||
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerViewController.swift; sourceTree = "<group>"; };
|
5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineCustomizerViewController.swift; sourceTree = "<group>"; };
|
||||||
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
|
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -2616,6 +2622,8 @@
|
|||||||
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */,
|
55E15BCA229D65A900D6602A /* AccountsReaderAPIWindowController.swift */,
|
||||||
5144EA352279FC3D00D19003 /* AccountsAddLocal.xib */,
|
5144EA352279FC3D00D19003 /* AccountsAddLocal.xib */,
|
||||||
5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */,
|
5144EA372279FC6200D19003 /* AccountsAddLocalWindowController.swift */,
|
||||||
|
5103A9DA242258C600410853 /* AccountsAddCloudKit.xib */,
|
||||||
|
5103A9F624225E4C00410853 /* AccountsAddCloudKitWindowController.swift */,
|
||||||
);
|
);
|
||||||
path = Accounts;
|
path = Accounts;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -3468,6 +3476,7 @@
|
|||||||
65ED405B235DEF6C0081F399 /* KeyboardShortcuts.html in Resources */,
|
65ED405B235DEF6C0081F399 /* KeyboardShortcuts.html in Resources */,
|
||||||
65ED405C235DEF6C0081F399 /* ImportOPMLSheet.xib in Resources */,
|
65ED405C235DEF6C0081F399 /* ImportOPMLSheet.xib in Resources */,
|
||||||
65ED405D235DEF6C0081F399 /* SidebarKeyboardShortcuts.plist in Resources */,
|
65ED405D235DEF6C0081F399 /* SidebarKeyboardShortcuts.plist in Resources */,
|
||||||
|
5103A9F5242258C600410853 /* AccountsAddCloudKit.xib in Resources */,
|
||||||
65ED405E235DEF6C0081F399 /* DefaultFeeds.opml in Resources */,
|
65ED405E235DEF6C0081F399 /* DefaultFeeds.opml in Resources */,
|
||||||
65ED405F235DEF6C0081F399 /* Preferences.storyboard in Resources */,
|
65ED405F235DEF6C0081F399 /* Preferences.storyboard in Resources */,
|
||||||
65ED4060235DEF6C0081F399 /* (null) in Resources */,
|
65ED4060235DEF6C0081F399 /* (null) in Resources */,
|
||||||
@ -3556,6 +3565,7 @@
|
|||||||
84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */,
|
84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */,
|
||||||
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */,
|
5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */,
|
||||||
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
|
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
|
||||||
|
5103A9F4242258C600410853 /* AccountsAddCloudKit.xib in Resources */,
|
||||||
84A3EE5F223B667F00557320 /* DefaultFeeds.opml in Resources */,
|
84A3EE5F223B667F00557320 /* DefaultFeeds.opml in Resources */,
|
||||||
849C78902362AAFC009A71E4 /* ExportOPMLSheet.xib in Resources */,
|
849C78902362AAFC009A71E4 /* ExportOPMLSheet.xib in Resources */,
|
||||||
84C9FC8222629E4800D921D6 /* Preferences.storyboard in Resources */,
|
84C9FC8222629E4800D921D6 /* Preferences.storyboard in Resources */,
|
||||||
@ -3778,6 +3788,7 @@
|
|||||||
65ED3FD6235DEF6C0081F399 /* MarkStatusCommand.swift in Sources */,
|
65ED3FD6235DEF6C0081F399 /* MarkStatusCommand.swift in Sources */,
|
||||||
65ED3FD7235DEF6C0081F399 /* NSApplication+Scriptability.swift in Sources */,
|
65ED3FD7235DEF6C0081F399 /* NSApplication+Scriptability.swift in Sources */,
|
||||||
65ED3FD8235DEF6C0081F399 /* NSView-Extensions.swift in Sources */,
|
65ED3FD8235DEF6C0081F399 /* NSView-Extensions.swift in Sources */,
|
||||||
|
5103A9F824225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */,
|
||||||
65ED3FD9235DEF6C0081F399 /* SidebarCell.swift in Sources */,
|
65ED3FD9235DEF6C0081F399 /* SidebarCell.swift in Sources */,
|
||||||
65ED3FDA235DEF6C0081F399 /* ArticleStatusSyncTimer.swift in Sources */,
|
65ED3FDA235DEF6C0081F399 /* ArticleStatusSyncTimer.swift in Sources */,
|
||||||
65ED3FDB235DEF6C0081F399 /* WebFeedTreeControllerDelegate.swift in Sources */,
|
65ED3FDB235DEF6C0081F399 /* WebFeedTreeControllerDelegate.swift in Sources */,
|
||||||
@ -4129,6 +4140,7 @@
|
|||||||
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */,
|
55E15BCC229D65A900D6602A /* AccountsReaderAPIWindowController.swift in Sources */,
|
||||||
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */,
|
5144EA382279FC6200D19003 /* AccountsAddLocalWindowController.swift in Sources */,
|
||||||
84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */,
|
84AD1EAA2031617300BC20B7 /* PasteboardFolder.swift in Sources */,
|
||||||
|
5103A9F724225E4C00410853 /* AccountsAddCloudKitWindowController.swift in Sources */,
|
||||||
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */,
|
5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */,
|
||||||
84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */,
|
84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */,
|
||||||
845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */,
|
845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user