From 01facf8bb9a5e08b7eaae720b77d0e318f42a211 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:08:23 +0700 Subject: [PATCH 1/9] Add new config for site creation guide --- .../WordPressAuthenticatorConfiguration.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift index 2ef67b01..c7cfc9db 100644 --- a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift +++ b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorConfiguration.swift @@ -174,6 +174,10 @@ public struct WordPressAuthenticatorConfiguration { /// let enableSiteAddressLoginOnlyInPrologue: Bool + /// If enabled, the prologue screen would display a link for site creation guide. + /// + let enableSiteCreationGuide: Bool + /// Designated Initializer /// public init (wpcomClientId: String, @@ -210,7 +214,8 @@ public struct WordPressAuthenticatorConfiguration { enableManualSiteCredentialLogin: Bool = false, enableManualErrorHandlingForSiteCredentialLogin: Bool = false, useEnterEmailAddressAsStepValueForGetStartedVC: Bool = false, - enableSiteAddressLoginOnlyInPrologue: Bool = false + enableSiteAddressLoginOnlyInPrologue: Bool = false, + enableSiteCreationGuide: Bool = false ) { self.wpcomClientId = wpcomClientId @@ -248,5 +253,6 @@ public struct WordPressAuthenticatorConfiguration { self.enableManualErrorHandlingForSiteCredentialLogin = enableManualErrorHandlingForSiteCredentialLogin self.useEnterEmailAddressAsStepValueForGetStartedVC = useEnterEmailAddressAsStepValueForGetStartedVC self.enableSiteAddressLoginOnlyInPrologue = enableSiteAddressLoginOnlyInPrologue + self.enableSiteCreationGuide = enableSiteCreationGuide } } From 87d4c12706eba3b875cd5ff19c890ce0ff4035e1 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:08:50 +0700 Subject: [PATCH 2/9] Update WordPressAuthenticatorDelegate with a new delgate method for site creation guide --- .../WordPressAuthenticatorDelegateProtocol.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDelegateProtocol.swift b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDelegateProtocol.swift index 9f94c23a..3282b931 100644 --- a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDelegateProtocol.swift +++ b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDelegateProtocol.swift @@ -148,6 +148,14 @@ public protocol WordPressAuthenticatorDelegate: AnyObject { /// func showSiteCreation(in navigationController: UINavigationController) + /// Signals to the Host App to navigate to the site creation guide. + /// This method triggered only if `enableSiteCreationGuide` config is enabled. + /// + /// - Parameters: + /// - navigationController: the current navigation stack of the login flow. + /// + func showSiteCreationGuide(in navigationController: UINavigationController) + /// Signals the Host App that a given Analytics Event has occurred. /// func track(event: WPAnalyticsStat) @@ -172,6 +180,10 @@ public extension WordPressAuthenticatorDelegate { // No-op } + func showSiteCreationGuide(in navigationController: UINavigationController) { + // No-op + } + func handleSiteCredentialLogin(credentials: WordPressOrgCredentials, onLoading: @escaping (Bool) -> Void, onSuccess: @escaping () -> Void, From e6f609a657294a4f5dc9f41be9242b915a23afd4 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:09:07 +0700 Subject: [PATCH 3/9] Add new string for site creation guide button --- .../WordPressAuthenticatorDisplayStrings.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDisplayStrings.swift b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDisplayStrings.swift index 82ea20b4..077fd52a 100644 --- a/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDisplayStrings.swift +++ b/WordPressAuthenticator/Authenticator/WordPressAuthenticatorDisplayStrings.swift @@ -54,6 +54,7 @@ public struct WordPressAuthenticatorDisplayStrings { public let signupTermsOfService: String public let whatIsWPComLinkTitle: String public let siteCreationButtonTitle: String + public let siteCreationGuideButtonTitle: String /// Placeholder text for textfields. /// @@ -109,7 +110,8 @@ public struct WordPressAuthenticatorDisplayStrings { passwordPlaceholder: String = defaultStrings.passwordPlaceholder, siteAddressPlaceholder: String = defaultStrings.siteAddressPlaceholder, twoFactorCodePlaceholder: String = defaultStrings.twoFactorCodePlaceholder, - emailAddressPlaceholder: String = defaultStrings.emailAddressPlaceholder) { + emailAddressPlaceholder: String = defaultStrings.emailAddressPlaceholder, + siteCreationGuideButtonTitle: String = defaultStrings.siteCreationGuideButtonTitle) { self.emailLoginInstructions = emailLoginInstructions self.getStartedInstructions = getStartedInstructions self.jetpackLoginInstructions = jetpackLoginInstructions @@ -155,6 +157,7 @@ public struct WordPressAuthenticatorDisplayStrings { self.siteAddressPlaceholder = siteAddressPlaceholder self.twoFactorCodePlaceholder = twoFactorCodePlaceholder self.emailAddressPlaceholder = emailAddressPlaceholder + self.siteCreationGuideButtonTitle = siteCreationGuideButtonTitle } } @@ -245,7 +248,12 @@ public extension WordPressAuthenticatorDisplayStrings { twoFactorCodePlaceholder: NSLocalizedString("Authentication code", comment: "Placeholder for the 2FA code textfield."), emailAddressPlaceholder: NSLocalizedString("Email address", - comment: "Placeholder for the email address textfield.") + comment: "Placeholder for the email address textfield."), + siteCreationGuideButtonTitle: NSLocalizedString( + "wordPressAuthenticatorDisplayStrings.default.siteCreationGuideButtonTitle", + value: "Starting a new site?", + comment: "Title for the link for site creation guide." + ) ) } } From 65f699fafce23602f2b9948a10ddbcd604462287 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:09:27 +0700 Subject: [PATCH 4/9] Add helper property for link button style --- .../NUX/Button/NUXButton.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/WordPressAuthenticator/NUX/Button/NUXButton.swift b/WordPressAuthenticator/NUX/Button/NUXButton.swift index 665d180e..9257cae6 100644 --- a/WordPressAuthenticator/NUX/Button/NUXButton.swift +++ b/WordPressAuthenticator/NUX/Button/NUXButton.swift @@ -25,6 +25,25 @@ public struct NUXButtonStyle { self.highlighted = highlighted self.disabled = disabled } + + public static var linkButtonStyle: NUXButtonStyle { + let backgroundColor = UIColor.clear + let buttonTitleColor = WordPressAuthenticator.shared.unifiedStyle?.textButtonColor ?? WordPressAuthenticator.shared.style.textButtonColor + let buttonHighlightColor = WordPressAuthenticator.shared.unifiedStyle?.textButtonHighlightColor ?? WordPressAuthenticator.shared.style.textButtonHighlightColor + + let normalButtonStyle = ButtonStyle(backgroundColor: backgroundColor, + borderColor: backgroundColor, + titleColor: buttonTitleColor) + let highlightedButtonStyle = ButtonStyle(backgroundColor: backgroundColor, + borderColor: backgroundColor, + titleColor: buttonHighlightColor) + let disabledButtonStyle = ButtonStyle(backgroundColor: backgroundColor, + borderColor: backgroundColor, + titleColor: buttonTitleColor.withAlphaComponent(0.5)) + return NUXButtonStyle(normal: normalButtonStyle, + highlighted: highlightedButtonStyle, + disabled: disabledButtonStyle) + } } /// A stylized button used by Login controllers. It also can display a `UIActivityIndicatorView`. @objc open class NUXButton: UIButton { From 2d4892b218caad0ee3347cd6482d222227351da1 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:10:33 +0700 Subject: [PATCH 5/9] Update prologue screen with an option to show site creation guide button --- .../Signin/LoginPrologueViewController.swift | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift index 54814a72..69172764 100644 --- a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift +++ b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift @@ -45,7 +45,10 @@ class LoginPrologueViewController: LoginViewController { /// Return`true` to use new `NUXStackedButtonsViewController` instead of `NUXButtonViewController` to create buttons /// private var useStackedButtonsViewController: Bool { - configuration.enableWPComLoginOnlyInPrologue || configuration.enableSiteCreation + configuration.enableWPComLoginOnlyInPrologue || + configuration.enableSiteCreation || + configuration.enableSiteAddressLoginOnlyInPrologue || + configuration.enableSiteCreationGuide } // MARK: - Lifecycle Methods @@ -293,25 +296,19 @@ class LoginPrologueViewController: LoginViewController { onTap: simplifiedLoginSiteCreationCallback()) }() - if configuration.enableWPComLoginOnlyInPrologue && configuration.enableSiteCreation { - buttons = [continueWithWPButton, - createSiteButton] - } else if configuration.enableWPComLoginOnlyInPrologue { - buttons = [continueWithWPButton] - } else if configuration.enableSiteAddressLoginOnlyInPrologue && configuration.enableSiteCreation { - buttons = [createSiteButton, enterYourSiteAddressButton] - } else if configuration.enableSiteAddressLoginOnlyInPrologue { - buttons = [enterYourSiteAddressButton] - } else if configuration.enableSiteCreation { - let createSiteButtonForBottomStackView = StackedButton(using: createSiteButton, - stackView: .bottom) - buttons = [continueWithWPButton, - enterYourSiteAddressButton, - createSiteButtonForBottomStackView] - } else { - WPAuthenticatorLogError("Failed to create `StackedButton`s in login prologue screen.") - buttons = [] - } + let siteCreationGuideButton: StackedButton = { + StackedButton(title: displayStrings.siteCreationGuideButtonTitle, + accessibilityIdentifier: "Prologue Site Creation Guide button", + style: NUXButtonStyle.linkButtonStyle, + onTap: siteCreationGuideCallback()) + }() + + buttons = [ + configuration.enableWPComLoginOnlyInPrologue ? nil : enterYourSiteAddressButton, + configuration.enableSiteAddressLoginOnlyInPrologue ? nil : continueWithWPButton, + configuration.enableSiteCreation ? createSiteButton : nil, + configuration.enableSiteCreationGuide ? siteCreationGuideButton : nil + ].compactMap { $0 } let showDivider = configuration.enableWPComLoginOnlyInPrologue == false && configuration.enableSiteCreation == true && @@ -345,6 +342,14 @@ class LoginPrologueViewController: LoginViewController { } } + private func siteCreationGuideCallback() -> NUXButtonViewController.CallBackType { + { [weak self] in + guard let self, let navigationController else { return } + // triggers the delegate to ask the host app to handle site creation guide + WordPressAuthenticator.shared.delegate?.showSiteCreationGuide(in: navigationController) + } + } + private func showCancelIfNeccessary(_ buttonViewController: NUXButtonViewController) { if showCancel { let cancelTitle = NSLocalizedString("Cancel", comment: "Button title. Tapping it cancels the login flow.") From 6e73c6b8d8b8364f7301a92bf3a932c6c23b3824 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:19:26 +0700 Subject: [PATCH 6/9] Update style for site creation guide button --- WordPressAuthenticator/Signin/LoginPrologueViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift index 69172764..1ec39eb5 100644 --- a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift +++ b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift @@ -298,6 +298,8 @@ class LoginPrologueViewController: LoginViewController { let siteCreationGuideButton: StackedButton = { StackedButton(title: displayStrings.siteCreationGuideButtonTitle, + isPrimary: false, + configureBodyFontForTitle: true, accessibilityIdentifier: "Prologue Site Creation Guide button", style: NUXButtonStyle.linkButtonStyle, onTap: siteCreationGuideCallback()) From 04abd76ac1af7cb7d6c1cc9935f32a9ee618cb65 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:34:44 +0700 Subject: [PATCH 7/9] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed73921b..44427241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,7 @@ _None._ ### New Features -_None._ +- Add an option to show site creation guide on the prologue screen [#844] ### Bug Fixes From c2fed7a7b86da25c1c8128626364e2aa08dd45d2 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 15:35:48 +0700 Subject: [PATCH 8/9] Fix swiftlint error --- WordPressAuthenticator/Signin/LoginPrologueViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift index 1ec39eb5..5d11d9c7 100644 --- a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift +++ b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift @@ -45,7 +45,7 @@ class LoginPrologueViewController: LoginViewController { /// Return`true` to use new `NUXStackedButtonsViewController` instead of `NUXButtonViewController` to create buttons /// private var useStackedButtonsViewController: Bool { - configuration.enableWPComLoginOnlyInPrologue || + configuration.enableWPComLoginOnlyInPrologue || configuration.enableSiteCreation || configuration.enableSiteAddressLoginOnlyInPrologue || configuration.enableSiteCreationGuide From 046be8081a2c87b095c0fd83be6403f8bcb14fb9 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 20 Mar 2024 16:10:04 +0700 Subject: [PATCH 9/9] Update logic for buttons on prologue screen --- .../Signin/LoginPrologueViewController.swift | 63 +++++++++++++------ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift index 5d11d9c7..e7c4fe7d 100644 --- a/WordPressAuthenticator/Signin/LoginPrologueViewController.swift +++ b/WordPressAuthenticator/Signin/LoginPrologueViewController.swift @@ -271,13 +271,22 @@ class LoginPrologueViewController: LoginViewController { let displayStrings = WordPressAuthenticator.shared.displayStrings let buttons: [StackedButton] - let continueWithWPButton = StackedButton(title: displayStrings.continueWithWPButtonTitle, - isPrimary: true, - configureBodyFontForTitle: true, - accessibilityIdentifier: "Prologue Continue Button", - style: primaryButtonStyle, - onTap: loginTapCallback()) - let enterYourSiteAddressButton: StackedButton = { + let continueWithWPButton: StackedButton? = { + guard !configuration.enableSiteAddressLoginOnlyInPrologue else { + return nil + } + return StackedButton(title: displayStrings.continueWithWPButtonTitle, + isPrimary: true, + configureBodyFontForTitle: true, + accessibilityIdentifier: "Prologue Continue Button", + style: primaryButtonStyle, + onTap: loginTapCallback()) + }() + + let enterYourSiteAddressButton: StackedButton? = { + guard !configuration.enableWPComLoginOnlyInPrologue else { + return nil + } let isPrimary = configuration.enableSiteAddressLoginOnlyInPrologue && !configuration.enableSiteCreation return StackedButton(title: displayStrings.enterYourSiteAddressButtonTitle, isPrimary: isPrimary, @@ -286,7 +295,11 @@ class LoginPrologueViewController: LoginViewController { style: secondaryButtonStyle, onTap: siteAddressTapCallback()) }() - let createSiteButton: StackedButton = { + + let createSiteButton: StackedButton? = { + guard configuration.enableSiteCreation else { + return nil + } let isPrimary = configuration.enableSiteAddressLoginOnlyInPrologue return StackedButton(title: displayStrings.siteCreationButtonTitle, isPrimary: isPrimary, @@ -296,20 +309,32 @@ class LoginPrologueViewController: LoginViewController { onTap: simplifiedLoginSiteCreationCallback()) }() - let siteCreationGuideButton: StackedButton = { - StackedButton(title: displayStrings.siteCreationGuideButtonTitle, - isPrimary: false, - configureBodyFontForTitle: true, - accessibilityIdentifier: "Prologue Site Creation Guide button", - style: NUXButtonStyle.linkButtonStyle, - onTap: siteCreationGuideCallback()) + let createSiteButtonForBottomStackView: StackedButton? = { + guard let createSiteButton else { + return nil + } + return StackedButton(using: createSiteButton, stackView: .bottom) + }() + + let siteCreationGuideButton: StackedButton? = { + guard configuration.enableSiteCreationGuide else { + return nil + } + return StackedButton(title: displayStrings.siteCreationGuideButtonTitle, + isPrimary: false, + configureBodyFontForTitle: true, + accessibilityIdentifier: "Prologue Site Creation Guide button", + style: NUXButtonStyle.linkButtonStyle, + onTap: siteCreationGuideCallback()) }() + let showBothLoginOptions = continueWithWPButton != nil && enterYourSiteAddressButton != nil buttons = [ - configuration.enableWPComLoginOnlyInPrologue ? nil : enterYourSiteAddressButton, - configuration.enableSiteAddressLoginOnlyInPrologue ? nil : continueWithWPButton, - configuration.enableSiteCreation ? createSiteButton : nil, - configuration.enableSiteCreationGuide ? siteCreationGuideButton : nil + continueWithWPButton, + !showBothLoginOptions ? createSiteButton : nil, + enterYourSiteAddressButton, + showBothLoginOptions ? createSiteButtonForBottomStackView : nil, + siteCreationGuideButton ].compactMap { $0 } let showDivider = configuration.enableWPComLoginOnlyInPrologue == false &&