Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onboarding Improvements: Epilogue (select site / create a new site) + Quick Start prompt #17564

Merged
merged 78 commits into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
dc4a1c7
Remove EpilogueSectionHeaderFooter
Oct 28, 2021
f892157
Add LoginEpilogueChooseSiteTableViewCell
Oct 28, 2021
2996b48
Adjusting UI
Oct 28, 2021
e3a3211
Updating UI
Oct 28, 2021
0447f9a
Add LoginEpilogueDividerView
Oct 29, 2021
fea658f
Add LoginEpilogueDividerView to bottomPanel
Oct 29, 2021
4aef602
Remove LoginEpilogueConnectSiteCell
Oct 29, 2021
827e9dd
Hide bottom panel if number of sites is less then 4
Oct 29, 2021
ab37fac
Fix separators
Oct 29, 2021
bcc2a99
Add LoginEpilogueCreateNewSiteCell
Oct 29, 2021
1a30276
Cleanup.
Oct 29, 2021
98f02e7
Fix: apply the correct constraints
Nov 1, 2021
bc0f96e
Refactor: define constants for LoginEpilogueCreateNewSiteCell
Nov 1, 2021
3f6e620
Refactor: define constants for divider view
Nov 1, 2021
561bcc2
Refactor: use divider muriel color
Nov 1, 2021
ca6a73e
Fix: remove seperator line on last row
Nov 1, 2021
1b0e9f4
Fix: hide Create A New Site button for Jetpack
Nov 1, 2021
ae7f0de
Refactor: define constants for choose site cell
Nov 2, 2021
0112ec7
Fix: update comment
Nov 2, 2021
94ef920
Refactor: extract condition into a bool constant
Nov 2, 2021
d658c41
Add: dismiss epilogue and navigate to My Site
Nov 2, 2021
f69c37c
Refactor: show selected blog
Nov 2, 2021
b2be93f
Refactor: rename parameter for clarity
Nov 3, 2021
1f6f023
Refactor: extract showBlogDetails to extension
Nov 3, 2021
fdd2611
Add: new quick start prompt vc
Nov 3, 2021
805ae18
Refactor: show quick start after blog is selected in epilogue
Nov 3, 2021
29dc8bd
Refactor: show My Site screen briefly before presenting Quick Start
Nov 4, 2021
2b5a91c
Refactor: extract dismissPrompt to a method
Nov 4, 2021
717ea6a
Add: user defaults extension for quick start
Nov 4, 2021
e5d9281
Add: mark quick start as dismissed if No Thanks was tapped
Nov 4, 2021
c7cbab5
Refactor: dismiss and show blog if quick start has already been dismi…
Nov 4, 2021
47d2226
Update: quick start delay
Nov 5, 2021
b3132e0
Fix: follow readable width for quick start prompt
Nov 5, 2021
3e6d60f
Fix: adjust font style
Nov 8, 2021
bf47970
Fix: adjust stackview spacing
Nov 8, 2021
309e487
Fix: constrain to contentview
Nov 8, 2021
2bb8530
Add: onCreateNewSite closure
Nov 10, 2021
d8e9b27
Add: present site creation wizard from epilogue
Nov 10, 2021
2bca277
Refactor: pass onDismissQuickStart closure
Nov 10, 2021
32cf5d0
Refactor: dismiss the fullscreen signin from the quick start prompt
Nov 11, 2021
06fb03e
Refactor: show quick start prompt instead of old quick start alert
Nov 11, 2021
6bd832a
Add: quick start settings helper class
Nov 9, 2021
2b3242e
Refactor: inject quick start settings
Nov 18, 2021
1ab0d56
Add: tests for quick start settings
Nov 9, 2021
9d915b0
Refactor: define on dismiss closure in wp auth manager
Nov 18, 2021
6f5a846
Fix: typo
Nov 18, 2021
e3a2f03
Refactor: inject quick start settings
Nov 18, 2021
1c1a42f
Refactor: extract delayed quick start execution to a method
Nov 18, 2021
e781e4f
Fix: show quick start tour after site creation via site picker
Nov 18, 2021
e11c944
Refactor: rename method to setupWithDelay and omit executeWithDelay p…
Nov 18, 2021
2f23fe0
Refactor: make QuickStartSettings non optional
Nov 18, 2021
3a7df0e
Update: copy for Customize quick start steps
Nov 17, 2021
e953c61
Update: copy for Grow quick start steps
Nov 17, 2021
daa75a1
Update: refine quick start prompt layout
Nov 17, 2021
bdaa035
Fix: create new site row display logic
Nov 17, 2021
fa75c97
Refactor: define constant for create new site row threshold
Nov 17, 2021
ec24613
Refactor: update button panel configuration
Nov 17, 2021
8f71f35
Refactor: don't show quickstart upgrade to v2 alert
Nov 18, 2021
dc8dbd3
Remove: reference to quick start v2 notice
Nov 18, 2021
a9984f6
Remove: obsolete file
Nov 18, 2021
6fb5edf
Refactor: configure LoginEpilogueChooseSiteTableViewCell based on if …
Nov 19, 2021
7d14e4a
Refactor: extract number of sites to a method
Nov 19, 2021
9dd1bdf
Refactor: Make create a new site button a subview of the button panel
Nov 22, 2021
4e2dc7d
Refactor: define two bottom constraints for tableview container view
Nov 22, 2021
fe38972
Refactor: add a skip button to the epilogue
Nov 22, 2021
b96ca20
Refactor: if there are no sites yet, then show the skip button
Nov 22, 2021
741c1ec
Refactor: configure button panel when there's no sites yet
Nov 22, 2021
cc1b871
Add: dismiss epilogue when the skip button is tapped
Nov 22, 2021
64ce3f2
Fix: when a blog is selected on the epilogue, first check if the quic…
Nov 22, 2021
9b728f4
Add: epilogue new events
Nov 25, 2021
e7b0393
Add: track site selected and creating a new site
leandroalonso Nov 23, 2021
b7e341b
Fix: track quick start prompt button actions
Nov 24, 2021
a9e5b11
Add: when switching to the quick start prompt, read the title
leandroalonso Nov 23, 2021
69991dc
Add: quick start prompt screen
Nov 24, 2021
847d008
Add: accesssibility identifier for login epilogue table
Nov 24, 2021
1e47f48
Fix: dismiss epilogue screen after adding self-hosted site via the si…
Nov 24, 2021
c8fc04f
Fix: tap on first site and dismiss quick start prompt if needed
Nov 24, 2021
9e32d77
Update: release notes for Onboarding Improvements
Nov 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* [***] Fixes a crasher that was sometimes triggered when seeing the details for like notifications.

