Merge branch 'master' of https://github.com/brentsimmons/NetNewsWire
This commit is contained in:
commit
afd9783711
|
@ -399,6 +399,10 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
opmlFile.save()
|
||||
}
|
||||
|
||||
public func prepareForDeletion() {
|
||||
delegate.accountWillBeDeleted(self)
|
||||
}
|
||||
|
||||
func loadOPMLItems(_ items: [RSOPMLItem], parentFolder: Folder?) {
|
||||
var feedsToAdd = Set<WebFeed>()
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ protocol AccountDelegate {
|
|||
|
||||
// Called at the end of account’s init method.
|
||||
func accountDidInitialize(_ account: Account)
|
||||
|
||||
func accountWillBeDeleted(_ account: Account)
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void)
|
||||
|
||||
|
|
|
@ -138,6 +138,8 @@ public final class AccountManager: UnreadCountProvider {
|
|||
return
|
||||
}
|
||||
|
||||
account.prepareForDeletion()
|
||||
|
||||
accountsDictionary.removeValue(forKey: account.accountID)
|
||||
account.isDeleted = true
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ class FeedlyOperationTests: XCTestCase {
|
|||
func testOperationCancellationFlags() {
|
||||
let testOperation = TestOperation()
|
||||
testOperation.didCallMainExpectation = expectation(description: "Did Call Main")
|
||||
testOperation.didCallMainExpectation?.isInverted = true
|
||||
|
||||
let completionExpectation = expectation(description: "Operation Completed")
|
||||
testOperation.completionBlock = {
|
||||
|
|
|
@ -67,11 +67,13 @@ class FeedlySyncAllOperationTests: XCTestCase {
|
|||
}
|
||||
|
||||
let syncCompletionExpectation = expectation(description: "Did Finish Sync")
|
||||
syncCompletionExpectation.isInverted = true
|
||||
syncAll.syncCompletionHandler = { result in
|
||||
switch result {
|
||||
case .success:
|
||||
XCTFail("Expected failure.")
|
||||
XCTFail("Sync operation was cancelled, not successful.")
|
||||
case .failure:
|
||||
XCTFail("Sync operation should cancel silently.")
|
||||
break
|
||||
}
|
||||
syncCompletionExpectation.fulfill()
|
||||
|
|
|
@ -541,6 +541,9 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
|||
credentials = try? account.retrieveCredentials(type: .basic)
|
||||
}
|
||||
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
|
||||
let caller = FeedbinAPICaller(transport: transport)
|
||||
|
|
|
@ -486,6 +486,10 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
|||
operationQueue.addOperation(refreshAccessToken)
|
||||
}
|
||||
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
assertionFailure("An `account` instance should enqueue an \(FeedlyRefreshAccessTokenOperation.self) instead.")
|
||||
completion(.success(credentials))
|
||||
|
|
|
@ -21,8 +21,8 @@ class FeedlyOperation: Operation {
|
|||
func didFinish() {
|
||||
assert(Thread.isMainThread)
|
||||
assert(!isFinished, "Finished operation is attempting to finish again.")
|
||||
self.isExecutingOperation = false
|
||||
self.isFinishedOperation = true
|
||||
isExecutingOperation = false
|
||||
isFinishedOperation = true
|
||||
}
|
||||
|
||||
func didFinish(_ error: Error) {
|
||||
|
@ -33,16 +33,18 @@ class FeedlyOperation: Operation {
|
|||
}
|
||||
|
||||
override func start() {
|
||||
guard !isCancelled else {
|
||||
isExecutingOperation = false
|
||||
isFinishedOperation = true
|
||||
return
|
||||
}
|
||||
|
||||
isExecutingOperation = true
|
||||
DispatchQueue.main.async {
|
||||
self.main()
|
||||
}
|
||||
}
|
||||
|
||||
override func cancel() {
|
||||
super.cancel()
|
||||
}
|
||||
|
||||
override var isExecuting: Bool {
|
||||
return isExecutingOperation
|
||||
}
|
||||
|
|
|
@ -94,10 +94,12 @@ final class FeedlySyncAllOperation: FeedlyOperation {
|
|||
os_log(.debug, log: log, "Cancelling sync %{public}@", syncUUID.uuidString)
|
||||
self.operationQueue.cancelAllOperations()
|
||||
|
||||
syncCompletionHandler?(.failure(URLError(.cancelled)))
|
||||
syncCompletionHandler = nil
|
||||
super.cancel()
|
||||
|
||||
self.didFinish()
|
||||
didFinish()
|
||||
|
||||
// Operation should silently cancel.
|
||||
syncCompletionHandler = nil
|
||||
}
|
||||
|
||||
override func main() {
|
||||
|
|
|
@ -96,13 +96,15 @@ final class FeedlySyncStarredArticlesOperation: FeedlyOperation, FeedlyOperation
|
|||
}
|
||||
|
||||
override func cancel() {
|
||||
os_log(.debug, log: log, "Canceling sync starred articles")
|
||||
operationQueue.cancelAllOperations()
|
||||
super.cancel()
|
||||
didFinish()
|
||||
}
|
||||
|
||||
override func main() {
|
||||
guard !isCancelled else {
|
||||
didFinish()
|
||||
// override of cancel calls didFinish().
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -110,6 +112,11 @@ final class FeedlySyncStarredArticlesOperation: FeedlyOperation, FeedlyOperation
|
|||
}
|
||||
|
||||
func feedlyGetStreamContentsOperation(_ operation: FeedlyGetStreamContentsOperation, didGetContentsOf stream: FeedlyStream) {
|
||||
guard !isCancelled else {
|
||||
os_log(.debug, log: log, "Cancelled starred stream contents for %@", stream.id)
|
||||
return
|
||||
}
|
||||
|
||||
entryProvider.addEntries(from: operation)
|
||||
os_log(.debug, log: log, "Collecting %i items from %@", stream.items.count, stream.id)
|
||||
|
||||
|
|
|
@ -42,13 +42,15 @@ final class FeedlySyncStreamContentsOperation: FeedlyOperation, FeedlyOperationD
|
|||
}
|
||||
|
||||
override func cancel() {
|
||||
os_log(.debug, log: log, "Canceling sync stream contents")
|
||||
operationQueue.cancelAllOperations()
|
||||
super.cancel()
|
||||
didFinish()
|
||||
}
|
||||
|
||||
override func main() {
|
||||
guard !isCancelled else {
|
||||
didFinish()
|
||||
// override of cancel calls didFinish().
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -92,6 +94,11 @@ final class FeedlySyncStreamContentsOperation: FeedlyOperation, FeedlyOperationD
|
|||
}
|
||||
|
||||
func feedlyGetStreamContentsOperation(_ operation: FeedlyGetStreamContentsOperation, didGetContentsOf stream: FeedlyStream) {
|
||||
guard !isCancelled else {
|
||||
os_log(.debug, log: log, "Cancelled requesting page for %@", resource.id)
|
||||
return
|
||||
}
|
||||
|
||||
os_log(.debug, log: log, "Ingesting %i items from %@", stream.items.count, stream.id)
|
||||
|
||||
guard let continuation = stream.continuation else {
|
||||
|
|
|
@ -77,13 +77,15 @@ final class FeedlySyncUnreadStatusesOperation: FeedlyOperation, FeedlyOperationD
|
|||
}
|
||||
|
||||
override func cancel() {
|
||||
os_log(.debug, log: log, "Canceling sync unread statuses")
|
||||
operationQueue.cancelAllOperations()
|
||||
super.cancel()
|
||||
didFinish()
|
||||
}
|
||||
|
||||
override func main() {
|
||||
guard !isCancelled else {
|
||||
didFinish()
|
||||
// override of cancel calls didFinish().
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -91,6 +93,11 @@ final class FeedlySyncUnreadStatusesOperation: FeedlyOperation, FeedlyOperationD
|
|||
}
|
||||
|
||||
func feedlyGetStreamIdsOperation(_ operation: FeedlyGetStreamIdsOperation, didGet streamIds: FeedlyStreamIds) {
|
||||
guard !isCancelled else {
|
||||
os_log(.debug, log: log, "Cancelled unread stream ids.")
|
||||
return
|
||||
}
|
||||
|
||||
os_log(.debug, log: log, "Collecting %i unread article ids from %@", streamIds.ids.count, resource.id)
|
||||
unreadEntryIdsProvider.addEntryIds(from: operation)
|
||||
|
||||
|
|
|
@ -195,6 +195,9 @@ final class LocalAccountDelegate: AccountDelegate {
|
|||
|
||||
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))
|
||||
|
|
|
@ -418,6 +418,9 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
|||
credentials = try? account.retrieveCredentials(type: .readerAPIKey)
|
||||
}
|
||||
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
guard let endpoint = endpoint else {
|
||||
completion(.failure(TransportError.noURL))
|
||||
|
|
|
@ -28,6 +28,19 @@ final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate
|
|||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
private var hidesCredentialsButton: Bool {
|
||||
guard let account = account else {
|
||||
return true
|
||||
}
|
||||
switch account.type {
|
||||
case .onMyMac,
|
||||
.feedly:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
|
@ -35,7 +48,7 @@ final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate
|
|||
typeLabel.stringValue = account?.defaultName ?? ""
|
||||
nameTextField.stringValue = account?.name ?? ""
|
||||
activeButton.state = account?.isActive ?? false ? .on : .off
|
||||
credentialsButton.isHidden = account?.type ?? .onMyMac == .onMyMac
|
||||
credentialsButton.isHidden = hidesCredentialsButton
|
||||
}
|
||||
|
||||
func controlTextDidEndEditing(_ obj: Notification) {
|
||||
|
@ -66,8 +79,6 @@ final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate
|
|||
accountsFreshRSSWindowController.account = account
|
||||
accountsFreshRSSWindowController.runSheetOnWindow(self.view.window!)
|
||||
accountsWindowController = accountsFreshRSSWindowController
|
||||
case .feedly:
|
||||
assertionFailure("Implement feedly logout window controller")
|
||||
break
|
||||
default:
|
||||
break
|
||||
|
|
|
@ -64,10 +64,20 @@ class AccountInspectorViewController: UITableViewController {
|
|||
}
|
||||
|
||||
@IBAction func deleteAccount(_ sender: Any) {
|
||||
let title = NSLocalizedString("Delete Account", comment: "Delete Account")
|
||||
let message = NSLocalizedString("Are you sure you want to delete this account? This can not be undone.", comment: "Delete Account")
|
||||
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
guard let account = account else {
|
||||
return
|
||||
}
|
||||
|
||||
let title = NSLocalizedString("Delete Account", comment: "Delete Account")
|
||||
let message: String = {
|
||||
switch account.type {
|
||||
case .feedly:
|
||||
return NSLocalizedString("Are you sure you want to delete this account? NetNewsWire will no longer be able to access articles and feeds unless the account is added again.", comment: "Log Out and Delete Account")
|
||||
default:
|
||||
return NSLocalizedString("Are you sure you want to delete this account? This can not be undone.", comment: "Delete Account")
|
||||
}
|
||||
}()
|
||||
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
let cancelTitle = NSLocalizedString("Cancel", comment: "Cancel")
|
||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .cancel)
|
||||
alertController.addAction(cancelAction)
|
||||
|
@ -86,19 +96,31 @@ class AccountInspectorViewController: UITableViewController {
|
|||
|
||||
present(alertController, animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Table View
|
||||
|
||||
extension AccountInspectorViewController {
|
||||
|
||||
var hidesCredentialsSection: Bool {
|
||||
guard let account = account else {
|
||||
return true
|
||||
}
|
||||
switch account.type {
|
||||
case .onMyMac,
|
||||
.feedly:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
guard let account = account else { return 0 }
|
||||
|
||||
if account == AccountManager.shared.defaultAccount {
|
||||
return 1
|
||||
} else if account.type == .onMyMac {
|
||||
} else if hidesCredentialsSection {
|
||||
return 2
|
||||
} else {
|
||||
return super.numberOfSections(in: tableView)
|
||||
|
@ -124,7 +146,7 @@ extension AccountInspectorViewController {
|
|||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell: UITableViewCell
|
||||
|
||||
if indexPath.section == 1, let account = account, account.type == .onMyMac {
|
||||
if indexPath.section == 1, hidesCredentialsSection {
|
||||
cell = super.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 2))
|
||||
} else {
|
||||
cell = super.tableView(tableView, cellForRowAt: indexPath)
|
||||
|
|
Loading…
Reference in New Issue