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

[WEB-700] FB Auth Deprecation | SetYourPassword UI #1714

Merged
merged 8 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC
public override func viewDidLoad() {
super.viewDidLoad()

self.navigationController?.configureTransparentNavigationBar()
msadoon marked this conversation as resolved.
Show resolved Hide resolved

self.configureViews()
self.setupConstraints()
self.configureTargets()
Expand Down
242 changes: 242 additions & 0 deletions Kickstarter-iOS/Views/Controllers/SetYourPasswordViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import Foundation
import Library
import Prelude
import ReactiveSwift
import UIKit

public final class SetYourPasswordViewController: UIViewController {
// MARK: - Properties

private lazy var contextLabel = { UILabel(frame: .zero) }()
private lazy var newPasswordLabel: UILabel = { UILabel(frame: .zero) }()
private lazy var newPasswordTextField: UITextField = { UITextField(frame: .zero) |> \.tag .~ 0 }()
private lazy var confirmPasswordLabel: UILabel = { UILabel(frame: .zero) }()
private lazy var confirmPasswordTextField: UITextField = { UITextField(frame: .zero) |> \.tag .~ 1 }()

private lazy var rootStackView = { UIStackView() }()
private lazy var scrollView = {
UIScrollView(frame: .zero)
|> \.alwaysBounceVertical .~ true

}()

private lazy var saveButton = { UIButton(type: .custom)
|> \.translatesAutoresizingMaskIntoConstraints .~ false
}()

fileprivate lazy var keyboardDimissingTapGestureRecognizer: UITapGestureRecognizer = {
UITapGestureRecognizer(
target: self,
action: #selector(SetYourPasswordViewController.dismissKeyboard)
)
|> \.cancelsTouchesInView .~ false
}()

private let viewModel: SetYourPasswordViewModelType = SetYourPasswordViewModel()

// MARK: - Configuration

public static func configuredWith(
userEmail: String
) -> SetYourPasswordViewController {
let vc = SetYourPasswordViewController.instantiate()
vc.viewModel.inputs.configureWith(userEmail)
return vc
}

// MARK: - Lifecycle

public override func viewDidLoad() {
super.viewDidLoad()

self.title = "Set your password"

self.view.addGestureRecognizer(self.keyboardDimissingTapGestureRecognizer)

self.configureViews()
self.setupConstraints()
self.configureTargets()

self.viewModel.inputs.viewDidLoad()
}

// MARK: - Styles

public override func bindStyles() {
super.bindStyles()

_ = self.contextLabel
|> contextLabelStyle

_ = self.rootStackView
|> baseStackViewStyle
|> loginRootStackViewStyle

_ = self.newPasswordLabel
|> textFieldLabelStyle

_ = self.confirmPasswordLabel
|> textFieldLabelStyle

_ = self.newPasswordTextField
|> textFieldStyle
|> \.accessibilityLabel .~ self.newPasswordLabel.text
|> \.attributedPlaceholder %~ { _ in settingsAttributedPlaceholder("") }

_ = self.confirmPasswordTextField
|> textFieldStyle
|> \.accessibilityLabel .~ self.confirmPasswordLabel.text
msadoon marked this conversation as resolved.
Show resolved Hide resolved
|> \.attributedPlaceholder %~ { _ in settingsAttributedPlaceholder("") }

_ = self.saveButton
|> savePasswordButtonStyle
|> \.isEnabled .~ false
}

// MARK: - Bind View Model

public override func bindViewModel() {
self.contextLabel.rac.text = self.viewModel.outputs.contextLabelText
self.newPasswordLabel.rac.text = self.viewModel.outputs.newPasswordLabel
self.confirmPasswordLabel.rac.text = self.viewModel.outputs.confirmPasswordLabel
self.saveButton.rac.enabled = self.viewModel.outputs.saveButtonIsEnabled
}

// MARK: - Functions

private func configureViews() {
_ = self.view
|> \.autoresizingMask .~ .flexibleHeight
|> \.backgroundColor .~ .ksr_white
|> \.clipsToBounds .~ true

_ = (self.scrollView, self.view)
|> ksr_addSubviewToParent()
|> ksr_constrainViewToEdgesInParent()

_ = (self.rootStackView, self.scrollView)
|> ksr_addSubviewToParent()
|> ksr_constrainViewToEdgesInParent()

_ = ([
self.contextLabel,
self.newPasswordLabel,
self.newPasswordTextField,
self.confirmPasswordLabel,
self.confirmPasswordTextField,
self.saveButton
], self.rootStackView)
|> ksr_addArrangedSubviewsToStackView()

self.rootStackView.setCustomSpacing(Styles.grid(7), after: self.contextLabel)
self.rootStackView.setCustomSpacing(Styles.grid(3), after: self.confirmPasswordTextField)
}

private func setupConstraints() {
NSLayoutConstraint.activate([
self.rootStackView.widthAnchor.constraint(equalTo: self.view.widthAnchor),
self.newPasswordTextField.heightAnchor.constraint(greaterThanOrEqualToConstant: 44),
self.confirmPasswordTextField.heightAnchor.constraint(greaterThanOrEqualToConstant: 44),
self.saveButton.heightAnchor.constraint(greaterThanOrEqualToConstant: 48)
msadoon marked this conversation as resolved.
Show resolved Hide resolved
])
}

private func configureTargets() {
self.newPasswordTextField
.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged)
self.confirmPasswordTextField
.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged)
self.saveButton.addTarget(self, action: #selector(self.saveButtonPressed), for: .touchUpInside)
}

// MARK: - Accessors

@objc private func dismissKeyboard() {
self.view.endEditing(true)
}

@objc private func textFieldDidChange(_ textField: UITextField) {
guard let password = textField.text else { return }

switch textField.tag {
case 0:
self.viewModel.inputs.newPasswordFieldDidChange(password)
case 1:
self.viewModel.inputs.confirmPasswordFieldDidChange(password)
default:
return
}
}

@objc private func saveButtonPressed() {
self.viewModel.inputs.saveButtonPressed()
}
}

