From 68fd7e74110c4351b9e5dc5033e05a84931a21df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiel=20Gillard=20=F0=9F=A4=AA?= Date: Wed, 23 Sep 2020 14:20:53 +1000 Subject: [PATCH] Clarify the UX of authorizing a Feedly account by directing users towards their default web browser #2444 --- .../OAuthAccountAuthorizationOperation.swift | 20 +++++++++-- .../Accounts/AccountsAddViewController.swift | 35 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/Frameworks/Account/Feedly/OAuthAccountAuthorizationOperation.swift b/Frameworks/Account/Feedly/OAuthAccountAuthorizationOperation.swift index 7c72d34d1..4378bedc5 100644 --- a/Frameworks/Account/Feedly/OAuthAccountAuthorizationOperation.swift +++ b/Frameworks/Account/Feedly/OAuthAccountAuthorizationOperation.swift @@ -71,10 +71,26 @@ public enum OAuthAccountAuthorizationOperationError: LocalizedError { self?.didEndAuthentication(url: url, error: error) } } - self.session = session + session.presentationContextProvider = self - session.start() + guard session.start() else { + + /// Documentation does not say on why `ASWebAuthenticationSession.start` or `canStart` might return false. + /// Perhaps it has something to do with an inter-process communication failure? No browsers installed? No browsers that support web authentication? + struct UnableToStartASWebAuthenticationSessionError: LocalizedError { + let errorDescription: String? = NSLocalizedString("Unable to start a web authentication session with the default web browser.", + comment: "OAuth - error description - unable to authorize because ASWebAuthenticationSession did not start.") + let recoverySuggestion: String? = NSLocalizedString("Check your default web browser in System Preferences or change it to Safari and try again.", + comment: "OAuth - recovery suggestion - ensure browser selected supports web authentication.") + } + + didFinish(UnableToStartASWebAuthenticationSessionError()) + + return + } + + self.session = session } public func cancel() { diff --git a/Mac/Preferences/Accounts/AccountsAddViewController.swift b/Mac/Preferences/Accounts/AccountsAddViewController.swift index 3e40d33d7..ef6a2c441 100644 --- a/Mac/Preferences/Accounts/AccountsAddViewController.swift +++ b/Mac/Preferences/Accounts/AccountsAddViewController.swift @@ -106,6 +106,7 @@ extension AccountsAddViewController: AccountsAddTableCellViewDelegate { let accountsAddLocalWindowController = AccountsAddLocalWindowController() accountsAddLocalWindowController.runSheetOnWindow(self.view.window!) accountsAddWindowController = accountsAddLocalWindowController + case .cloudKit: let accountsAddCloudKitWindowController = AccountsAddCloudKitWindowController() accountsAddCloudKitWindowController.runSheetOnWindow(self.view.window!) { response in @@ -115,24 +116,32 @@ extension AccountsAddViewController: AccountsAddTableCellViewDelegate { } } accountsAddWindowController = accountsAddCloudKitWindowController + case .feedbin: let accountsFeedbinWindowController = AccountsFeedbinWindowController() accountsFeedbinWindowController.runSheetOnWindow(self.view.window!) accountsAddWindowController = accountsFeedbinWindowController + case .feedWrangler: let accountsFeedWranglerWindowController = AccountsFeedWranglerWindowController() accountsFeedWranglerWindowController.runSheetOnWindow(self.view.window!) accountsAddWindowController = accountsFeedWranglerWindowController + case .freshRSS: let accountsReaderAPIWindowController = AccountsReaderAPIWindowController() accountsReaderAPIWindowController.accountType = .freshRSS accountsReaderAPIWindowController.runSheetOnWindow(self.view.window!) accountsAddWindowController = accountsReaderAPIWindowController + case .feedly: let addAccount = OAuthAccountAuthorizationOperation(accountType: .feedly) addAccount.delegate = self addAccount.presentationAnchor = self.view.window! + + runAwaitingFeedlyLoginAlertModal(forLifetimeOf: addAccount) + MainThreadOperationQueue.shared.add(addAccount) + case .newsBlur: let accountsNewsBlurWindowController = AccountsNewsBlurWindowController() accountsNewsBlurWindowController.runSheetOnWindow(self.view.window!) @@ -141,6 +150,32 @@ extension AccountsAddViewController: AccountsAddTableCellViewDelegate { } + private func runAwaitingFeedlyLoginAlertModal(forLifetimeOf operation: OAuthAccountAuthorizationOperation) { + let alert = NSAlert() + alert.alertStyle = .informational + alert.messageText = NSLocalizedString("Waiting for access to Feedly", + comment: "Alert title when adding a Feedly account and waiting for authorization from the user.") + + alert.informativeText = NSLocalizedString("Your default web browser will open the Feedly login for you to authorize access.", + comment: "Alert informative text when adding a Feedly account and waiting for authorization from the user.") + + alert.addButton(withTitle: NSLocalizedString("Cancel", comment: "Cancel")) + + let attachedWindow = self.view.window! + + alert.beginSheetModal(for: attachedWindow) { response in + if response == .alertFirstButtonReturn { + operation.cancel() + } + } + + operation.completionBlock = { _ in + guard alert.window.isVisible else { + return + } + attachedWindow.endSheet(alert.window) + } + } } // MARK: OAuthAccountAuthorizationOperationDelegate