From 8e372dd864528ee377b19b83c93e117b42a4271c Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Sat, 30 Sep 2017 23:07:18 -0600 Subject: [PATCH 01/14] Add error screen VC --- .../NUX/LoginSocialErrorCell.swift | 64 +++++++++ .../NUX/LoginSocialErrorViewController.swift | 132 ++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift create mode 100644 WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift new file mode 100644 index 000000000000..88a8f226f1c1 --- /dev/null +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift @@ -0,0 +1,64 @@ +class LoginSocialErrorCell: UITableViewCell { + private let errorTitle: String + private let errorDescription: String + private let titleLabel: UILabel + private let descriptionLabel: UILabel + private let labelStack: UIStackView + + private struct Constants { + static let labelSpacing: CGFloat = 15.0 + static let labelVerticalMargin: CGFloat = 20.0 + } + + init(title: String, description: String) { + errorTitle = title + errorDescription = description + titleLabel = UILabel(frame: .zero) + descriptionLabel = UILabel(frame: .zero) + labelStack = UIStackView(frame: .zero) + + super.init(style: .default, reuseIdentifier: "LoginSocialErrorCell") + + layoutLabels() + } + + required init?(coder aDecoder: NSCoder) { + errorTitle = aDecoder.value(forKey: "errorTitle") as? String ?? "" + errorDescription = aDecoder.value(forKey: "errorDescription") as? String ?? "" + titleLabel = UILabel(frame: .zero) + descriptionLabel = UILabel(frame: .zero) + labelStack = UIStackView(frame: .zero) + + super.init(coder: aDecoder) + + layoutLabels() + } + + private func layoutLabels() { + contentView.addSubview(labelStack) + labelStack.translatesAutoresizingMaskIntoConstraints = false + labelStack.addArrangedSubview(titleLabel) + labelStack.addArrangedSubview(descriptionLabel) + labelStack.axis = .vertical + labelStack.spacing = Constants.labelSpacing + + titleLabel.font = WPStyleGuide.fontForTextStyle(.footnote) + titleLabel.textColor = WPStyleGuide.greyDarken30() + descriptionLabel.font = WPStyleGuide.mediumWeightFont(forStyle: .subheadline) + descriptionLabel.textColor = WPStyleGuide.darkGrey() + descriptionLabel.numberOfLines = 0 + descriptionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 14.0).isActive = true + + contentView.addConstraints([ + contentView.topAnchor.constraint(equalTo: labelStack.topAnchor, constant: Constants.labelVerticalMargin * -1.0), + contentView.bottomAnchor.constraint(equalTo: labelStack.bottomAnchor, constant: Constants.labelVerticalMargin), + contentView.layoutMarginsGuide.leadingAnchor.constraint(equalTo: labelStack.leadingAnchor), + contentView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: labelStack.trailingAnchor) + ]) + + titleLabel.text = errorTitle.localizedUppercase + descriptionLabel.text = errorDescription + + backgroundColor = WPStyleGuide.greyLighten30() + } +} diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift new file mode 100644 index 000000000000..2a0f6ac51c60 --- /dev/null +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -0,0 +1,132 @@ +import Foundation +import Gridicons + +class LoginSocialErrorViewController: UITableViewController { + fileprivate var errorTitle: String + fileprivate var errorDescription: String + + init(title: String, description: String) { + errorTitle = title + errorDescription = description + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + errorTitle = aDecoder.value(forKey: "errorTitle") as? String ?? "" + errorDescription = aDecoder.value(forKey: "errorDescription") as? String ?? "" + + super.init(coder: aDecoder) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + tableView.estimatedRowHeight = 100.0 + + view.backgroundColor = WPStyleGuide.greyLighten30() + } +} + + +// MARK: UITableViewDelegate methods + +extension LoginSocialErrorViewController { + fileprivate enum Sections: Int { + case titleAndDescription = 0 + case buttons = 1 + + static var count: Int { + return buttons.rawValue + 1 + } + } + + override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { + switch indexPath.section { + case Sections.titleAndDescription.rawValue: + return 300.0 + case Sections.buttons.rawValue: + fallthrough + default: + return 50.0 + } + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableViewAutomaticDimension + } +} + + +// MARK: UITableViewDataSource methods + +extension LoginSocialErrorViewController +{ + private struct Constants { + static let buttonCount = 3 + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return Sections.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch section { + case Sections.titleAndDescription.rawValue: + return 1 + case Sections.buttons.rawValue: + return Constants.buttonCount + default: + return 0 + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell: UITableViewCell + switch indexPath.section { + case Sections.titleAndDescription.rawValue: + cell = titleAndDescriptionCell() + case Sections.buttons.rawValue: + fallthrough + default: + cell = buttonCell(index: indexPath.row) + } + return cell + } + + override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + let footer = UIView() + footer.backgroundColor = WPStyleGuide.greyLighten20() + return footer + } + + override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 0.5 + } + + private func titleAndDescriptionCell() -> UITableViewCell { + return LoginSocialErrorCell(title: errorTitle, description: errorDescription) + } + + private func buttonCell(index: Int) -> UITableViewCell { + let cell = UITableViewCell(frame: .zero) + let buttonText: String + let buttonIcon: UIImage + switch index { + case 0: + buttonText = NSLocalizedString("Try with another email", comment: "When social login fails, this button offers to let the user try again with a differen email address") + buttonIcon = Gridicon.iconOfType(.undo) + case 1: + buttonText = NSLocalizedString("Try with the site address", comment: "When social login fails, this button offers to let them try tp login using a URL") + buttonIcon = Gridicon.iconOfType(.domains) + case 2: + fallthrough + default: + buttonText = NSLocalizedString("Sign up", comment: "When social login fails, this button offers to let them signup for a new WordPress.com account") + buttonIcon = Gridicon.iconOfType(.mySites) + } + cell.textLabel?.text = buttonText + cell.imageView?.image = buttonIcon.imageWithTintColor(WPStyleGuide.grey()) + return cell + } +} From be1e614ff5b2e91ae79caae1c8ad51fb6879740a Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Sat, 30 Sep 2017 23:38:54 -0600 Subject: [PATCH 02/14] Add social login error action to try again buttons --- .../NUX/LoginSocialErrorViewController.swift | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 2a0f6ac51c60..0a7ddaad46b8 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -5,6 +5,21 @@ class LoginSocialErrorViewController: UITableViewController { fileprivate var errorTitle: String fileprivate var errorDescription: String + fileprivate enum Sections: Int { + case titleAndDescription = 0 + case buttons = 1 + + static var count: Int { + return buttons.rawValue + 1 + } + } + + fileprivate enum Buttons: Int { + case tryEmail = 0 + case tryAddress = 1 + case signup = 2 + } + init(title: String, description: String) { errorTitle = title errorDescription = description @@ -26,30 +41,39 @@ class LoginSocialErrorViewController: UITableViewController { view.backgroundColor = WPStyleGuide.greyLighten30() } -} + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard indexPath.section == Sections.buttons.rawValue else { + return + } -// MARK: UITableViewDelegate methods + let storyboard = UIStoryboard(name: "Login", bundle: nil) -extension LoginSocialErrorViewController { - fileprivate enum Sections: Int { - case titleAndDescription = 0 - case buttons = 1 + let controller: NUXAbstractViewController? - static var count: Int { - return buttons.rawValue + 1 + switch indexPath.row { + case Buttons.tryEmail.rawValue: + controller = storyboard.instantiateViewController(withIdentifier: "emailEntry") as? NUXAbstractViewController + case Buttons.tryAddress.rawValue: + controller = storyboard.instantiateViewController(withIdentifier: "siteAddress") as? NUXAbstractViewController + case Buttons.signup.rawValue: + fallthrough + default: + controller = nil + } + + if let controller = controller { + navigationController?.setViewControllers([controller], animated: true) } } +} + +// MARK: UITableViewDelegate methods + +extension LoginSocialErrorViewController { override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { - switch indexPath.section { - case Sections.titleAndDescription.rawValue: - return 300.0 - case Sections.buttons.rawValue: - fallthrough - default: - return 50.0 - } + return 45.0 } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { @@ -113,13 +137,13 @@ extension LoginSocialErrorViewController let buttonText: String let buttonIcon: UIImage switch index { - case 0: + case Buttons.tryEmail.rawValue: buttonText = NSLocalizedString("Try with another email", comment: "When social login fails, this button offers to let the user try again with a differen email address") buttonIcon = Gridicon.iconOfType(.undo) - case 1: + case Buttons.tryAddress.rawValue: buttonText = NSLocalizedString("Try with the site address", comment: "When social login fails, this button offers to let them try tp login using a URL") buttonIcon = Gridicon.iconOfType(.domains) - case 2: + case Buttons.signup.rawValue: fallthrough default: buttonText = NSLocalizedString("Sign up", comment: "When social login fails, this button offers to let them signup for a new WordPress.com account") From e38ed8919e3cb1de7c790e4a6a6b654e3e2b68c0 Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Sun, 1 Oct 2017 22:41:13 -0600 Subject: [PATCH 03/14] Add signup button to social login error --- .../NUX/LoginSocialErrorViewController.swift | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 0a7ddaad46b8..10ca787e31eb 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -47,22 +47,20 @@ class LoginSocialErrorViewController: UITableViewController { return } - let storyboard = UIStoryboard(name: "Login", bundle: nil) - - let controller: NUXAbstractViewController? - + let controllerKey: String switch indexPath.row { case Buttons.tryEmail.rawValue: - controller = storyboard.instantiateViewController(withIdentifier: "emailEntry") as? NUXAbstractViewController + controllerKey = "emailEntry" case Buttons.tryAddress.rawValue: - controller = storyboard.instantiateViewController(withIdentifier: "siteAddress") as? NUXAbstractViewController + controllerKey = "siteAddress" case Buttons.signup.rawValue: fallthrough default: - controller = nil + controllerKey = "SignupViewController" } - if let controller = controller { + let storyboard = UIStoryboard(name: "Login", bundle: nil) + if let controller = storyboard.instantiateViewController(withIdentifier: controllerKey) as? NUXAbstractViewController { navigationController?.setViewControllers([controller], animated: true) } } From 64a020bd81310a3b25911f54269492474bdc0add Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Sun, 1 Oct 2017 23:11:39 -0600 Subject: [PATCH 04/14] Add display of error screen to google login --- .../ViewRelated/NUX/LoginEmailViewController.swift | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift index 252a9506616e..20ed10ae1187 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift @@ -13,6 +13,7 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { var didFindSafariSharedCredentials = false var didRequestSafariSharedCredentials = false + fileprivate var awaitingGoogle = false override var restrictToWPCom: Bool { didSet { if isViewLoaded { @@ -144,6 +145,8 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { } func googleLoginTapped() { + awaitingGoogle = true + GIDSignIn.sharedInstance().delegate = self GIDSignIn.sharedInstance().uiDelegate = self GIDSignIn.sharedInstance().clientID = ApiCredentials.googleLoginClientId() @@ -304,10 +307,15 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { } override func displayRemoteError(_ error: Error!) { - configureViewLoading(false) + if awaitingGoogle { + let socialErrorVC = LoginSocialErrorViewController(title: NSLocalizedString("Unable To Connect", comment: "Shown when a user logs in with Google but it subsequently fails to work as login to WordPress.com"), description: error.localizedDescription) + navigationController?.setViewControllers([socialErrorVC], animated: true) + } else { + configureViewLoading(false) - errorToPresent = error - performSegue(withIdentifier: .showWPComLogin, sender: self) + errorToPresent = error + performSegue(withIdentifier: .showWPComLogin, sender: self) + } } From bc51ab862f38c82a1deb3f7775c5b8e2fc1be71c Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Sun, 1 Oct 2017 23:43:31 -0600 Subject: [PATCH 05/14] fix a brace from a really bad bad brace to an obviously better one --- .../ViewRelated/NUX/LoginSocialErrorViewController.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 10ca787e31eb..3dc8ff2eecf3 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -82,8 +82,7 @@ extension LoginSocialErrorViewController { // MARK: UITableViewDataSource methods -extension LoginSocialErrorViewController -{ +extension LoginSocialErrorViewController { private struct Constants { static let buttonCount = 3 } From 0ec7017fdbff82dde599c5dc16453fa2521411dd Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Mon, 2 Oct 2017 14:01:25 -0600 Subject: [PATCH 06/14] Add missing new entries to project file --- WordPress/WordPress.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index cbf701fda470..5940e9e57433 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -198,6 +198,8 @@ 43D2AE441EF704A70009387E /* LoginProloguePromoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D2AE431EF704A70009387E /* LoginProloguePromoViewController.swift */; }; 43D54D131DCAA070007F575F /* PostPostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D54D121DCAA070007F575F /* PostPostViewController.swift */; }; 43F258AA1ED7772C0075406B /* LoginPrologueViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F258A91ED7772C0075406B /* LoginPrologueViewController.swift */; }; + 43F283C01F82DEAC00DC00F1 /* LoginSocialErrorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C5A3E11F80AED50008BE81 /* LoginSocialErrorCell.swift */; }; + 43F283C11F82DEAE00DC00F1 /* LoginSocialErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F295951F7EA74E00E51E2A /* LoginSocialErrorViewController.swift */; }; 43FB3F411EBD215C00FC8A62 /* LoginEpilogueBlogCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43FB3F401EBD215C00FC8A62 /* LoginEpilogueBlogCell.swift */; }; 43FB3F431EC0DDAD00FC8A62 /* LoginEpilogueSectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43FB3F421EC0DDAD00FC8A62 /* LoginEpilogueSectionHeader.xib */; }; 43FB3F451EC1020600FC8A62 /* LoginEpilogueSectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43FB3F441EC1020600FC8A62 /* LoginEpilogueSectionHeader.swift */; }; @@ -1280,12 +1282,14 @@ 43A85B301E9E815B00FA990B /* Login.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Login.storyboard; sourceTree = ""; }; 43AB7C5D1D3E70510066CB6A /* PostListFilterSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostListFilterSettings.swift; sourceTree = ""; }; 43AD9F9B1F4F756C00565CE6 /* LoginTextButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginTextButton.swift; sourceTree = ""; }; + 43C5A3E11F80AED50008BE81 /* LoginSocialErrorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginSocialErrorCell.swift; sourceTree = ""; }; 43CC1EBF1ED898E30097E334 /* LoginTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginTextField.swift; sourceTree = ""; }; 43CE48B21F103C1F00768B87 /* FancyAlertViewController+LoginError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FancyAlertViewController+LoginError.swift"; sourceTree = ""; }; 43D2436C1EAFCE3C00D0C77B /* LoginSegueHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginSegueHandler.swift; sourceTree = ""; }; 43D2AE431EF704A70009387E /* LoginProloguePromoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginProloguePromoViewController.swift; sourceTree = ""; }; 43D54D121DCAA070007F575F /* PostPostViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostPostViewController.swift; sourceTree = ""; }; 43F258A91ED7772C0075406B /* LoginPrologueViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginPrologueViewController.swift; sourceTree = ""; }; + 43F295951F7EA74E00E51E2A /* LoginSocialErrorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginSocialErrorViewController.swift; sourceTree = ""; }; 43FB3F401EBD215C00FC8A62 /* LoginEpilogueBlogCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginEpilogueBlogCell.swift; sourceTree = ""; }; 43FB3F421EC0DDAD00FC8A62 /* LoginEpilogueSectionHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LoginEpilogueSectionHeader.xib; sourceTree = ""; }; 43FB3F441EC1020600FC8A62 /* LoginEpilogueSectionHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginEpilogueSectionHeader.swift; sourceTree = ""; }; @@ -3037,6 +3041,15 @@ path = Animations; sourceTree = ""; }; + 43F295941F7EA72800E51E2A /* Social Login */ = { + isa = PBXGroup; + children = ( + 43F295951F7EA74E00E51E2A /* LoginSocialErrorViewController.swift */, + 43C5A3E11F80AED50008BE81 /* LoginSocialErrorCell.swift */, + ); + name = "Social Login"; + sourceTree = ""; + }; 45C73C23113C36F50024D0D2 /* Resources-iPad */ = { isa = PBXGroup; children = ( @@ -5029,6 +5042,7 @@ E6C1E8441EF1D25D00D139D9 /* Magic Links */, E6C1E8451EF1D28500D139D9 /* SelfHosted */, E6C1E8431EF1D21F00D139D9 /* Epilogue */, + 43F295941F7EA72800E51E2A /* Social Login */, 434D96051EA92A4A00B90B89 /* Login2FAViewController.swift */, 438A80971EA5666B005D4651 /* LoginEmailViewController.swift */, 438A809D1EA5DC31005D4651 /* LoginWPComViewController.swift */, @@ -6055,6 +6069,7 @@ B587797D19B799D800E57C5A /* UIDevice+Helpers.swift in Sources */, E2AA87A518523E5300886693 /* UIView+Subviews.m in Sources */, 5D51ADAF19A832AF00539C0B /* WordPress-20-21.xcmappingmodel in Sources */, + 43F283C01F82DEAC00DC00F1 /* LoginSocialErrorCell.swift in Sources */, 434D96061EA92A4A00B90B89 /* Login2FAViewController.swift in Sources */, 43FB3F471EC10F1E00FC8A62 /* LoginEpilogueTableView.swift in Sources */, 93C486511810445D00A24725 /* ActivityLogViewController.m in Sources */, @@ -6309,6 +6324,7 @@ 5926E1E31AC4468300964783 /* WPCrashlytics.m in Sources */, E16273E11B2ACEB600088AF7 /* BlogToBlog32to33.swift in Sources */, E678FC151C76241000F55F55 /* WPStyleGuide+ApplicationStyles.swift in Sources */, + 43F283C11F82DEAE00DC00F1 /* LoginSocialErrorViewController.swift in Sources */, E66EB6F91C1B7A76003DABC5 /* ReaderSpacerView.swift in Sources */, B55853F31962337500FAF6C3 /* NSScanner+Helpers.m in Sources */, 17EC9FC61DDC761D00D5BE8E /* UIWindow+Helpers.swift in Sources */, From eb709dcbc1bdfb20eb7361964d7e9165a224781a Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Wed, 4 Oct 2017 14:23:03 -0600 Subject: [PATCH 07/14] Change button color to darkGrey --- .../Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 3dc8ff2eecf3..a6786f9d4aa1 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -147,6 +147,7 @@ extension LoginSocialErrorViewController { buttonIcon = Gridicon.iconOfType(.mySites) } cell.textLabel?.text = buttonText + cell.textLabel?.textColor = WPStyleGuide.darkGrey() cell.imageView?.image = buttonIcon.imageWithTintColor(WPStyleGuide.grey()) return cell } From 1d6228a7c269145d4f67f3fdb07c6d2e9b4e3fed Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Wed, 4 Oct 2017 14:36:01 -0600 Subject: [PATCH 08/14] Set awaitingGoogle back to false, cleanup configureViewLoading --- .../Classes/ViewRelated/NUX/LoginEmailViewController.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift index 20ed10ae1187..2a846f367738 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift @@ -307,12 +307,14 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { } override func displayRemoteError(_ error: Error!) { + configureViewLoading(false) + if awaitingGoogle { + awaitingGoogle = false + let socialErrorVC = LoginSocialErrorViewController(title: NSLocalizedString("Unable To Connect", comment: "Shown when a user logs in with Google but it subsequently fails to work as login to WordPress.com"), description: error.localizedDescription) navigationController?.setViewControllers([socialErrorVC], animated: true) } else { - configureViewLoading(false) - errorToPresent = error performSegue(withIdentifier: .showWPComLogin, sender: self) } From 2af050a0c435475f7fdd8fe35af4d2a60a185e30 Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Wed, 4 Oct 2017 14:38:58 -0600 Subject: [PATCH 09/14] Make min height value a Constant --- WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift index 88a8f226f1c1..ea7c52f88593 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift @@ -8,6 +8,7 @@ class LoginSocialErrorCell: UITableViewCell { private struct Constants { static let labelSpacing: CGFloat = 15.0 static let labelVerticalMargin: CGFloat = 20.0 + static let descriptionMinHeight: CGFloat = 14.0 } init(title: String, description: String) { @@ -47,7 +48,7 @@ class LoginSocialErrorCell: UITableViewCell { descriptionLabel.font = WPStyleGuide.mediumWeightFont(forStyle: .subheadline) descriptionLabel.textColor = WPStyleGuide.darkGrey() descriptionLabel.numberOfLines = 0 - descriptionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 14.0).isActive = true + descriptionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: Constants.descriptionMinHeight).isActive = true contentView.addConstraints([ contentView.topAnchor.constraint(equalTo: labelStack.topAnchor, constant: Constants.labelVerticalMargin * -1.0), From 42d648c18539de05ad7f53e01c185036e08dce2c Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Wed, 4 Oct 2017 15:27:41 -0600 Subject: [PATCH 10/14] Move bg color to viewDidLoad; clean up estimated height code --- .../NUX/LoginSocialErrorViewController.swift | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index a6786f9d4aa1..f79df05796d0 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -34,10 +34,8 @@ class LoginSocialErrorViewController: UITableViewController { super.init(coder: aDecoder) } - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - - tableView.estimatedRowHeight = 100.0 + override func viewDidLoad() { + super.viewDidLoad() view.backgroundColor = WPStyleGuide.greyLighten30() } @@ -70,12 +68,17 @@ class LoginSocialErrorViewController: UITableViewController { // MARK: UITableViewDelegate methods extension LoginSocialErrorViewController { + private struct RowHeightConstants { + static let estimate: CGFloat = 45.0 + static let automatic: CGFloat = UITableViewAutomaticDimension + } + override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { - return 45.0 + return RowHeightConstants.estimate } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return UITableViewAutomaticDimension + return RowHeightConstants.automatic } } From c93e916c6aa3473430a1a8630d28e693eb8d1855 Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Wed, 4 Oct 2017 15:43:38 -0600 Subject: [PATCH 11/14] Remove frame: .zero init calls --- .../ViewRelated/NUX/LoginSocialErrorCell.swift | 12 ++++++------ .../NUX/LoginSocialErrorViewController.swift | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift index ea7c52f88593..7e3fcecd638e 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorCell.swift @@ -14,9 +14,9 @@ class LoginSocialErrorCell: UITableViewCell { init(title: String, description: String) { errorTitle = title errorDescription = description - titleLabel = UILabel(frame: .zero) - descriptionLabel = UILabel(frame: .zero) - labelStack = UIStackView(frame: .zero) + titleLabel = UILabel() + descriptionLabel = UILabel() + labelStack = UIStackView() super.init(style: .default, reuseIdentifier: "LoginSocialErrorCell") @@ -26,9 +26,9 @@ class LoginSocialErrorCell: UITableViewCell { required init?(coder aDecoder: NSCoder) { errorTitle = aDecoder.value(forKey: "errorTitle") as? String ?? "" errorDescription = aDecoder.value(forKey: "errorDescription") as? String ?? "" - titleLabel = UILabel(frame: .zero) - descriptionLabel = UILabel(frame: .zero) - labelStack = UIStackView(frame: .zero) + titleLabel = UILabel() + descriptionLabel = UILabel() + labelStack = UIStackView() super.init(coder: aDecoder) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index f79df05796d0..07f2ba444edb 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -133,7 +133,7 @@ extension LoginSocialErrorViewController { } private func buttonCell(index: Int) -> UITableViewCell { - let cell = UITableViewCell(frame: .zero) + let cell = UITableViewCell() let buttonText: String let buttonIcon: UIImage switch index { From e30271b64c87a3e0080a4ddf4ec68d986f95c649 Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Thu, 5 Oct 2017 13:19:31 -0600 Subject: [PATCH 12/14] Add some comments to LoginSocialErrorViewController --- .../ViewRelated/NUX/LoginSocialErrorViewController.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 07f2ba444edb..1a262ecb6c3c 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -1,6 +1,8 @@ import Foundation import Gridicons + +/// ViewController for presenting recovery options when social login fails class LoginSocialErrorViewController: UITableViewController { fileprivate var errorTitle: String fileprivate var errorDescription: String @@ -20,6 +22,11 @@ class LoginSocialErrorViewController: UITableViewController { case signup = 2 } + /// Create and instance of LoginSocialErrorViewController + /// + /// - Parameters: + /// - title: The title that will be shown on the error VC + /// - description: A brief explination of what failed during social login init(title: String, description: String) { errorTitle = title errorDescription = description From fee9eda09ee99a5bbd2eccbe7d3efaac2ecb2a29 Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Thu, 5 Oct 2017 14:16:08 -0600 Subject: [PATCH 13/14] Switch social error VC to use modal presentation --- .../NUX/LoginEmailViewController.swift | 26 ++++++++++++++++++- .../NUX/LoginSocialErrorViewController.swift | 22 +++++++++------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift index 2a846f367738..8a5237e28365 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift @@ -313,7 +313,9 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { awaitingGoogle = false let socialErrorVC = LoginSocialErrorViewController(title: NSLocalizedString("Unable To Connect", comment: "Shown when a user logs in with Google but it subsequently fails to work as login to WordPress.com"), description: error.localizedDescription) - navigationController?.setViewControllers([socialErrorVC], animated: true) + let socialErrorNav = LoginNavigationController(rootViewController: socialErrorVC) + socialErrorVC.delegate = self + present(socialErrorNav, animated: true) {} } else { errorToPresent = error performSegue(withIdentifier: .showWPComLogin, sender: self) @@ -419,5 +421,27 @@ extension LoginEmailViewController: GIDSignInDelegate { } } +extension LoginEmailViewController: LoginSocialErrorViewControllerDelegate { + private func cleanupAfterSocialErrors() { + loginFields.username = "" + dismiss(animated: true) {} + } + + func retryWithEmail() { + cleanupAfterSocialErrors() + } + func retryWithAddress() { + cleanupAfterSocialErrors() + loginToSelfHostedSite() + } + func retryAsSignup() { + cleanupAfterSocialErrors() + let storyboard = UIStoryboard(name: "Login", bundle: nil) + if let controller = storyboard.instantiateViewController(withIdentifier: "SignupViewController") as? NUXAbstractViewController { + navigationController?.pushViewController(controller, animated: true) + } + } +} + extension LoginEmailViewController: GIDSignInUIDelegate { } diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 1a262ecb6c3c..77ad14bb3a9a 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -1,11 +1,18 @@ import Foundation import Gridicons +@objc +protocol LoginSocialErrorViewControllerDelegate { + func retryWithEmail() + func retryWithAddress() + func retryAsSignup() +} /// ViewController for presenting recovery options when social login fails class LoginSocialErrorViewController: UITableViewController { fileprivate var errorTitle: String fileprivate var errorDescription: String + var delegate: LoginSocialErrorViewControllerDelegate? fileprivate enum Sections: Int { case titleAndDescription = 0 @@ -48,25 +55,20 @@ class LoginSocialErrorViewController: UITableViewController { } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard indexPath.section == Sections.buttons.rawValue else { + guard indexPath.section == Sections.buttons.rawValue, + let delegate = delegate else { return } - let controllerKey: String switch indexPath.row { case Buttons.tryEmail.rawValue: - controllerKey = "emailEntry" + delegate.retryWithEmail() case Buttons.tryAddress.rawValue: - controllerKey = "siteAddress" + delegate.retryWithAddress() case Buttons.signup.rawValue: fallthrough default: - controllerKey = "SignupViewController" - } - - let storyboard = UIStoryboard(name: "Login", bundle: nil) - if let controller = storyboard.instantiateViewController(withIdentifier: controllerKey) as? NUXAbstractViewController { - navigationController?.setViewControllers([controller], animated: true) + delegate.retryAsSignup() } } } From 677a8d031f059c4525c2557edc8e1d2b419f614e Mon Sep 17 00:00:00 2001 From: Nate Heagy Date: Fri, 6 Oct 2017 08:12:25 -0600 Subject: [PATCH 14/14] Add help button and WP logo to social error screen --- .../NUX/LoginSocialErrorViewController.swift | 4 +- .../ViewRelated/NUX/LoginViewController.swift | 88 ++++++++++++------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift index 77ad14bb3a9a..c7982d3604da 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginSocialErrorViewController.swift @@ -9,7 +9,7 @@ protocol LoginSocialErrorViewControllerDelegate { } /// ViewController for presenting recovery options when social login fails -class LoginSocialErrorViewController: UITableViewController { +class LoginSocialErrorViewController: UITableViewController, LoginWithLogoAndHelpViewController { fileprivate var errorTitle: String fileprivate var errorDescription: String var delegate: LoginSocialErrorViewControllerDelegate? @@ -52,6 +52,8 @@ class LoginSocialErrorViewController: UITableViewController { super.viewDidLoad() view.backgroundColor = WPStyleGuide.greyLighten30() + addHelpButtonToNavController() + addWordPressLogoToNavController() } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { diff --git a/WordPress/Classes/ViewRelated/NUX/LoginViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginViewController.swift index 0c9f90771763..5680875fcbed 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginViewController.swift @@ -1,7 +1,58 @@ import Foundation import Gridicons -class LoginViewController: NUXAbstractViewController { +protocol LoginWithLogoAndHelpViewController { + func addWordPressLogoToNavController() + func addHelpButtonToNavController() -> (UIButton, WPNUXHelpBadgeLabel) +} + +extension LoginWithLogoAndHelpViewController where Self: UIViewController { + func addWordPressLogoToNavController() { + let image = Gridicon.iconOfType(.mySites) + let imageView = UIImageView(image: image.imageWithTintColor(UIColor.white)) + navigationItem.titleView = imageView + } + func addHelpButtonToNavController() -> (UIButton, WPNUXHelpBadgeLabel) { + let helpButtonMarginSpacerWidth = CGFloat(-8) + let helpBadgeSize = CGSize(width: 12, height: 10) + let helpButtonContainerFrame = CGRect(x: 0, y: 0, width: 44, height: 44) + + NotificationCenter.default.addObserver(self, selector: #selector(NUXAbstractViewController.handleHelpshiftUnreadCountUpdated(_:)), name: NSNotification.Name.HelpshiftUnreadCountUpdated, object: nil) + + let customView = UIView(frame: helpButtonContainerFrame) + + let helpButton = UIButton(type: .custom) + helpButton.setTitle(NSLocalizedString("Help", comment: "Help button"), for: .normal) + helpButton.setTitleColor(UIColor(white: 1.0, alpha: 0.4), for: .highlighted) + helpButton.addTarget(self, action: #selector(NUXAbstractViewController.handleHelpButtonTapped(_:)), for: .touchUpInside) + + customView.addSubview(helpButton) + helpButton.translatesAutoresizingMaskIntoConstraints = false + helpButton.leadingAnchor.constraint(equalTo: customView.leadingAnchor).isActive = true + helpButton.trailingAnchor.constraint(equalTo: customView.trailingAnchor).isActive = true + helpButton.topAnchor.constraint(equalTo: customView.topAnchor).isActive = true + helpButton.bottomAnchor.constraint(equalTo: customView.bottomAnchor).isActive = true + + let helpBadge = WPNUXHelpBadgeLabel() + helpBadge.translatesAutoresizingMaskIntoConstraints = false + helpBadge.isHidden = true + customView.addSubview(helpBadge) + helpBadge.centerXAnchor.constraint(equalTo: helpButton.trailingAnchor).isActive = true + helpBadge.centerYAnchor.constraint(equalTo: helpButton.topAnchor).isActive = true + helpBadge.widthAnchor.constraint(equalToConstant: helpBadgeSize.width).isActive = true + helpBadge.heightAnchor.constraint(equalToConstant: helpBadgeSize.height).isActive = true + + let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) + spacer.width = helpButtonMarginSpacerWidth + + let barButton = UIBarButtonItem(customView: customView) + navigationItem.rightBarButtonItems = [spacer, barButton] + + return (helpButton, helpBadge) + } +} + +class LoginViewController: NUXAbstractViewController, LoginWithLogoAndHelpViewController { @IBOutlet var instructionLabel: UILabel? @IBOutlet var errorLabel: UILabel? @IBOutlet var submitButton: NUXSubmitButton? @@ -33,9 +84,7 @@ class LoginViewController: NUXAbstractViewController { /// Places the WordPress logo in the navbar /// func setupNavBarIcon() { - let image = Gridicon.iconOfType(.mySites) - let imageView = UIImageView(image: image.imageWithTintColor(UIColor.white)) - navigationItem.titleView = imageView + addWordPressLogoToNavController() } /// Configures instruction label font @@ -47,34 +96,9 @@ class LoginViewController: NUXAbstractViewController { /// Sets up the help button and the helpshift conversation badge. /// override func setupHelpButtonAndBadge() { - NotificationCenter.default.addObserver(self, selector: #selector(NUXAbstractViewController.handleHelpshiftUnreadCountUpdated(_:)), name: NSNotification.Name.HelpshiftUnreadCountUpdated, object: nil) - - let customView = UIView(frame: helpButtonContainerFrame) - - helpButton = UIButton(type: .custom) - helpButton.setTitle(NSLocalizedString("Help", comment: "Help button"), for: .normal) - helpButton.setTitleColor(UIColor(white: 1.0, alpha: 0.4), for: .highlighted) - helpButton.addTarget(self, action: #selector(NUXAbstractViewController.handleHelpButtonTapped(_:)), for: .touchUpInside) - - customView.addSubview(helpButton) - helpButton.translatesAutoresizingMaskIntoConstraints = false - helpButton.trailingAnchor.constraint(equalTo: customView.trailingAnchor).isActive = true - helpButton.centerYAnchor.constraint(equalTo: customView.centerYAnchor).isActive = true - - helpBadge = WPNUXHelpBadgeLabel() - helpBadge.translatesAutoresizingMaskIntoConstraints = false - helpBadge.isHidden = true - customView.addSubview(helpBadge) - helpBadge.centerXAnchor.constraint(equalTo: helpButton.trailingAnchor).isActive = true - helpBadge.centerYAnchor.constraint(equalTo: helpButton.topAnchor).isActive = true - helpBadge.widthAnchor.constraint(equalToConstant: helpBadgeSize.width).isActive = true - helpBadge.heightAnchor.constraint(equalToConstant: helpBadgeSize.height).isActive = true - - let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) - spacer.width = helpButtonMarginSpacerWidth - - let barButton = UIBarButtonItem(customView: customView) - navigationItem.rightBarButtonItems = [spacer, barButton] + let (helpButtonResult, helpBadgeResult) = addHelpButtonToNavController() + helpButton = helpButtonResult + helpBadge = helpBadgeResult } /// Sets the text of the error label.