// MARK: - Extensions

extension SetYourPasswordViewController: UITextFieldDelegate {
public func textFieldDidEndEditing(_ textField: UITextField) {
guard let password = textField.text else { return }

switch textField.tag {
case 0:
self.viewModel.inputs.newPasswordFieldDidReturn(newPassword: password)
case 1:
self.viewModel.inputs.confirmPasswordFieldDidReturn(confirmPassword: password)
default:
return
}
}
}

// MARK: - Styles

private let baseStackViewStyle: StackViewStyle = { stackView in
stackView
|> \.distribution .~ .fill
|> \.alignment .~ .fill
|> \.axis .~ .vertical
|> UIStackView.lens.spacing .~ Styles.grid(2)
}

private let contextLabelStyle: LabelStyle = { label in
label
|> \.textAlignment .~ NSTextAlignment.left
|> \.lineBreakMode .~ NSLineBreakMode.byWordWrapping
|> \.numberOfLines .~ 0
|> UILabel.lens.font %~ { _ in UIFont.ksr_body(size: 16) }
}

private let textFieldLabelStyle: LabelStyle = { label in
label
|> \.textAlignment .~ NSTextAlignment.left
|> \.lineBreakMode .~ NSLineBreakMode.byWordWrapping
|> \.numberOfLines .~ 0
|> \.backgroundColor .~ .ksr_white
|> \.textColor .~ UIColor.ksr_support_700
|> \.font %~ { _ in .ksr_callout(size: 13) }
}

private let textFieldStyle: TextFieldStyle = { textField in
textField
|> settingsNewPasswordFormFieldAutoFillStyle
|> roundedStyle(cornerRadius: Styles.grid(2))
|> UITextField.lens.textColor .~ .ksr_black
|> UITextField.lens.font %~ { _ in UIFont.ksr_body(size: 13) }
|> \.textAlignment .~ .left
|> \.borderStyle .~ UITextField.BorderStyle.roundedRect
|> \.layer.borderColor .~ UIColor.ksr_support_300.cgColor
|> \.layer.borderWidth .~ 1
|> \.returnKeyType .~ .done
}

