Skip to content

Commit 33e65ab

Browse files
Merge pull request #19602 from wordpress-mobile/task/19585-site-creation-phase-one
Jetpack Focus: Display Site Creation overlay
2 parents c4363cf + cc84bf3 commit 33e65ab

11 files changed

+227
-25
lines changed
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
extension BlogListViewController {
22
@objc
33
func launchSiteCreation() {
4-
let wizardLauncher = SiteCreationWizardLauncher()
5-
guard let wizard = wizardLauncher.ui else {
6-
return
4+
JetpackFeaturesRemovalCoordinator.presentSiteCreationOverlayIfNeeded(in: self) {
5+
guard JetpackFeaturesRemovalCoordinator.siteCreationPhase() != .two else {
6+
return
7+
}
8+
9+
// Display site creation flow if not in phase two
10+
let wizardLauncher = SiteCreationWizardLauncher()
11+
guard let wizard = wizardLauncher.ui else {
12+
return
13+
}
14+
self.present(wizard, animated: true)
15+
WPAnalytics.track(.enhancedSiteCreationAccessed, withProperties: ["source": "my_sites"])
716
}
8-
present(wizard, animated: true)
9-
WPAnalytics.track(.enhancedSiteCreationAccessed, withProperties: ["source": "my_sites"])
1017
}
1118
}

WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -696,12 +696,19 @@ class MySiteViewController: UIViewController, NoResultsViewHost {
696696
}
697697

698698
func launchSiteCreation(source: String) {
699-
let wizardLauncher = SiteCreationWizardLauncher()
700-
guard let wizard = wizardLauncher.ui else {
701-
return
699+
JetpackFeaturesRemovalCoordinator.presentSiteCreationOverlayIfNeeded(in: self) {
700+
guard JetpackFeaturesRemovalCoordinator.siteCreationPhase() != .two else {
701+
return
702+
}
703+
704+
// Display site creation flow if not in phase two
705+
let wizardLauncher = SiteCreationWizardLauncher()
706+
guard let wizard = wizardLauncher.ui else {
707+
return
708+
}
709+
self.present(wizard, animated: true)
710+
WPAnalytics.track(.enhancedSiteCreationAccessed, withProperties: ["source": source])
702711
}
703-
present(wizard, animated: true)
704-
WPAnalytics.track(.enhancedSiteCreationAccessed, withProperties: ["source": source])
705712
}
706713

707714
@objc

WordPress/Classes/ViewRelated/Jetpack/Branding/Coordinator/JetpackFeaturesRemovalCoordinator.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ class JetpackFeaturesRemovalCoordinator {
100100
frequencyTracker.track()
101101
}
102102

103+
/// Used to display Site Creation overlays.
104+
/// - Parameters:
105+
/// - viewController: View controller where the overlay should be presented in.
106+
static func presentSiteCreationOverlayIfNeeded(in viewController: UIViewController,
107+
onDismiss: JetpackOverlayDismissCallback? = nil) {
108+
let phase = siteCreationPhase()
109+
var viewModel = JetpackFullscreenOverlaySiteCreationViewModel(phase: phase)
110+
viewModel.onDismiss = onDismiss
111+
guard viewModel.shouldShowOverlay else {
112+
onDismiss?()
113+
return
114+
}
115+
createAndPresentOverlay(with: viewModel, in: viewController)
116+
}
117+
103118
private static func createAndPresentOverlay(with viewModel: JetpackFullscreenOverlayViewModel, in viewController: UIViewController) {
104119
let overlay = JetpackFullscreenOverlayViewController(with: viewModel)
105120
let navigationViewController = UINavigationController(rootViewController: overlay)

WordPress/Classes/ViewRelated/Jetpack/Branding/Fullscreen Overlay/JetpackFullscreenOverlayGeneralViewModel.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ struct JetpackFullscreenOverlayGeneralViewModel: JetpackFullscreenOverlayViewMod
159159
var analyticsSource: String {
160160
return source.rawValue
161161
}
162+
163+
var titleLabelMaxNumberOfLines: Int {
164+
return Constants.titleLabelMaxNumberOfLines
165+
}
166+
167+
var onDismiss: JetpackOverlayDismissCallback?
162168
}
163169

164170
private extension JetpackFullscreenOverlayGeneralViewModel {
@@ -169,6 +175,7 @@ private extension JetpackFullscreenOverlayGeneralViewModel {
169175
static let readerLogoAnimationRtl = "JetpackReaderLogoAnimation_rtl"
170176
static let notificationsLogoAnimationLtr = "JetpackNotificationsLogoAnimation_ltr"
171177
static let notificationsLogoAnimationRtl = "JetpackNotificationsLogoAnimation_rtl"
178+
static let titleLabelMaxNumberOfLines: Int = 2
172179
}
173180

174181
enum Strings {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Foundation
2+
import AutomatticTracks
3+
4+
extension JetpackFullscreenOverlaySiteCreationViewModel {
5+
6+
// MARK: Analytics Implementation
7+
8+
func trackOverlayDisplayed() {
9+
// TODO: Implement this
10+
}
11+
12+
func trackLearnMoreTapped() {
13+
// TODO: Implement this
14+
}
15+
16+
func trackSwitchButtonTapped() {
17+
// TODO: Implement this
18+
}
19+
20+
func trackCloseButtonTapped() {
21+
// TODO: Implement this
22+
}
23+
24+
func trackContinueButtonTapped() {
25+
// TODO: Implement this
26+
}
27+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import Foundation
2+
3+
/// Dynamic implementation of `JetpackFullscreenOverlayViewModel` based on the site creation phase
4+
/// Should be used for Site Creation overlays.
5+
struct JetpackFullscreenOverlaySiteCreationViewModel: JetpackFullscreenOverlayViewModel {
6+
7+
let phase: JetpackFeaturesRemovalCoordinator.SiteCreationPhase
8+
9+
var shouldShowOverlay: Bool {
10+
switch phase {
11+
case .normal:
12+
return false
13+
case .one:
14+
fallthrough
15+
case .two:
16+
return true
17+
}
18+
}
19+
20+
var title: String {
21+
return Strings.title
22+
}
23+
24+
var subtitle: String {
25+
switch phase {
26+
case .one:
27+
return Strings.phaseOneSubtitle
28+
case .two:
29+
return Strings.phaseTwoSubtitle
30+
default:
31+
return ""
32+
}
33+
}
34+
35+
var animationLtr: String {
36+
return Constants.wpJetpackLogoAnimationLtr
37+
}
38+
39+
var animationRtl: String {
40+
return Constants.wpJetpackLogoAnimationRtl
41+
}
42+
43+
var footnote: String? {
44+
return nil
45+
}
46+
47+
var shouldShowLearnMoreButton: Bool {
48+
return false
49+
}
50+
51+
var switchButtonText: String {
52+
return Strings.switchButtonTitle
53+
}
54+
55+
var continueButtonText: String? {
56+
switch phase {
57+
// Show only in phase one
58+
case .one:
59+
return Strings.continueButtonTitle
60+
default:
61+
return nil
62+
}
63+
}
64+
65+
var shouldShowCloseButton: Bool {
66+
return true
67+
}
68+
69+
var analyticsSource: String {
70+
return Constants.analyticsSource
71+
}
72+
73+
var titleLabelMaxNumberOfLines: Int {
74+
return Constants.titleLabelMaxNumberOfLines
75+
}
76+
77+
var onDismiss: JetpackOverlayDismissCallback?
78+
}
79+
80+
private extension JetpackFullscreenOverlaySiteCreationViewModel {
81+
enum Constants {
82+
static let wpJetpackLogoAnimationLtr = "JetpackWordPressLogoAnimation_ltr"
83+
static let wpJetpackLogoAnimationRtl = "JetpackWordPressLogoAnimation_rtl"
84+
static let analyticsSource = "site_creation"
85+
static let titleLabelMaxNumberOfLines: Int = 3
86+
}
87+
88+
enum Strings {
89+
static let title = NSLocalizedString("jetpack.fullscreen.overlay.siteCreation.title",
90+
value: "Create a new WordPress site with the Jetpack app",
91+
comment: "Title of a screen displayed when the user trys creating a new site from the WordPress app. The screen showcases the Jetpack app.")
92+
static let phaseOneSubtitle = NSLocalizedString("jetpack.fullscreen.overlay.phaseOne.siteCreation.subtitle",
93+
value: "Jetpack provides stats, notifications and more to help you build and grow the WordPress site of your dreams.",
94+
comment: "Subtitle of a screen displayed when the user trys creating a new site from the WordPress app. The screen showcases the Jetpack app.")
95+
static let phaseTwoSubtitle = NSLocalizedString("jetpack.fullscreen.overlay.phaseTwo.siteCreation.subtitle",
96+
value: "Jetpack provides stats, notifications and more to help you build and grow the WordPress site of your dreams.\n\nThe WordPress app no longer supports creating a new site.",
97+
comment: "Subtitle of a screen displayed when the user trys creating a new site from the WordPress app. The screen showcases the Jetpack app.")
98+
static let switchButtonTitle = NSLocalizedString("jetpack.fullscreen.overlay.siteCreation.switch.title",
99+
value: "Try the new Jetpack app",
100+
comment: "Title of a button that navigates the user to the Jetpack app if installed, or to the app store.")
101+
static let continueButtonTitle = NSLocalizedString("jetpack.fullscreen.overlay.siteCreation.continue.title",
102+
value: "Continue without Jetpack",
103+
comment: "Title of a button that navigates the user to the Jetpack app if installed, or to the app store.")
104+
}
105+
}

WordPress/Classes/ViewRelated/Jetpack/Branding/Fullscreen Overlay/JetpackFullscreenOverlayViewController.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class JetpackFullscreenOverlayViewController: UIViewController {
5252
@IBOutlet weak var learnMoreButton: UIButton!
5353
@IBOutlet weak var switchButton: UIButton!
5454
@IBOutlet weak var continueButton: UIButton!
55+
@IBOutlet weak var buttonsSuperViewBottomConstraint: NSLayoutConstraint!
5556

5657
// MARK: Initializers
5758

@@ -72,7 +73,7 @@ class JetpackFullscreenOverlayViewController: UIViewController {
7273
self.isModalInPresentation = true
7374
configureNavigationBar()
7475
applyStyles()
75-
addConstraints()
76+
setupConstraints()
7677
setupContent()
7778
setupColors()
7879
setupFonts()
@@ -107,12 +108,17 @@ class JetpackFullscreenOverlayViewController: UIViewController {
107108

108109
private func applyStyles() {
109110
switchButton.layer.cornerRadius = Metrics.switchButtonCornerRadius
111+
titleLabel.numberOfLines = viewModel.titleLabelMaxNumberOfLines
110112
}
111113

112-
private func addConstraints() {
114+
private func setupConstraints() {
115+
// Animation constraint
113116
let animationSize = animation?.size ?? .init(width: 1, height: 1)
114117
let ratio = animationSize.width / animationSize.height
115118
animationView.widthAnchor.constraint(equalTo: animationView.heightAnchor, multiplier: ratio).isActive = true
119+
120+
// Buttons bottom constraint
121+
buttonsSuperViewBottomConstraint.constant = viewModel.continueButtonIsHidden ? Metrics.singleButtonBottomSpacing : Metrics.buttonsNormalBottomSpacing
116122
}
117123

118124
private func setupContent() {
@@ -205,6 +211,7 @@ class JetpackFullscreenOverlayViewController: UIViewController {
205211
@objc private func closeButtonPressed(sender: UIButton) {
206212
dismiss(animated: true, completion: nil)
207213
viewModel.trackCloseButtonTapped()
214+
viewModel.onDismiss?()
208215
}
209216

210217

@@ -216,6 +223,7 @@ class JetpackFullscreenOverlayViewController: UIViewController {
216223
@IBAction func continueButtonPressed(_ sender: Any) {
217224
dismiss(animated: true, completion: nil)
218225
viewModel.trackContinueButtonTapped()
226+
viewModel.onDismiss?()
219227
}
220228

221229
@IBAction func learnMoreButtonPressed(_ sender: Any) {
@@ -251,6 +259,8 @@ private extension JetpackFullscreenOverlayViewController {
251259
static let switchButtonCornerRadius: CGFloat = 6
252260
static let titleLineHeightMultiple: CGFloat = 0.88
253261
static let titleKern: CGFloat = 0.37
262+
static let buttonsNormalBottomSpacing: CGFloat = 30
263+
static let singleButtonBottomSpacing: CGFloat = 60
254264
}
255265

256266
enum Constants {

WordPress/Classes/ViewRelated/Jetpack/Branding/Fullscreen Overlay/JetpackFullscreenOverlayViewController.xib

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="JetpackFullscreenOverlayViewController" customModule="WordPress" customModuleProvider="target">
1313
<connections>
1414
<outlet property="animationView" destination="v3d-AD-Jsf" id="8wg-bB-WH5"/>
15+
<outlet property="buttonsSuperViewBottomConstraint" destination="zhh-p2-mZx" id="4cZ-ra-9SF"/>
1516
<outlet property="contentStackView" destination="TTg-Z6-h4X" id="rbe-WF-3kb"/>
1617
<outlet property="continueButton" destination="hPW-8A-Di4" id="fym-yu-QBz"/>
1718
<outlet property="footnoteLabel" destination="1l4-qY-6ZA" id="Szg-6d-q2E"/>
@@ -34,7 +35,7 @@
3435
<rect key="frame" x="0.0" y="0.0" width="375" height="514"/>
3536
<subviews>
3637
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="TTg-Z6-h4X" userLabel="Content Stack View">
37-
<rect key="frame" x="30" y="115.5" width="315" height="283"/>
38+
<rect key="frame" x="30" y="115.66666666666666" width="315" height="282.66666666666674"/>
3839
<subviews>
3940
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bUe-f2-zzc" userLabel="Icon Super View">
4041
<rect key="frame" x="0.0" y="0.0" width="315" height="75"/>
@@ -57,28 +58,28 @@
5758
</constraints>
5859
</view>
5960
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.59999999999999998" translatesAutoresizingMaskIntoConstraints="NO" id="EqD-nO-Q6T">
60-
<rect key="frame" x="0.0" y="95" width="315" height="20.5"/>
61+
<rect key="frame" x="0.0" y="94.999999999999986" width="315" height="20.333333333333329"/>
6162
<fontDescription key="fontDescription" type="system" pointSize="17"/>
6263
<nil key="textColor"/>
6364
<nil key="highlightedColor"/>
6465
</label>
6566
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Subtitle Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.59999999999999998" translatesAutoresizingMaskIntoConstraints="NO" id="n6H-KY-dMw">
66-
<rect key="frame" x="0.0" y="135.5" width="315" height="20.5"/>
67+
<rect key="frame" x="0.0" y="135.33333333333331" width="315" height="20.333333333333343"/>
6768
<fontDescription key="fontDescription" type="system" pointSize="17"/>
6869
<nil key="textColor"/>
6970
<nil key="highlightedColor"/>
7071
</label>
7172
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Footnote Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.59999999999999998" translatesAutoresizingMaskIntoConstraints="NO" id="1l4-qY-6ZA">
72-
<rect key="frame" x="0.0" y="176" width="315" height="20.5"/>
73+
<rect key="frame" x="0.0" y="175.66666666666663" width="315" height="20.333333333333343"/>
7374
<fontDescription key="fontDescription" type="system" pointSize="17"/>
7475
<nil key="textColor"/>
7576
<nil key="highlightedColor"/>
7677
</label>
7778
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0z9-x4-AgY" userLabel="Learn More Super View">
78-
<rect key="frame" x="0.0" y="216.5" width="315" height="66.5"/>
79+
<rect key="frame" x="0.0" y="216" width="315" height="66.666666666666686"/>
7980
<subviews>
8081
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="n55-iX-u43">
81-
<rect key="frame" x="0.0" y="0.0" width="128" height="66.5"/>
82+
<rect key="frame" x="0.0" y="0.0" width="128" height="66.666666666666671"/>
8283
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
8384
<state key="normal" title="Learn More Button"/>
8485
<connections>
@@ -116,7 +117,7 @@
116117
</constraints>
117118
</scrollView>
118119
<stackView opaque="NO" contentMode="scaleToFill" placeholderIntrinsicWidth="354" placeholderIntrinsicHeight="166" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="vcE-wc-fHe">
119-
<rect key="frame" x="10.5" y="529" width="354" height="108"/>
120+
<rect key="frame" x="10.666666666666657" y="529" width="354" height="108"/>
120121
<subviews>
121122
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VGE-FS-gsd">
122123
<rect key="frame" x="0.0" y="0.0" width="354" height="50"/>

WordPress/Classes/ViewRelated/Jetpack/Branding/Fullscreen Overlay/JetpackFullscreenOverlayViewModel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import Foundation
22

3+
typealias JetpackOverlayDismissCallback = () -> Void
4+
35
/// Protocol used to configure `JetpackFullscreenOverlayViewController`
46
protocol JetpackFullscreenOverlayViewModel {
57
var title: String { get }
@@ -12,6 +14,8 @@ protocol JetpackFullscreenOverlayViewModel {
1214
var continueButtonText: String? { get }
1315
var shouldShowCloseButton: Bool { get }
1416
var analyticsSource: String { get }
17+
var titleLabelMaxNumberOfLines: Int { get }
18+
var onDismiss: JetpackOverlayDismissCallback? { get }
1519

1620
func trackOverlayDisplayed()
1721
func trackLearnMoreTapped()

WordPress/Classes/ViewRelated/NUX/WordPressAuthenticationManager.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,13 +385,20 @@ extension WordPressAuthenticationManager: WordPressAuthenticatorDelegate {
385385
let onDismissQuickStartPromptForNewSiteHandler = onDismissQuickStartPromptHandler(type: .newSite, onDismiss: onDismiss)
386386

387387
epilogueViewController.onCreateNewSite = {
388-
let wizardLauncher = SiteCreationWizardLauncher(onDismiss: onDismissQuickStartPromptForNewSiteHandler)
389-
guard let wizard = wizardLauncher.ui else {
390-
return
391-
}
388+
JetpackFeaturesRemovalCoordinator.presentSiteCreationOverlayIfNeeded(in: navigationController) {
389+
guard JetpackFeaturesRemovalCoordinator.siteCreationPhase() != .two else {
390+
return
391+
}
392392

393-
navigationController.present(wizard, animated: true)
394-
WPAnalytics.track(.enhancedSiteCreationAccessed, withProperties: ["source": "login_epilogue"])
393+
// Display site creation flow if not in phase two
394+
let wizardLauncher = SiteCreationWizardLauncher(onDismiss: onDismissQuickStartPromptForNewSiteHandler)
395+
guard let wizard = wizardLauncher.ui else {
396+
return
397+
}
398+
399+
navigationController.present(wizard, animated: true)
400+
WPAnalytics.track(.enhancedSiteCreationAccessed, withProperties: ["source": "login_epilogue"])
401+
}
395402
}
396403

397404
navigationController.delegate = epilogueViewController

0 commit comments

Comments
 (0)