* [*] Editor: Show a compact notice when switching between HTML or Visual mode. [https://github.com/wordpress-mobile/WordPress-iOS/pull/17521]
* [*] Onboarding Improvements: Need a little help after login? We're here for you. We've made a few changes to the login flow that will make it easier for you to start managing your site or create a new one. [#17564]
* [***] Fixed crash where uploading image when offline crashes iOS app. [#17488]

18.7
Expand Down
17 changes: 11 additions & 6 deletions WordPress/Classes/System/WindowManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ class WindowManager: NSObject {
/// Shows the initial UI for the App to be shown right after launch. This method will present the sign-in flow if the user is not
/// authenticated, or the actuall App UI if the user is already authenticated.
///
public func showUI() {
public func showUI(for blog: Blog? = nil) {
if AccountHelper.isLoggedIn {
showAppUI()
showAppUI(for: blog)
} else {
showSignInUI()
}
Expand All @@ -45,20 +45,25 @@ class WindowManager: NSObject {
showSignInUI()
}

func dismissFullscreenSignIn(completion: Completion? = nil) {
func dismissFullscreenSignIn(blogToShow: Blog? = nil, completion: Completion? = nil) {
guard isShowingFullscreenSignIn == true && AccountHelper.isLoggedIn == true else {
return
}

showAppUI(completion: completion)
showAppUI(for: blogToShow, completion: completion)
}

/// Shows the UI for authenticated users.
///
func showAppUI(completion: Completion? = nil) {
func showAppUI(for blog: Blog? = nil, completion: Completion? = nil) {
isShowingFullscreenSignIn = false

show(WPTabBarController.sharedInstance(), completion: completion)

guard let blog = blog else {
return
}

WPTabBarController.sharedInstance()?.showBlogDetails(for: blog)
}

/// Shows the initial UI for unauthenticated users.
Expand Down
10 changes: 10 additions & 0 deletions WordPress/Classes/Utility/Analytics/WPAnalyticsEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ import Foundation
case privacySettingsOpened
case privacySettingsReportCrashesToggled

// Login: Epilogue
case loginEpilogueChooseSiteTapped
case loginEpilogueCreateNewSiteTapped

/// A String that represents the event
var value: String {
switch self {
Expand Down Expand Up @@ -690,6 +694,12 @@ import Foundation
return "account_close_tapped"
case .accountCloseCompleted:
return "account_close_completed"

// Login: Epilogue
case .loginEpilogueChooseSiteTapped:
return "login_epilogue_choose_site_tapped"
case .loginEpilogueCreateNewSiteTapped:
return "login_epilogue_create_new_site_tapped"
} // END OF SWITCH
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extension BlogDetailsViewController {
return
}
let newWorkItem = DispatchWorkItem { [weak self] in
self?.showNoticeOrAlertAsNeeded()
self?.showNoticeAsNeeded()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: newWorkItem)
alertWorkItem = newWorkItem
Expand All @@ -80,13 +80,8 @@ extension BlogDetailsViewController {
return false
}

private func showNoticeOrAlertAsNeeded() {

if QuickStartTourGuide.shared.shouldShowUpgradeToV2Notice(for: blog) {
showUpgradeToV2Alert(for: blog)

QuickStartTourGuide.shared.didShowUpgradeToV2Notice(for: blog)
} else if let tourToSuggest = QuickStartTourGuide.shared.tourToSuggest(for: blog) {
private func showNoticeAsNeeded() {
if let tourToSuggest = QuickStartTourGuide.shared.tourToSuggest(for: blog) {
QuickStartTourGuide.shared.suggest(tourToSuggest, for: blog)
}
}
Expand Down Expand Up @@ -165,17 +160,4 @@ extension BlogDetailsViewController {
section.showQuickStartMenu = true
return section
}

private func showUpgradeToV2Alert(for blog: Blog) {
guard noPresentedViewControllers else {
return
}

let alert = FancyAlertViewController.makeQuickStartUpgradeToV2AlertController(blog: blog)
alert.modalPresentationStyle = .custom
alert.transitioningDelegate = self
tabBarController?.present(alert, animated: true)

WPAnalytics.track(.quickStartMigrationDialogViewed)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import UIKit

final class QuickStartPromptViewController: UIViewController {

// MARK: - IBOutlets

/// Site info
@IBOutlet private weak var siteIconView: UIImageView!
@IBOutlet private weak var siteTitleLabel: UILabel!
@IBOutlet private weak var siteDescriptionLabel: UILabel!

/// Prompt info
@IBOutlet private weak var promptTitleLabel: UILabel!
@IBOutlet private weak var promptDescriptionLabel: UILabel!

/// Buttons
@IBOutlet private weak var showMeAroundButton: FancyButton!
@IBOutlet private weak var noThanksButton: FancyButton!

// MARK: - Properties

private let blog: Blog
private let quickStartSettings: QuickStartSettings

/// Closure to be executed upon dismissal.
///
var onDismiss: ((Blog) -> Void)?

// MARK: - Init

init(blog: Blog, quickStartSettings: QuickStartSettings = QuickStartSettings()) {
self.blog = blog
self.quickStartSettings = quickStartSettings
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Lifecycle

override func viewDidLoad() {
super.viewDidLoad()
applyStyles()
setup()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIAccessibility.post(notification: .layoutChanged, argument: promptTitleLabel)
}

// MARK: - Styling

private func applyStyles() {
siteTitleLabel.numberOfLines = 0
siteTitleLabel.font = WPStyleGuide.fontForTextStyle(.subheadline)
siteTitleLabel.textColor = .text

siteDescriptionLabel.numberOfLines = 0
siteDescriptionLabel.font = WPStyleGuide.fontForTextStyle(.subheadline)
siteDescriptionLabel.textColor = .textSubtle

promptTitleLabel.numberOfLines = 0
promptTitleLabel.font = WPStyleGuide.fontForTextStyle(.callout, fontWeight: .medium)
promptTitleLabel.textColor = .text

promptDescriptionLabel.numberOfLines = 0
promptDescriptionLabel.font = WPStyleGuide.fontForTextStyle(.subheadline)
promptDescriptionLabel.textColor = .textSubtle

showMeAroundButton.isPrimary = true
noThanksButton.isPrimary = false
}

// MARK: - Setup

private func setup() {
setupSiteInfoViews()
setupPromptInfoViews()
setupButtons()
}

private func setupSiteInfoViews() {
siteIconView.downloadSiteIcon(for: blog)

let displayURL = blog.displayURL as String? ?? ""
if let name = blog.settings?.name?.nonEmptyString() {
siteTitleLabel.text = name
siteDescriptionLabel.text = displayURL
} else {
siteTitleLabel.text = displayURL
siteDescriptionLabel.text = nil
}
}

private func setupPromptInfoViews() {
promptTitleLabel.text = Strings.promptTitle
promptDescriptionLabel.text = Strings.promptDescription
}

private func setupButtons() {
showMeAroundButton.setTitle(Strings.showMeAroundButtonTitle, for: .normal)
noThanksButton.setTitle(Strings.noThanksButtonTitle, for: .normal)
}

// MARK: - IBAction

@IBAction private func showMeAroundButtonTapped(_ sender: Any) {
onDismiss?(blog)
dismiss(animated: true)

WPAnalytics.track(.quickStartRequestAlertButtonTapped, withProperties: ["type": "positive"])
}

@IBAction private func noThanksButtonTapped(_ sender: Any) {
quickStartSettings.setPromptWasDismissed(true, for: blog)
onDismiss?(blog)
dismiss(animated: true)

WPAnalytics.track(.quickStartRequestAlertButtonTapped, withProperties: ["type": "neutral"])
}
}

extension QuickStartPromptViewController {

private enum Strings {
static let promptTitle = NSLocalizedString("Want a little help managing this site with the app?", comment: "Title for a prompt asking if users want to try out the quick start checklist.")
static let promptDescription = NSLocalizedString("Learn the basics with a quick walk through.", comment: "Description for a prompt asking if users want to try out the quick start checklist.")
static let showMeAroundButtonTitle = NSLocalizedString("Show me around", comment: "Button title. When tapped, the quick start checklist will be shown.")
static let noThanksButtonTitle = NSLocalizedString("No thanks", comment: "Button title. When tapped, the quick start checklist will not be shown, and the prompt will be dismissed.")
}

}
124 changes: 124 additions & 0 deletions WordPress/Classes/ViewRelated/Blog/QuickStartPromptViewController.xib
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="QuickStartPromptViewController" customModule="WordPress" customModuleProvider="target">
<connections>
<outlet property="noThanksButton" destination="2uc-tK-alt" id="EyT-E0-oLS"/>
<outlet property="promptDescriptionLabel" destination="Kqr-FO-d5M" id="lbG-CU-xOm"/>
<outlet property="promptTitleLabel" destination="doQ-6M-3Uv" id="i5m-E1-5kU"/>
<outlet property="showMeAroundButton" destination="0WF-fO-mti" id="MyR-dp-DjP"/>
<outlet property="siteDescriptionLabel" destination="T6b-Pg-T2k" id="Jbd-bS-EqF"/>
<outlet property="siteIconView" destination="5pl-dB-rPb" id="ovD-LF-JHV"/>
<outlet property="siteTitleLabel" destination="3V2-cy-NN5" id="ool-ZA-cxV"/>
<outlet property="view" destination="i5M-Pr-FkT" id="w2c-2a-ctD"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" layoutMarginsFollowReadableWidth="YES" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="wS6-OQ-uc5">
<rect key="frame" x="20" y="124" width="374" height="110"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="5oK-P9-biU">
<rect key="frame" x="0.0" y="0.0" width="374" height="45"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="5pl-dB-rPb">
<rect key="frame" x="0.0" y="2.5" width="40" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="LBc-8A-qPF"/>
<constraint firstAttribute="width" secondItem="5pl-dB-rPb" secondAttribute="height" id="VjL-ts-OLa"/>
</constraints>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="lqh-pW-MOV">
<rect key="frame" x="50" y="0.0" width="324" height="45"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3V2-cy-NN5">
<rect key="frame" x="0.0" y="0.0" width="324" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="T6b-Pg-T2k">
<rect key="frame" x="0.0" y="24.5" width="324" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="kWJ-TZ-NYM">
<rect key="frame" x="0.0" y="61" width="374" height="49"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="doQ-6M-3Uv">
<rect key="frame" x="0.0" y="0.0" width="374" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Kqr-FO-d5M">
<rect key="frame" x="0.0" y="28.5" width="374" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="88c-8d-UbI">
<rect key="frame" x="20" y="734" width="374" height="104"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0WF-fO-mti" customClass="FancyButton" customModule="WordPressUI">
<rect key="frame" x="0.0" y="0.0" width="374" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="B3O-Yu-fRo"/>
</constraints>
<state key="normal" title="Button"/>
<connections>
<action selector="showMeAroundButtonTapped:" destination="-1" eventType="touchUpInside" id="mp9-Ig-efP"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2uc-tK-alt" customClass="FancyButton" customModule="WordPressUI">
<rect key="frame" x="0.0" y="60" width="374" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="oud-dv-V6a"/>
</constraints>
<state key="normal" title="Button"/>
<connections>
<action selector="noThanksButtonTapped:" destination="-1" eventType="touchUpInside" id="pO2-el-6ic"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="wS6-OQ-uc5" secondAttribute="trailing" id="Ado-d7-g5C"/>
<constraint firstItem="wS6-OQ-uc5" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leadingMargin" id="MFc-W9-00A"/>
<constraint firstAttribute="leadingMargin" secondItem="88c-8d-UbI" secondAttribute="leading" id="Qbc-f2-ZaH"/>
<constraint firstAttribute="trailingMargin" secondItem="88c-8d-UbI" secondAttribute="trailing" id="daa-Gn-9WI"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="88c-8d-UbI" secondAttribute="bottom" constant="24" id="oQS-J2-RXn"/>
<constraint firstItem="wS6-OQ-uc5" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="80" id="vN3-dJ-56h"/>
</constraints>
<point key="canvasLocation" x="132" y="76"/>
</view>
</objects>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
Loading