private let savePasswordButtonStyle: ButtonStyle = { button in
button
|> greenButtonStyle
|> roundedStyle(cornerRadius: Styles.grid(2))
|> UIButton.lens.backgroundColor(for: .disabled) .~ UIColor.ksr_support_300.mixLighter(0.12)
|> UIButton.lens.title(for: .normal) %~ { _ in
Strings.Save()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@testable import Kickstarter_Framework
@testable import KsApi
@testable import Library
import Prelude
import XCTest

final class SetYourPasswordViewControllerTests: TestCase {
override func setUp() {
super.setUp()

AppEnvironment.pushEnvironment(mainBundle: Bundle.framework)
UIView.setAnimationsEnabled(false)
}

func testView() {
combos([Language.en], [Device.phone4_7inch, Device.pad]).forEach {
language, device in
withEnvironment(language: language) {
let controller = SetYourPasswordViewController.configuredWith(userEmail: "abc******@gmail.com")
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: controller)

self.scheduler.run()

FBSnapshotVerifyView(parent.view, identifier: "lang_\(language)_device_\(device)")
msadoon marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

override func tearDown() {
AppEnvironment.popEnvironment()
UIView.setAnimationsEnabled(true)
super.tearDown()
}
}
16 changes: 16 additions & 0 deletions Kickstarter.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,10 @@
59D1E6261D1865AC00896A4C /* DashboardVideoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D1E6241D1865AC00896A4C /* DashboardVideoCell.swift */; };
59D1E6581D1866F800896A4C /* DashboardVideoCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D1E6571D1866F800896A4C /* DashboardVideoCellViewModel.swift */; };
59E877381DC9419700BCD1F7 /* Newsletter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59E877371DC9419700BCD1F7 /* Newsletter.swift */; };
608E7A5328ABDBAE00289E92 /* SetYourPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608E7A5128ABD5E700289E92 /* SetYourPasswordViewController.swift */; };
608E7A5628ABE6CD00289E92 /* SetYourPasswordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608E7A5428ABE27400289E92 /* SetYourPasswordViewModel.swift */; };
60DA50EB28B689A4002E2DF1 /* SetYourPasswordViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60DA50E928B68990002E2DF1 /* SetYourPasswordViewModelTests.swift */; };
60DA50F128B6953A002E2DF1 /* SetYourPasswordViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60DA50EF28B69534002E2DF1 /* SetYourPasswordViewControllerTests.swift */; };
Comment on lines +457 to +460
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So yea for the view controller and view model, try to put them in alphabetical order if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the ViewController and ViewModel files are already separate folders and are in alphabetical order

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just meant that in the directory listing the vc and vm are at the bottom, maybe in your next pr just place them in alpha order like the other files.

