@@ -9,13 +9,16 @@ class PasswordViewController: LoginViewController {
99
1010 @IBOutlet private weak var tableView : UITableView !
1111 @IBOutlet var bottomContentConstraint : NSLayoutConstraint ?
12+ @IBOutlet private weak var secondaryButton : NUXButton !
1213
1314 private weak var passwordField : UITextField ?
1415 private var rows = [ Row] ( )
1516 private var errorMessage : String ?
1617 private var shouldChangeVoiceOverFocus : Bool = false
1718 private var loginLinkCell : TextLinkButtonTableViewCell ?
1819
20+ private let isMagicLinkShownAsSecondaryAction : Bool = WordPressAuthenticator . shared. configuration. isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen
21+
1922 /// Depending on where we're coming from, this screen needs to track a password challenge
2023 /// (if logging on with a Social account) or not (if logging in through WP.com).
2124 ///
@@ -51,6 +54,7 @@ class PasswordViewController: LoginViewController {
5154 defaultTableViewMargin = tableViewLeadingConstraint? . constant ?? 0
5255 setTableViewMargins ( forWidth: view. frame. width)
5356
57+ configureLoginWithMagicLinkButton ( )
5458 localizePrimaryButton ( )
5559 registerTableViewCells ( )
5660 loadRows ( )
@@ -174,7 +178,7 @@ class PasswordViewController: LoginViewController {
174178
175179 // Is everything filled out?
176180 if !loginFields. validateFieldsPopulatedForSignin ( ) {
177- let errorMsg = Constants . missingInfoError
181+ let errorMsg = Localization . missingInfoError
178182 displayError ( message: errorMsg, moveVoiceOverFocus: true )
179183
180184 return
@@ -248,6 +252,50 @@ extension PasswordViewController: NUXKeyboardResponder {
248252
249253}
250254
255+ // MARK: - Magic Link
256+
257+ private extension PasswordViewController {
258+ func configureLoginWithMagicLinkButton( ) {
259+ if isMagicLinkShownAsSecondaryAction {
260+ secondaryButton. setTitle ( Localization . loginWithMagicLink, for: . normal)
261+ secondaryButton. accessibilityIdentifier = AccessibilityIdentifier . loginWithMagicLink
262+ secondaryButton. on ( . touchUpInside) { [ weak self] _ in
263+ Task { @MainActor [ weak self] in
264+ guard let self = self else { return }
265+ self . secondaryButton. isEnabled = false
266+ await self . loginWithMagicLink ( )
267+ self . secondaryButton. isEnabled = true
268+ }
269+ }
270+ } else {
271+ secondaryButton. isHidden = true
272+ }
273+ }
274+
275+ func loginWithMagicLink( ) async {
276+ tracker. track ( click: . requestMagicLink)
277+ loginFields. meta. emailMagicLinkSource = . login
278+
279+ configureViewLoading ( true )
280+ let result = await MagicLinkRequester ( ) . requestMagicLink ( email: loginFields. username, jetpackLogin: loginFields. meta. jetpackLogin)
281+ switch result {
282+ case . success:
283+ didRequestAuthenticationLink ( )
284+ case . failure( let error) :
285+ switch error {
286+ case MagicLinkRequester . MagicLinkRequestError. invalidEmail:
287+ DDLogError ( " Attempted to request authentication link, but the email address did not appear valid. " )
288+ let alert = buildInvalidEmailAlert ( )
289+ present ( alert, animated: true , completion: nil )
290+ default :
291+ tracker. track ( failure: error. localizedDescription)
292+ displayError ( error as NSError , sourceTag: sourceTag)
293+ }
294+ }
295+ configureViewLoading ( false )
296+ }
297+ }
298+
251299// MARK: - Table Management
252300
253301private extension PasswordViewController {
@@ -284,7 +332,10 @@ private extension PasswordViewController {
284332 }
285333
286334 rows. append ( . forgotPassword)
287- rows. append ( . sendMagicLink)
335+
336+ if !isMagicLinkShownAsSecondaryAction {
337+ rows. append ( . sendMagicLink)
338+ }
288339 }
289340
290341 /// Configure cells.
@@ -394,7 +445,7 @@ private extension PasswordViewController {
394445 cell. configureButton ( text: WordPressAuthenticator . shared. displayStrings. getLoginLinkButtonTitle,
395446 accessibilityTrait: . link,
396447 showBorder: true )
397- cell. accessibilityIdentifier = " Get Login Link Button "
448+ cell. accessibilityIdentifier = AccessibilityIdentifier . loginWithMagicLink
398449
399450 // Save reference to the login link cell so it can be enabled/disabled.
400451 loginLinkCell = cell
@@ -406,8 +457,9 @@ private extension PasswordViewController {
406457
407458 cell. enableButton ( false )
408459
409- self . tracker. track ( click: . requestMagicLink)
410- self . requestAuthenticationLink ( )
460+ Task { @MainActor [ weak self] in
461+ await self ? . loginWithMagicLink ( )
462+ }
411463 }
412464 }
413465
@@ -441,40 +493,11 @@ private extension PasswordViewController {
441493 submitButton as Any
442494 ]
443495
444- UIAccessibility . post ( notification: . screenChanged, argument: passwordField)
445- }
446-
447- /// Makes the call to request a magic authentication link be emailed to the user.
448- ///
449- func requestAuthenticationLink( ) {
450- loginFields. meta. emailMagicLinkSource = . login
451-
452- let email = loginFields. username
453- guard email. isValidEmail ( ) else {
454- DDLogError ( " Attempted to request authentication link, but the email address did not appear valid. " )
455- let alert = buildInvalidEmailAlert ( )
456- present ( alert, animated: true , completion: nil )
457- return
496+ if isMagicLinkShownAsSecondaryAction {
497+ view. accessibilityElements? . append ( secondaryButton as Any )
458498 }
459499
460- configureViewLoading ( true )
461- let service = WordPressComAccountService ( )
462- service. requestAuthenticationLink ( for: email,
463- jetpackLogin: loginFields. meta. jetpackLogin,
464- success: { [ weak self] in
465- self ? . didRequestAuthenticationLink ( )
466- self ? . configureViewLoading ( false )
467-
468- } , failure: { [ weak self] ( error: Error ) in
469- guard let self = self else {
470- return
471- }
472-
473- self . tracker. track ( failure: error. localizedDescription)
474-
475- self . displayError ( error as NSError , sourceTag: self . sourceTag)
476- self . configureViewLoading ( false )
477- } )
500+ UIAccessibility . post ( notification: . screenChanged, argument: passwordField)
478501 }
479502
480503 /// When a magic link successfully sends, navigate the user to the next step.
@@ -541,11 +564,19 @@ private extension PasswordViewController {
541564 }
542565 }
543566 }
567+ }
544568
545- /// Constants
569+ private extension PasswordViewController {
570+ /// Localization constants
546571 ///
547- struct Constants {
572+ enum Localization {
548573 static let missingInfoError = NSLocalizedString ( " Please fill out all the fields " ,
549574 comment: " A short prompt asking the user to properly fill out all login fields. " )
575+ static let loginWithMagicLink = NSLocalizedString ( " Or log in with magic link " ,
576+ comment: " The button title for a secondary call-to-action button on the password screen. When the user wants to try sending a magic link instead of entering a password. " )
577+ }
578+
579+ enum AccessibilityIdentifier {
580+ static let loginWithMagicLink = " Get Login Link Button "
550581 }
551582}
0 commit comments