Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Commit d443c19

Browse files
authored
Merge pull request #691 from wordpress-mobile/wcios/simplified-login-flow-i1
New configs and updates for simplified login flow i1
2 parents c77e998 + 3c70e88 commit d443c19

File tree

9 files changed

+210
-61
lines changed

9 files changed

+210
-61
lines changed

WordPressAuthenticator.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Pod::Spec.new do |s|
44
s.name = 'WordPressAuthenticator'
5-
s.version = '3.2.2'
5+
s.version = '3.3.0-beta.1'
66

77
s.summary = 'WordPressAuthenticator implements an easy and elegant way to authenticate your WordPress Apps.'
88
s.description = <<-DESC

WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ public struct WordPressAuthenticatorConfiguration {
112112
/// If disabled, the alternative magic link action on the password screen is shown below the reset password action.
113113
let isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen: Bool
114114

115+
/// If enabled, the Prologue screen will display only the entry point for WPCom login and no site address login.
116+
///
117+
let enableWPComLoginOnlyInPrologue: Bool
118+
119+
/// If enabled, an entry point to the site creation flow will be added to the bottom button of the prologue screen of simplified login.
120+
///
121+
let enableSiteCreation: Bool
122+
123+
/// If enabled, social login will be display at the bottom of the WPCom login screen.
124+
///
125+
let enableSocialLogin: Bool
126+
127+
/// If enabled, there will be a border around the email label on the WPCom password screen.
128+
///
129+
let emphasizeEmailForWPComPassword: Bool
130+
131+
/// The optional instructions for WPCom password.
132+
///
133+
let wpcomPasswordInstructions: String?
134+
115135
/// Designated Initializer
116136
///
117137
public init (wpcomClientId: String,
@@ -136,7 +156,12 @@ public struct WordPressAuthenticatorConfiguration {
136156
enableSiteCredentialsLoginForSelfHostedSites: Bool = false,
137157
isWPComLoginRequiredForSiteCredentialsLogin: Bool = false,
138158
isWPComMagicLinkPreferredToPassword: Bool = false,
139-
isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen: Bool = false) {
159+
isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen: Bool = false,
160+
enableWPComLoginOnlyInPrologue: Bool = false,
161+
enableSiteCreation: Bool = false,
162+
enableSocialLogin: Bool = false,
163+
emphasizeEmailForWPComPassword: Bool = false,
164+
wpcomPasswordInstructions: String? = nil) {
140165

141166
self.wpcomClientId = wpcomClientId
142167
self.wpcomSecret = wpcomSecret
@@ -161,5 +186,10 @@ public struct WordPressAuthenticatorConfiguration {
161186
self.isWPComLoginRequiredForSiteCredentialsLogin = isWPComLoginRequiredForSiteCredentialsLogin
162187
self.isWPComMagicLinkPreferredToPassword = isWPComMagicLinkPreferredToPassword
163188
self.isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen = isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen
189+
self.enableWPComLoginOnlyInPrologue = enableWPComLoginOnlyInPrologue
190+
self.enableSiteCreation = enableSiteCreation
191+
self.enableSocialLogin = enableSocialLogin
192+
self.emphasizeEmailForWPComPassword = emphasizeEmailForWPComPassword
193+
self.wpcomPasswordInstructions = wpcomPasswordInstructions
164194
}
165195
}

WordPressAuthenticator/Authenticator/WordPressAuthenticatorDelegateProtocol.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ public protocol WordPressAuthenticatorDelegate: AnyObject {
105105
///
106106
func troubleshootSite(_ siteInfo: WordPressComSiteInfo?, in navigationController: UINavigationController?)
107107

108+
/// Signals to the Host App to navigate to the site creation flow.
109+
/// This method is currently used only in the simplified login flow
110+
/// when the configs `enableSimplifiedLoginI1` and `enableSiteCreationForSimplifiedLoginI1` is enabled
111+
///
112+
/// - Parameters:
113+
/// - navigationController: the current navigation stack of the login flow.
114+
///
115+
func showSiteCreation(in navigationController: UINavigationController)
116+
108117
/// Signals the Host App that a given Analytics Event has occurred.
109118
///
110119
func track(event: WPAnalyticsStat)
@@ -124,4 +133,8 @@ public extension WordPressAuthenticatorDelegate {
124133
func troubleshootSite(_ siteInfo: WordPressComSiteInfo?, in navigationController: UINavigationController?) {
125134
// No-op
126135
}
136+
137+
func showSiteCreation(in navigationController: UINavigationController) {
138+
// No-op
139+
}
127140
}

WordPressAuthenticator/Authenticator/WordPressAuthenticatorDisplayStrings.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public struct WordPressAuthenticatorDisplayStrings {
5151
public let loginTermsOfService: String
5252
public let signupTermsOfService: String
5353
public let whatIsWPComLinkTitle: String
54+
public let siteCreationButtonTitle: String
5455

5556
/// Placeholder text for textfields.
5657
///
@@ -95,6 +96,7 @@ public struct WordPressAuthenticatorDisplayStrings {
9596
loginTermsOfService: String = defaultStrings.loginTermsOfService,
9697
signupTermsOfService: String = defaultStrings.signupTermsOfService,
9798
whatIsWPComLinkTitle: String = defaultStrings.whatIsWPComLinkTitle,
99+
siteCreationButtonTitle: String = defaultStrings.siteCreationButtonTitle,
98100
getStartedTitle: String = defaultStrings.getStartedTitle,
99101
logInTitle: String = defaultStrings.logInTitle,
100102
signUpTitle: String = defaultStrings.signUpTitle,
@@ -137,6 +139,7 @@ public struct WordPressAuthenticatorDisplayStrings {
137139
self.loginTermsOfService = loginTermsOfService
138140
self.signupTermsOfService = signupTermsOfService
139141
self.whatIsWPComLinkTitle = whatIsWPComLinkTitle
142+
self.siteCreationButtonTitle = siteCreationButtonTitle
140143
self.getStartedTitle = getStartedTitle
141144
self.logInTitle = logInTitle
142145
self.signUpTitle = signUpTitle
@@ -213,6 +216,8 @@ public extension WordPressAuthenticatorDisplayStrings {
213216
signupTermsOfService: NSLocalizedString("If you continue with Apple or Google and don't already have a WordPress.com account, you are creating an account and you agree to our _Terms of Service_.", comment: "Legal disclaimer for signing up. The underscores _..._ denote underline."),
214217
whatIsWPComLinkTitle: NSLocalizedString("What is WordPress.com?",
215218
comment: "Navigates to page with details about What is WordPress.com."),
219+
siteCreationButtonTitle: NSLocalizedString("Create a Site",
220+
comment: "Navigates to a new flow for site creation."),
216221
getStartedTitle: NSLocalizedString("Get Started",
217222
comment: "View title for initial auth views."),
218223
logInTitle: NSLocalizedString("Log In",

WordPressAuthenticator/Signin/LoginPrologueViewController.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@ class LoginPrologueViewController: LoginViewController {
158158
return
159159
}
160160

161-
buildUnifiedPrologueButtons(buttonViewController)
161+
if configuration.enableWPComLoginOnlyInPrologue {
162+
buildPrologueButtonsWithWPComAndOptionalSiteCreation(buttonViewController: buttonViewController)
163+
} else {
164+
buildUnifiedPrologueButtons(buttonViewController)
165+
}
162166

163167
buttonViewController.shadowLayoutGuide = view.safeAreaLayoutGuide
164168
buttonViewController.topButtonStyle = WordPressAuthenticator.shared.style.prologuePrimaryButtonStyle
@@ -240,6 +244,21 @@ class LoginPrologueViewController: LoginViewController {
240244
setButtonViewControllerBackground(buttonViewController)
241245
}
242246

247+
private func buildPrologueButtonsWithWPComAndOptionalSiteCreation(buttonViewController: NUXButtonViewController) {
248+
setButtonViewMargins(forWidth: view.frame.width)
249+
250+
let displayStrings = WordPressAuthenticator.shared.displayStrings
251+
let loginTitle = displayStrings.continueWithWPButtonTitle
252+
buttonViewController.setupTopButton(title: loginTitle, isPrimary: true, accessibilityIdentifier: "Prologue Log In Button", onTap: loginTapCallback())
253+
254+
if configuration.enableSiteCreation {
255+
let createSiteTitle = displayStrings.siteCreationButtonTitle
256+
buttonViewController.setupBottomButton(title: createSiteTitle, isPrimary: false, accessibilityIdentifier: "Prologue Create Site Button", onTap: simplifiedLoginSiteCreationCallback())
257+
}
258+
259+
setButtonViewControllerBackground(buttonViewController)
260+
}
261+
243262
private func siteAddressTapCallback() -> NUXButtonViewController.CallBackType {
244263
return { [weak self] in
245264
self?.siteAddressTapped()
@@ -257,6 +276,14 @@ class LoginPrologueViewController: LoginViewController {
257276
}
258277
}
259278

279+
private func simplifiedLoginSiteCreationCallback() -> NUXButtonViewController.CallBackType {
280+
{ [weak self] in
281+
guard let self = self, let navigationController = self.navigationController else { return }
282+
// triggers the delegate to ask the host app to handle site creation
283+
WordPressAuthenticator.shared.delegate?.showSiteCreation(in: navigationController)
284+
}
285+
}
286+
260287
private func showCancelIfNeccessary(_ buttonViewController: NUXButtonViewController) {
261288
if showCancel {
262289
let cancelTitle = NSLocalizedString("Cancel", comment: "Button title. Tapping it cancels the login flow.")

WordPressAuthenticator/Unified Auth/View Related/Get Started/GetStartedViewController.swift

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ class GetStartedViewController: LoginViewController, NUXKeyboardResponder {
111111
return button
112112
}()
113113

114+
private var showsContinueButtonAtTheBottom: Bool {
115+
screenMode == .signInUsingSiteCredentials ||
116+
configuration.enableSocialLogin == false
117+
}
118+
114119
override open var sourceTag: WordPressSupportSourceTag {
115120
get {
116121
return .loginEmail
@@ -128,8 +133,11 @@ class GetStartedViewController: LoginViewController, NUXKeyboardResponder {
128133
loadRows()
129134
setupTableFooterView()
130135
configureDivider()
136+
131137
if screenMode == .signInUsingSiteCredentials {
132138
configureButtonViewControllerForSiteCredentialsMode()
139+
} else if configuration.enableSocialLogin == false {
140+
configureButtonViewControllerWithoutSocialLogin()
133141
} else {
134142
configureSocialButtons()
135143
}
@@ -157,7 +165,7 @@ class GetStartedViewController: LoginViewController, NUXKeyboardResponder {
157165
hiddenPasswordField?.text = nil
158166
hiddenPasswordField?.isAccessibilityElement = false
159167

160-
if screenMode == .signInUsingSiteCredentials {
168+
if showsContinueButtonAtTheBottom {
161169
registerForKeyboardEvents(keyboardWillShowAction: #selector(handleKeyboardWillShow(_:)),
162170
keyboardWillHideAction: #selector(handleKeyboardWillHide(_:)))
163171
}
@@ -254,13 +262,13 @@ private extension GetStartedViewController {
254262
stackView.layoutMargins = Constants.FooterStackView.layoutMargins
255263
stackView.isLayoutMarginsRelativeArrangement = true
256264

257-
if screenMode == .signInUsingWordPressComOrSocialAccounts {
258-
// Continue button will be added to `buttonViewController` along with sign in with site credentials button when `screenMode` is `signInUsingSiteCredentials`.
259-
// So, adding it to stackView here ONLY for `signInUsingWordPressComOrSocialAccounts` `screenMode`
265+
if showsContinueButtonAtTheBottom == false {
266+
// Continue button will be added to `buttonViewController` along with sign in with site credentials button when `screenMode` is `signInUsingSiteCredentials`
267+
// and simplified login flow is disabled.
260268
stackView.addArrangedSubview(continueButton)
261269
}
262270

263-
if WordPressAuthenticator.shared.configuration.whatIsWPComURL != nil {
271+
if configuration.whatIsWPComURL != nil {
264272
let stackViewWithCenterAlignment = UIStackView()
265273
stackViewWithCenterAlignment.axis = .vertical
266274
stackViewWithCenterAlignment.alignment = .center
@@ -277,10 +285,9 @@ private extension GetStartedViewController {
277285
/// Style the "OR" divider.
278286
///
279287
func configureDivider() {
280-
guard screenMode == .signInUsingWordPressComOrSocialAccounts else {
288+
guard showsContinueButtonAtTheBottom == false else {
281289
return dividerStackView.isHidden = true
282290
}
283-
284291
let color = WordPressAuthenticator.shared.unifiedStyle?.borderColor ?? WordPressAuthenticator.shared.style.primaryNormalBorderColor
285292
leadingDividerLine.backgroundColor = color
286293
leadingDividerLineWidth.constant = WPStyleGuide.hairlineBorderWidth
@@ -307,7 +314,7 @@ private extension GetStartedViewController {
307314

308315
@IBAction func whatIsWPComButtonTapped(_ sender: UIButton) {
309316
tracker.track(click: .whatIsWPCom)
310-
guard let whatIsWPCom = WordPressAuthenticator.shared.configuration.whatIsWPComURL,
317+
guard let whatIsWPCom = configuration.whatIsWPComURL,
311318
let url = URL(string: whatIsWPCom) else {
312319
return
313320
}
@@ -466,11 +473,10 @@ private extension GetStartedViewController {
466473
/// Configures appearance of the submit button.
467474
///
468475
func configureContinueButton(animating: Bool) {
469-
switch screenMode {
470-
case .signInUsingSiteCredentials:
476+
if showsContinueButtonAtTheBottom {
471477
buttonViewController?.setTopButtonState(isLoading: animating,
472478
isEnabled: enableSubmit(animating: animating))
473-
case .signInUsingWordPressComOrSocialAccounts:
479+
} else {
474480
continueButton.showActivityIndicator(animating)
475481
continueButton.isEnabled = enableSubmit(animating: animating)
476482
}
@@ -541,7 +547,7 @@ private extension GetStartedViewController {
541547
source: source,
542548
loginFields: loginFields,
543549
tracker: tracker,
544-
configuration: WordPressAuthenticator.shared.configuration)
550+
configuration: configuration)
545551
passwordCoordinator = coordinator
546552
Task { @MainActor [weak self] in
547553
guard let self = self else { return }
@@ -556,7 +562,7 @@ private extension GetStartedViewController {
556562
let userInfo = (error as NSError).userInfo
557563
let errorCode = userInfo[WordPressComRestApi.ErrorKeyErrorCode] as? String
558564

559-
if WordPressAuthenticator.shared.configuration.enableSignUp, errorCode == "unknown_user" {
565+
if configuration.enableSignUp, errorCode == "unknown_user" {
560566
self.sendEmail()
561567
} else if errorCode == "email_login_not_allowed" {
562568
// If we get this error, we know we have a WordPress.com user but their
@@ -771,7 +777,7 @@ private extension GetStartedViewController {
771777

772778
buttonViewController.hideShadowView()
773779

774-
if WordPressAuthenticator.shared.configuration.enableSignInWithApple {
780+
if configuration.enableSignInWithApple {
775781
buttonViewController.setupTopButtonFor(socialService: .apple, onTap: appleTapped)
776782
}
777783

@@ -804,6 +810,21 @@ private extension GetStartedViewController {
804810
onTap: handleSiteCredentialsButtonTapped)
805811
}
806812

813+
func configureButtonViewControllerWithoutSocialLogin() {
814+
guard let buttonViewController = buttonViewController else {
815+
return
816+
}
817+
818+
buttonViewController.hideShadowView()
819+
820+
// Add a "Continue" button here as the `continueButton` at the top will be hidden
821+
//
822+
buttonViewController.setupTopButton(title: ButtonConfiguration.Continue.title,
823+
isPrimary: true,
824+
accessibilityIdentifier: ButtonConfiguration.Continue.accessibilityIdentifier,
825+
onTap: handleSubmitButtonTapped)
826+
}
827+
807828
@objc func appleTapped() {
808829
tracker.track(click: .loginWithApple)
809830

WordPressAuthenticator/Unified Auth/View Related/Password/PasswordViewController.swift

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class PasswordViewController: LoginViewController {
1919

2020
private let isMagicLinkShownAsSecondaryAction: Bool = WordPressAuthenticator.shared.configuration.isWPComMagicLinkShownAsSecondaryActionOnPasswordScreen
2121

22+
private let configuration = WordPressAuthenticator.shared.configuration
23+
2224
/// Depending on where we're coming from, this screen needs to track a password challenge
2325
/// (if logging on with a Social account) or not (if logging in through WP.com).
2426
///
@@ -338,8 +340,9 @@ private extension PasswordViewController {
338340
func loadRows() {
339341
rows = [.gravatarEmail]
340342

341-
// Instructions only for social accounts
342-
if loginFields.meta.socialService != nil {
343+
// Instructions only for social accounts and simplified WPCom login flow
344+
if loginFields.meta.socialService != nil ||
345+
configuration.wpcomPasswordInstructions != nil {
343346
rows.append(.instructions)
344347
}
345348

@@ -380,7 +383,7 @@ private extension PasswordViewController {
380383
/// Configure the gravatar + email cell.
381384
///
382385
func configureGravatarEmail(_ cell: GravatarEmailTableViewCell) {
383-
cell.configure(withEmail: loginFields.username)
386+
cell.configure(withEmail: loginFields.username, hasBorders: configuration.emphasizeEmailForWPComPassword)
384387

385388
cell.onChangeSelectionHandler = { [weak self] textfield in
386389
// The email can only be changed via a password manager.
@@ -397,18 +400,22 @@ private extension PasswordViewController {
397400
}
398401
}
399402

400-
/// Configure the instruction cell.
403+
/// Configure the instruction cell for social accounts or simplified login.
401404
///
402405
func configureInstructionLabel(_ cell: TextLabelTableViewCell) {
403-
// Instructions only for social accounts
404-
guard let service = loginFields.meta.socialService else {
406+
let displayStrings = WordPressAuthenticator.shared.displayStrings
407+
let instructions: String? = {
408+
if let service = loginFields.meta.socialService {
409+
return (service == .google) ? displayStrings.googlePasswordInstructions :
410+
displayStrings.applePasswordInstructions
411+
}
412+
return configuration.wpcomPasswordInstructions
413+
}()
414+
415+
guard let instructions = instructions else {
405416
return
406417
}
407418

408-
let displayStrings = WordPressAuthenticator.shared.displayStrings
409-
let instructions = (service == .google) ? displayStrings.googlePasswordInstructions :
410-
displayStrings.applePasswordInstructions
411-
412419
cell.configureLabel(text: instructions)
413420
}
414421

0 commit comments

Comments
 (0)