UI improvements for add feedbin account

This commit is contained in:
Phil Viso 2019-05-22 21:17:50 -05:00
parent 3e97754ab9
commit 13c0f3a09c
3 changed files with 87 additions and 76 deletions

View File

@ -24,14 +24,14 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
} }
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard.settings
switch indexPath.row { switch indexPath.row {
case 0: case 0:
let addViewController = UIStoryboard.settings.instantiateViewController(withIdentifier: "AddLocalAccountViewController") as! AddLocalAccountViewController let addViewController = storyboard.instantiateViewController(withIdentifier: "AddLocalAccountViewController") as! AddLocalAccountViewController
addViewController.delegate = self addViewController.delegate = self
navigationController?.pushViewController(addViewController, animated: true) navigationController?.pushViewController(addViewController, animated: true)
case 1: case 1:
let navController = UIStoryboard.settings.instantiateViewController(withIdentifier: "FeedbinAccountNavigationViewController") as! UINavigationController let addViewController = storyboard.instantiateViewController(withIdentifier: "FeedbinAccountViewController") as! FeedbinAccountViewController
let addViewController = navController.topViewController as! FeedbinAccountViewController
addViewController.delegate = self addViewController.delegate = self
navigationController?.pushViewController(addViewController, animated: true) navigationController?.pushViewController(addViewController, animated: true)
default: default:

View File

@ -12,11 +12,12 @@ import RSWeb
class FeedbinAccountViewController: UIViewController { class FeedbinAccountViewController: UIViewController {
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView! @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var doneBarButtonItem: UIBarButtonItem!
@IBOutlet weak var emailTextField: UITextField! @IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var addAccountButton: UIButton!
@IBOutlet weak var errorMessageLabel: UILabel! @IBOutlet weak var errorMessageLabel: UILabel!
weak var account: Account? weak var account: Account?
@ -26,6 +27,8 @@ class FeedbinAccountViewController: UIViewController {
super.viewDidLoad() super.viewDidLoad()
activityIndicator.isHidden = true activityIndicator.isHidden = true
emailTextField.delegate = self
passwordTextField.delegate = self
if let account = account, let credentials = try? account.retrieveBasicCredentials() { if let account = account, let credentials = try? account.retrieveBasicCredentials() {
if case .basic(let username, let password) = credentials { if case .basic(let username, let password) = credentials {
@ -35,12 +38,7 @@ class FeedbinAccountViewController: UIViewController {
} }
} }
@IBAction func cancel(_ sender: Any) { @IBAction func addAccountTapped(_ sender: Any) {
dismiss(animated: true)
}
@IBAction func done(_ sender: Any) {
self.errorMessageLabel.text = nil self.errorMessageLabel.text = nil
guard emailTextField.text != nil && passwordTextField.text != nil else { guard emailTextField.text != nil && passwordTextField.text != nil else {
@ -48,26 +46,21 @@ class FeedbinAccountViewController: UIViewController {
return return
} }
cancelBarButtonItem.isEnabled = false startAnimatingActivityIndicator()
doneBarButtonItem.isEnabled = false disableNavigation()
activityIndicator.isHidden = false
activityIndicator.startAnimating()
let credentials = Credentials.basic(username: emailTextField.text ?? "", password: passwordTextField.text ?? "") // When you fill in the email address via auto-complete it adds extra whitespace
let emailAddress = emailTextField.text?.trimmingCharacters(in: .whitespaces)
let credentials = Credentials.basic(username: emailAddress ?? "", password: passwordTextField.text ?? "")
Account.validateCredentials(type: .feedbin, credentials: credentials) { [weak self] result in Account.validateCredentials(type: .feedbin, credentials: credentials) { [weak self] result in
guard let self = self else { return } guard let self = self else { return }
self.cancelBarButtonItem.isEnabled = true self.stopAnimtatingActivityIndicator()
self.doneBarButtonItem.isEnabled = true self.enableNavigation()
self.activityIndicator.isHidden = true
self.activityIndicator.stopAnimating()
switch result { switch result {
case .success(let authenticated): case .success(let authenticated):
if authenticated { if authenticated {
var newAccount = false var newAccount = false
if self.account == nil { if self.account == nil {
self.account = AccountManager.shared.createAccount(type: .feedbin) self.account = AccountManager.shared.createAccount(type: .feedbin)
@ -80,24 +73,49 @@ class FeedbinAccountViewController: UIViewController {
if newAccount { if newAccount {
self.account?.refreshAll() self.account?.refreshAll()
} }
self.dismiss(animated: true)
self.delegate?.dismiss() self.delegate?.dismiss()
} catch { } catch {
self.errorMessageLabel.text = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error") self.errorMessageLabel.text = NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error")
} }
} else { } else {
self.errorMessageLabel.text = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error") self.errorMessageLabel.text = NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error")
} }
case .failure: case .failure:
self.errorMessageLabel.text = NSLocalizedString("Network error. Try again later.", comment: "Credentials Error")
self.errorMessageLabel.text = NSLocalizedString("Network error. Try again later.", comment: "Credentials Error")
} }
} }
}
private func enableNavigation() {
self.navigationItem.backBarButtonItem?.isEnabled = true
self.addAccountButton.isEnabled = true
self.activityIndicator.isHidden = true
}
private func disableNavigation() {
navigationItem.backBarButtonItem?.isEnabled = false
addAccountButton.isEnabled = false
}
private func startAnimatingActivityIndicator() {
activityIndicator.isHidden = false
activityIndicator.startAnimating()
}
private func stopAnimtatingActivityIndicator() {
self.activityIndicator.isHidden = true
self.activityIndicator.stopAnimating()
}
}
extension FeedbinAccountViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
} }
} }

View File

@ -438,7 +438,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountLocal" translatesAutoresizingMaskIntoConstraints="NO" id="tb2-dO-AhR"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountLocal" translatesAutoresizingMaskIntoConstraints="NO" id="tb2-dO-AhR">
<rect key="frame" x="20" y="11.5" width="32" height="32"/> <rect key="frame" x="20" y="11.5" width="32" height="32.000000000000028"/>
<color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="32" id="0GF-vU-aEc"/> <constraint firstAttribute="height" constant="32" id="0GF-vU-aEc"/>
@ -520,7 +520,7 @@
<rect key="frame" x="90.5" y="84" width="233" height="36"/> <rect key="frame" x="90.5" y="84" width="233" height="36"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountLocal" translatesAutoresizingMaskIntoConstraints="NO" id="74E-kl-vU9"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountLocal" translatesAutoresizingMaskIntoConstraints="NO" id="74E-kl-vU9">
<rect key="frame" x="0.0" y="2" width="32" height="32"/> <rect key="frame" x="0.0" y="2" width="32" height="32.000000000000028"/>
<color key="tintColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="tintColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="32" id="E7T-ps-KgX"/> <constraint firstAttribute="width" constant="32" id="E7T-ps-KgX"/>
@ -580,23 +580,7 @@
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="oPp-xq-kz9" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="oPp-xq-kz9" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2564" y="144"/> <point key="canvasLocation" x="2510" y="139"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="qOt-Py-TKw">
<objects>
<navigationController storyboardIdentifier="FeedbinAccountNavigationViewController" id="AGX-Ph-lE3" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="fpp-8U-JGs">
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="byh-sg-6p5" kind="relationship" relationship="rootViewController" id="u92-3E-dIA"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ieC-Y8-e5K" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3919" y="145"/>
</scene> </scene>
<!--Feedbin Account View Controller--> <!--Feedbin Account View Controller-->
<scene sceneID="sCm-Gd-byr"> <scene sceneID="sCm-Gd-byr">
@ -607,7 +591,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="vFL-2i-eRz"> <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="vFL-2i-eRz">
<rect key="frame" x="129" y="108" width="156" height="36"/> <rect key="frame" x="129" y="84" width="156" height="36"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountFeedbin" translatesAutoresizingMaskIntoConstraints="NO" id="9ht-ce-lQp"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="accountFeedbin" translatesAutoresizingMaskIntoConstraints="NO" id="9ht-ce-lQp">
<rect key="frame" x="0.0" y="2" width="32" height="32"/> <rect key="frame" x="0.0" y="2" width="32" height="32"/>
@ -626,55 +610,65 @@
</subviews> </subviews>
</stackView> </stackView>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="UiV-th-dQb"> <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="UiV-th-dQb">
<rect key="frame" x="107" y="160" width="200" height="30"/> <rect key="frame" x="0.0" y="140" width="414" height="48"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="200" id="ULv-Nf-M1O"/> <constraint firstAttribute="height" constant="48" id="UjW-Pq-uNU"/>
</constraints> </constraints>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" keyboardType="emailAddress" textContentType="email"/> <textInputTraits key="textInputTraits" keyboardType="emailAddress" textContentType="email"/>
</textField> </textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="lDh-Kk-Kem"> <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Password" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="lDh-Kk-Kem">
<rect key="frame" x="107" y="198" width="200" height="30"/> <rect key="frame" x="0.0" y="196" width="414" height="48"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="200" id="vMu-uR-0vC"/> <constraint firstAttribute="height" constant="48" id="pKQ-Mm-Oc8"/>
</constraints> </constraints>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/> <textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/>
</textField> </textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9QD-Wz-fqW"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pv5-O6-P6Z">
<rect key="frame" x="207" y="244" width="0.0" height="0.0"/> <rect key="frame" x="0.0" y="264" width="414" height="48"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="48" id="8Vt-l1-eL1"/>
</constraints>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/> <state key="normal" title="Add Account"/>
<connections>
<action selector="addAccountTapped:" destination="byh-sg-6p5" eventType="touchUpInside" id="BFR-MI-1qW"/>
<action selector="addAccountTapped:" destination="lkT-rF-XV3" eventType="touchUpInside" id="YKl-dE-pVK"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9QD-Wz-fqW">
<rect key="frame" x="207" y="332" width="0.0" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" red="0.93735349178314209" green="0.93682962656021118" blue="0.95681577920913696" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<constraints> <constraints>
<constraint firstItem="UiV-th-dQb" firstAttribute="top" secondItem="vFL-2i-eRz" secondAttribute="bottom" constant="16" id="BUG-5p-BDh"/> <constraint firstItem="UiV-th-dQb" firstAttribute="leading" secondItem="4Rm-PZ-VHc" secondAttribute="leading" id="1ok-W1-dkI"/>
<constraint firstItem="UiV-th-dQb" firstAttribute="top" secondItem="vFL-2i-eRz" secondAttribute="bottom" constant="20" id="BUG-5p-BDh"/>
<constraint firstItem="9QD-Wz-fqW" firstAttribute="top" secondItem="pv5-O6-P6Z" secondAttribute="bottom" constant="20" id="BxD-TQ-zRm"/>
<constraint firstItem="4Rm-PZ-VHc" firstAttribute="trailing" secondItem="lDh-Kk-Kem" secondAttribute="trailing" id="CUI-hN-BsR"/>
<constraint firstItem="pv5-O6-P6Z" firstAttribute="trailing" secondItem="4Rm-PZ-VHc" secondAttribute="trailing" id="DkX-t4-GH3"/>
<constraint firstItem="pv5-O6-P6Z" firstAttribute="leading" secondItem="4Rm-PZ-VHc" secondAttribute="leading" id="Jhs-JE-qWd"/>
<constraint firstItem="lDh-Kk-Kem" firstAttribute="top" secondItem="UiV-th-dQb" secondAttribute="bottom" constant="8" id="N81-px-3YV"/> <constraint firstItem="lDh-Kk-Kem" firstAttribute="top" secondItem="UiV-th-dQb" secondAttribute="bottom" constant="8" id="N81-px-3YV"/>
<constraint firstItem="9QD-Wz-fqW" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="Sgr-tG-nT2"/> <constraint firstItem="9QD-Wz-fqW" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="Sgr-tG-nT2"/>
<constraint firstItem="vFL-2i-eRz" firstAttribute="top" secondItem="4Rm-PZ-VHc" secondAttribute="top" constant="20" id="khS-vK-fL0"/> <constraint firstItem="pv5-O6-P6Z" firstAttribute="top" secondItem="lDh-Kk-Kem" secondAttribute="bottom" constant="20" id="UUS-1q-Fn4"/>
<constraint firstItem="4Rm-PZ-VHc" firstAttribute="trailing" secondItem="UiV-th-dQb" secondAttribute="trailing" id="hfB-Ql-twm"/>
<constraint firstItem="vFL-2i-eRz" firstAttribute="top" secondItem="4Rm-PZ-VHc" secondAttribute="top" constant="40" id="khS-vK-fL0"/>
<constraint firstItem="lDh-Kk-Kem" firstAttribute="leading" secondItem="4Rm-PZ-VHc" secondAttribute="leading" id="nHZ-XJ-CXN"/>
<constraint firstItem="vFL-2i-eRz" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="qew-4G-xhG"/> <constraint firstItem="vFL-2i-eRz" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="qew-4G-xhG"/>
<constraint firstItem="9QD-Wz-fqW" firstAttribute="top" secondItem="lDh-Kk-Kem" secondAttribute="bottom" constant="16" id="u49-x7-qrR"/>
<constraint firstItem="UiV-th-dQb" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="vLa-hN-GpR"/> <constraint firstItem="UiV-th-dQb" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="vLa-hN-GpR"/>
<constraint firstItem="lDh-Kk-Kem" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="zjW-9v-aqJ"/> <constraint firstItem="lDh-Kk-Kem" firstAttribute="centerX" secondItem="E6e-jd-9b6" secondAttribute="centerX" id="zjW-9v-aqJ"/>
</constraints> </constraints>
<viewLayoutGuide key="safeArea" id="4Rm-PZ-VHc"/> <viewLayoutGuide key="safeArea" id="4Rm-PZ-VHc"/>
</view> </view>
<navigationItem key="navigationItem" id="BFN-hJ-pWd"> <navigationItem key="navigationItem" id="BFN-hJ-pWd">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="hLE-sO-Oak">
<connections>
<action selector="cancel:" destination="byh-sg-6p5" id="Ghd-hv-96w"/>
</connections>
</barButtonItem>
<rightBarButtonItems> <rightBarButtonItems>
<barButtonItem systemItem="done" id="2cL-39-uWX">
<connections>
<action selector="done:" destination="byh-sg-6p5" id="p1d-pI-ioe"/>
</connections>
</barButtonItem>
<barButtonItem style="plain" id="L90-ti-E7I"> <barButtonItem style="plain" id="L90-ti-E7I">
<view key="customView" contentMode="scaleToFill" id="xpt-lr-f2h"> <view key="customView" contentMode="scaleToFill" id="xpt-lr-f2h">
<rect key="frame" x="325.5" y="12" width="20" height="20"/> <rect key="frame" x="325.5" y="12" width="20" height="20"/>
@ -692,8 +686,7 @@
</navigationItem> </navigationItem>
<connections> <connections>
<outlet property="activityIndicator" destination="Pl1-lc-sIl" id="hqg-mX-Yns"/> <outlet property="activityIndicator" destination="Pl1-lc-sIl" id="hqg-mX-Yns"/>
<outlet property="cancelBarButtonItem" destination="hLE-sO-Oak" id="hdM-yd-oDT"/> <outlet property="addAccountButton" destination="pv5-O6-P6Z" id="DEh-oq-rnD"/>
<outlet property="doneBarButtonItem" destination="2cL-39-uWX" id="wUU-LS-5k8"/>
<outlet property="emailTextField" destination="UiV-th-dQb" id="fCb-hg-AXa"/> <outlet property="emailTextField" destination="UiV-th-dQb" id="fCb-hg-AXa"/>
<outlet property="errorMessageLabel" destination="9QD-Wz-fqW" id="Kjo-73-Pgh"/> <outlet property="errorMessageLabel" destination="9QD-Wz-fqW" id="Kjo-73-Pgh"/>
<outlet property="passwordTextField" destination="lDh-Kk-Kem" id="ew7-Ej-UpK"/> <outlet property="passwordTextField" destination="lDh-Kk-Kem" id="ew7-Ej-UpK"/>
@ -701,7 +694,7 @@
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="l5n-Op-NE2" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="l5n-Op-NE2" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="4642" y="144"/> <point key="canvasLocation" x="3203" y="139"/>
</scene> </scene>
<!--Timeline Text--> <!--Timeline Text-->
<scene sceneID="07z-Vb-4Fm"> <scene sceneID="07z-Vb-4Fm">