770187C022FDCFCA0019129D /* PledgeViewControllerMessageDisplaying.swift in Sources */ = {isa = PBXBuildFile; fileRef = 770187BE22FDCF960019129D /* PledgeViewControllerMessageDisplaying.swift */; };
7703B42223217D4F00169EF3 /* EnvironmentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7703B42123217D4F00169EF3 /* EnvironmentType.swift */; };
7703B4242321844900169EF3 /* PKPaymentRequest+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7703B4232321844900169EF3 /* PKPaymentRequest+Helpers.swift */; };
Expand Down Expand Up @@ -2149,6 +2153,10 @@
59D1E6241D1865AC00896A4C /* DashboardVideoCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashboardVideoCell.swift; sourceTree = "<group>"; };
59D1E6571D1866F800896A4C /* DashboardVideoCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashboardVideoCellViewModel.swift; sourceTree = "<group>"; };
59E877371DC9419700BCD1F7 /* Newsletter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Newsletter.swift; sourceTree = "<group>"; };
608E7A5128ABD5E700289E92 /* SetYourPasswordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetYourPasswordViewController.swift; sourceTree = "<group>"; };
608E7A5428ABE27400289E92 /* SetYourPasswordViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetYourPasswordViewModel.swift; sourceTree = "<group>"; };
60DA50E928B68990002E2DF1 /* SetYourPasswordViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetYourPasswordViewModelTests.swift; sourceTree = "<group>"; };
60DA50EF28B69534002E2DF1 /* SetYourPasswordViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetYourPasswordViewControllerTests.swift; sourceTree = "<group>"; };
770187BE22FDCF960019129D /* PledgeViewControllerMessageDisplaying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PledgeViewControllerMessageDisplaying.swift; sourceTree = "<group>"; };
7703B42123217D4F00169EF3 /* EnvironmentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentType.swift; sourceTree = "<group>"; };
7703B4232321844900169EF3 /* PKPaymentRequest+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentRequest+Helpers.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4241,6 +4249,8 @@
8072F41C1D46B75200999EF1 /* UpdatePreviewViewController.swift */,
A731BF8B1D1EE44E00A734AC /* UpdateViewController.swift */,
59673CBC1D50ED380035AFD9 /* VideoViewController.swift */,
608E7A5128ABD5E700289E92 /* SetYourPasswordViewController.swift */,
60DA50EF28B69534002E2DF1 /* SetYourPasswordViewControllerTests.swift */,
);
path = Controllers;
sourceTree = "<group>";
Expand Down Expand Up @@ -4985,6 +4995,8 @@
A7ED1F9C1E831C5C00BFFA01 /* VideoViewModelTests.swift */,
D08CD1FE21913166009F89F0 /* WatchProjectViewModel.swift */,
D08CD200219216BA009F89F0 /* WatchProjectViewModelTests.swift */,
608E7A5428ABE27400289E92 /* SetYourPasswordViewModel.swift */,
60DA50E928B68990002E2DF1 /* SetYourPasswordViewModelTests.swift */,
);
path = ViewModels;
sourceTree = "<group>";
Expand Down Expand Up @@ -5994,6 +6006,7 @@
A75511631C8642C3005355CF /* LocalizedString.swift in Sources */,
77A64E5A24647C55003BF98E /* DiscoveryProjectCardViewModel.swift in Sources */,
06B0FDBA2702579A00147E3E /* ProjectPageViewModel.swift in Sources */,
608E7A5628ABE6CD00289E92 /* SetYourPasswordViewModel.swift in Sources */,
A7F441E11D005A9400FE6FC5 /* ResetPasswordViewModel.swift in Sources */,
774D98D423A94EDB00FC81C2 /* OptimizelyExperiment.swift in Sources */,
94114D83265451FF0063E8F6 /* CommentCellViewModel.swift in Sources */,
Expand Down Expand Up @@ -6422,6 +6435,7 @@
A7ED1FBF1E831C5C00BFFA01 /* SortPagerViewModelTests.swift in Sources */,
D6AE53161FD1E05E00BEC788 /* String+Base64Tests.swift in Sources */,
A7ED1FCB1E831C5C00BFFA01 /* ActivityFriendBackingViewModelTests.swift in Sources */,
60DA50EB28B689A4002E2DF1 /* SetYourPasswordViewModelTests.swift in Sources */,
A7ED1FE51E831C5C00BFFA01 /* MessageDialogViewModelTests.swift in Sources */,
776B1A1124193C2500B03098 /* CategoryPillCellViewModelTests.swift in Sources */,
A7ED1FB11E831C5C00BFFA01 /* ActivitySampleProjectCellViewModelTests.swift in Sources */,
Expand Down Expand Up @@ -6602,6 +6616,7 @@
D63BBD392180BE5D007E01F0 /* PaymentMethodsFooterView.swift in Sources */,
774F8D5B22B1B0B300A1ACD5 /* FeatureFlagToolsViewController.swift in Sources */,
7754A0AE215A8361003AA36D /* ChangePasswordViewController.swift in Sources */,
608E7A5328ABDBAE00289E92 /* SetYourPasswordViewController.swift in Sources */,
A72C3AB71D00FB1F0075227E /* DiscoveryExpandedSelectableRow.swift in Sources */,
063D2D0A2846767F00CEDE33 /* PledgeLocalPickupView.swift in Sources */,
37059843226F79A700BDA6E3 /* PledgeShippingLocationViewController.swift in Sources */,
Expand Down Expand Up @@ -6864,6 +6879,7 @@
A7ED204B1E8323E900BFFA01 /* DiscoveryNavigationHeaderViewControllerTests.swift in Sources */,
A78356081E85BE6D0021DA5A /* BackerDashboardProjectsDataSourceTests.swift in Sources */,
D60C8BF321481BCC00D96152 /* SettingsAccountViewControllerTests.swift in Sources */,
60DA50F128B6953A002E2DF1 /* SetYourPasswordViewControllerTests.swift in Sources */,
8AA3DB36250AE470009AC8EA /* SettingsAccountViewModelTests.swift in Sources */,
94114D7B26543AE30063E8F6 /* CommentsDataSourceTests.swift in Sources */,
D6B4F0032107B4760079159D /* SettingsNewslettersViewControllerTests.swift in Sources */,
Expand Down