mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge branch 'charlesmchen/onboardingCleanup'
This commit is contained in:
commit
0e62514541
|
@ -2,7 +2,7 @@
|
|||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Screen Shot 2019-02-12 at 2.22.35 PM.png",
|
||||
"filename" : "onboarding_splash.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 35 KiB |
BIN
Signal/Images.xcassets/onboarding_splash_hero.imageset/onboarding_splash.png
vendored
Normal file
BIN
Signal/Images.xcassets/onboarding_splash_hero.imageset/onboarding_splash.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
|
@ -31,37 +31,31 @@ public class OnboardingBaseViewController: OWSViewController {
|
|||
let titleLabel = UILabel()
|
||||
titleLabel.text = text
|
||||
titleLabel.textColor = Theme.primaryColor
|
||||
titleLabel.font = UIFont.ows_dynamicTypeTitle2.ows_mediumWeight()
|
||||
titleLabel.font = UIFont.ows_dynamicTypeTitle1Clamped.ows_mediumWeight()
|
||||
titleLabel.numberOfLines = 0
|
||||
titleLabel.lineBreakMode = .byWordWrapping
|
||||
titleLabel.textAlignment = .center
|
||||
return titleLabel
|
||||
}
|
||||
|
||||
func explanationLabel(explanationText: String, linkText: String, selector: Selector) -> UILabel {
|
||||
let explanationText = NSAttributedString(string: explanationText)
|
||||
.rtlSafeAppend(NSAttributedString(string: " "))
|
||||
.rtlSafeAppend(linkText,
|
||||
attributes: [
|
||||
NSAttributedStringKey.foregroundColor: UIColor.ows_materialBlue
|
||||
])
|
||||
func explanationLabel(explanationText: String) -> UILabel {
|
||||
let explanationLabel = UILabel()
|
||||
explanationLabel.textColor = Theme.secondaryColor
|
||||
explanationLabel.font = UIFont.ows_dynamicTypeCaption1
|
||||
explanationLabel.attributedText = explanationText
|
||||
explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
explanationLabel.text = explanationText
|
||||
explanationLabel.numberOfLines = 0
|
||||
explanationLabel.textAlignment = .center
|
||||
explanationLabel.lineBreakMode = .byWordWrapping
|
||||
explanationLabel.isUserInteractionEnabled = true
|
||||
explanationLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: selector))
|
||||
return explanationLabel
|
||||
}
|
||||
|
||||
func button(title: String, selector: Selector) -> OWSFlatButton {
|
||||
// TODO: Make sure this all fits if dynamic font sizes are maxed out.
|
||||
let buttonHeight: CGFloat = 48
|
||||
let font = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
|
||||
// Button height should be 48pt if the font is 17pt.
|
||||
let buttonHeight = font.pointSize * 48 / 17
|
||||
let button = OWSFlatButton.button(title: title,
|
||||
font: OWSFlatButton.fontForHeight(buttonHeight),
|
||||
font: font,
|
||||
titleColor: .white,
|
||||
backgroundColor: .ows_materialBlue,
|
||||
target: self,
|
||||
|
@ -70,11 +64,28 @@ public class OnboardingBaseViewController: OWSViewController {
|
|||
return button
|
||||
}
|
||||
|
||||
func linkButton(title: String, selector: Selector) -> OWSFlatButton {
|
||||
// TODO: Make sure this all fits if dynamic font sizes are maxed out.
|
||||
let font = UIFont.ows_dynamicTypeBodyClamped.ows_mediumWeight()
|
||||
// Button height should be 48pt if the font is 17pt.
|
||||
let buttonHeight = font.pointSize * 48 / 17
|
||||
let button = OWSFlatButton.button(title: title,
|
||||
font: font,
|
||||
titleColor: .ows_materialBlue,
|
||||
backgroundColor: .white,
|
||||
target: self,
|
||||
selector: selector)
|
||||
button.autoSetDimension(.height, toSize: buttonHeight)
|
||||
return button
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = true
|
||||
|
||||
// TODO: Is there a better way to do this?
|
||||
if let navigationController = self.navigationController as? OWSNavigationController {
|
||||
SignalApp.shared().signUpFlowNavigationController = navigationController
|
||||
|
@ -83,6 +94,12 @@ public class OnboardingBaseViewController: OWSViewController {
|
|||
}
|
||||
}
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = true
|
||||
}
|
||||
|
||||
// MARK: - Orientation
|
||||
|
||||
public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
|
||||
|
|
|
@ -73,8 +73,6 @@ public class OnboardingCaptchaViewController: OnboardingBaseViewController {
|
|||
public override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = false
|
||||
|
||||
loadContent()
|
||||
}
|
||||
|
||||
|
@ -93,12 +91,6 @@ public class OnboardingCaptchaViewController: OnboardingBaseViewController {
|
|||
webView.scrollView.contentOffset = .zero
|
||||
}
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = false
|
||||
}
|
||||
|
||||
// MARK: - Notifications
|
||||
|
||||
@objc func didBecomeActive() {
|
||||
|
|
|
@ -12,10 +12,7 @@ public class OnboardingPermissionsViewController: OnboardingBaseViewController {
|
|||
super.loadView()
|
||||
|
||||
view.backgroundColor = Theme.backgroundColor
|
||||
view.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
|
||||
|
||||
// TODO:
|
||||
// navigationItem.title = NSLocalizedString("SETTINGS_BACKUP", comment: "Label for the backup view in app settings.")
|
||||
view.layoutMargins = .zero
|
||||
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(title: NSLocalizedString("NAVIGATION_ITEM_SKIP_BUTTON", comment: "A button to skip a view."),
|
||||
style: .plain,
|
||||
|
@ -23,58 +20,42 @@ public class OnboardingPermissionsViewController: OnboardingBaseViewController {
|
|||
action: #selector(skipWasPressed))
|
||||
|
||||
let titleLabel = self.titleLabel(text: NSLocalizedString("ONBOARDING_PERMISSIONS_TITLE", comment: "Title of the 'onboarding permissions' view."))
|
||||
view.addSubview(titleLabel)
|
||||
titleLabel.autoPinEdges(toSuperviewMarginsExcludingEdge: .bottom)
|
||||
|
||||
// TODO: Finalize copy.
|
||||
let explanationLabel = self.explanationLabel(explanationText: NSLocalizedString("ONBOARDING_PERMISSIONS_EXPLANATION",
|
||||
comment: "Explanation in the 'onboarding permissions' view."),
|
||||
linkText: NSLocalizedString("ONBOARDING_PERMISSIONS_LEARN_MORE_LINK",
|
||||
comment: "Link to the 'learn more' in the 'onboarding permissions' view."),
|
||||
selector: #selector(explanationLabelTapped))
|
||||
comment: "Explanation in the 'onboarding permissions' view."))
|
||||
|
||||
// TODO: Make sure this all fits if dynamic font sizes are maxed out.
|
||||
let giveAccessButton = self.button(title: NSLocalizedString("ONBOARDING_PERMISSIONS_GIVE_ACCESS_BUTTON",
|
||||
let giveAccessButton = self.button(title: NSLocalizedString("ONBOARDING_PERMISSIONS_ENABLE_PERMISSIONS_BUTTON",
|
||||
comment: "Label for the 'give access' button in the 'onboarding permissions' view."),
|
||||
selector: #selector(giveAccessPressed))
|
||||
|
||||
let notNowButton = self.button(title: NSLocalizedString("ONBOARDING_PERMISSIONS_NOT_NOW_BUTTON",
|
||||
comment: "Label for the 'not now' button in the 'onboarding permissions' view."),
|
||||
let notNowButton = self.linkButton(title: NSLocalizedString("ONBOARDING_PERMISSIONS_NOT_NOW_BUTTON",
|
||||
comment: "Label for the 'not now' button in the 'onboarding permissions' view."),
|
||||
selector: #selector(notNowPressed))
|
||||
|
||||
let buttonStack = UIStackView(arrangedSubviews: [
|
||||
giveAccessButton,
|
||||
notNowButton
|
||||
])
|
||||
buttonStack.axis = .vertical
|
||||
buttonStack.alignment = .fill
|
||||
buttonStack.spacing = 12
|
||||
|
||||
let topSpacer = UIView.vStretchingSpacer()
|
||||
let bottomSpacer = UIView.vStretchingSpacer()
|
||||
let stackView = UIStackView(arrangedSubviews: [
|
||||
titleLabel,
|
||||
UIView.spacer(withHeight: 20),
|
||||
explanationLabel,
|
||||
buttonStack
|
||||
topSpacer,
|
||||
giveAccessButton,
|
||||
UIView.spacer(withHeight: 12),
|
||||
notNowButton,
|
||||
bottomSpacer
|
||||
])
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .fill
|
||||
stackView.spacing = 40
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
view.addSubview(stackView)
|
||||
stackView.autoPinWidthToSuperviewMargins()
|
||||
stackView.autoPinEdge(.top, to: .bottom, of: titleLabel, withOffset: 20, relation: .greaterThanOrEqual)
|
||||
NSLayoutConstraint.autoSetPriority(.defaultHigh) {
|
||||
stackView.autoVCenterInSuperview()
|
||||
}
|
||||
}
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
|
||||
stackView.autoPin(toBottomLayoutGuideOf: self, withInset: 0)
|
||||
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = false
|
||||
}
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = false
|
||||
// Ensure whitespace is balanced, so inputs are vertically centered.
|
||||
topSpacer.autoMatch(.height, to: .height, of: bottomSpacer)
|
||||
}
|
||||
|
||||
// MARK: Request Access
|
||||
|
@ -117,13 +98,6 @@ public class OnboardingPermissionsViewController: OnboardingBaseViewController {
|
|||
onboardingController.onboardingPermissionsWasSkipped(viewController: self)
|
||||
}
|
||||
|
||||
@objc func explanationLabelTapped(sender: UIGestureRecognizer) {
|
||||
guard sender.state == .recognized else {
|
||||
return
|
||||
}
|
||||
// TODO:
|
||||
}
|
||||
|
||||
@objc func giveAccessPressed() {
|
||||
Logger.info("")
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
private let callingCodeLabel = UILabel()
|
||||
private let phoneNumberTextField = UITextField()
|
||||
private var nextButton: OWSFlatButton?
|
||||
private var phoneStrokeNormal: UIView?
|
||||
private var phoneStrokeError: UIView?
|
||||
private let validationWarningLabel = UILabel()
|
||||
private var isPhoneNumberInvalid = false
|
||||
|
||||
override public func loadView() {
|
||||
super.loadView()
|
||||
|
@ -29,9 +33,6 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
view.backgroundColor = Theme.backgroundColor
|
||||
view.layoutMargins = .zero
|
||||
|
||||
// TODO:
|
||||
// navigationItem.title = NSLocalizedString("SETTINGS_BACKUP", comment: "Label for the backup view in app settings.")
|
||||
|
||||
let titleLabel = self.titleLabel(text: NSLocalizedString("ONBOARDING_PHONE_NUMBER_TITLE", comment: "Title of the 'onboarding phone number' view."))
|
||||
|
||||
// Country
|
||||
|
@ -39,7 +40,7 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
let rowHeight: CGFloat = 40
|
||||
|
||||
countryNameLabel.textColor = Theme.primaryColor
|
||||
countryNameLabel.font = UIFont.ows_dynamicTypeBody
|
||||
countryNameLabel.font = UIFont.ows_dynamicTypeBodyClamped
|
||||
countryNameLabel.setContentHuggingHorizontalLow()
|
||||
countryNameLabel.setCompressionResistanceHorizontalLow()
|
||||
|
||||
|
@ -61,26 +62,27 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
countryRow.isUserInteractionEnabled = true
|
||||
countryRow.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(countryRowTapped)))
|
||||
countryRow.autoSetDimension(.height, toSize: rowHeight)
|
||||
addBottomStroke(countryRow)
|
||||
_ = addBottomStroke(countryRow)
|
||||
|
||||
callingCodeLabel.textColor = Theme.primaryColor
|
||||
callingCodeLabel.font = UIFont.ows_dynamicTypeBody
|
||||
callingCodeLabel.font = UIFont.ows_dynamicTypeBodyClamped
|
||||
callingCodeLabel.setContentHuggingHorizontalHigh()
|
||||
callingCodeLabel.setCompressionResistanceHorizontalHigh()
|
||||
callingCodeLabel.isUserInteractionEnabled = true
|
||||
callingCodeLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(countryCodeTapped)))
|
||||
addBottomStroke(callingCodeLabel)
|
||||
_ = addBottomStroke(callingCodeLabel)
|
||||
callingCodeLabel.autoSetDimension(.width, toSize: rowHeight, relation: .greaterThanOrEqual)
|
||||
|
||||
phoneNumberTextField.textAlignment = .left
|
||||
phoneNumberTextField.delegate = self
|
||||
phoneNumberTextField.keyboardType = .numberPad
|
||||
phoneNumberTextField.textColor = Theme.primaryColor
|
||||
phoneNumberTextField.font = UIFont.ows_dynamicTypeBody
|
||||
phoneNumberTextField.font = UIFont.ows_dynamicTypeBodyClamped
|
||||
phoneNumberTextField.setContentHuggingHorizontalLow()
|
||||
phoneNumberTextField.setCompressionResistanceHorizontalLow()
|
||||
|
||||
addBottomStroke(phoneNumberTextField)
|
||||
phoneStrokeNormal = addBottomStroke(phoneNumberTextField)
|
||||
phoneStrokeError = addBottomStroke(phoneNumberTextField, color: .ows_destructiveRed, strokeWidth: 2)
|
||||
|
||||
let phoneNumberRow = UIStackView(arrangedSubviews: [
|
||||
callingCodeLabel,
|
||||
|
@ -92,6 +94,16 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
phoneNumberRow.autoSetDimension(.height, toSize: rowHeight)
|
||||
callingCodeLabel.autoMatch(.height, to: .height, of: phoneNumberTextField)
|
||||
|
||||
validationWarningLabel.text = NSLocalizedString("ONBOARDING_PHONE_NUMBER_VALIDATION_WARNING",
|
||||
comment: "Label indicating that the phone number is invalid in the 'onboarding phone number' view.")
|
||||
validationWarningLabel.textColor = .ows_destructiveRed
|
||||
validationWarningLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
|
||||
let validationWarningRow = UIView()
|
||||
validationWarningRow.addSubview(validationWarningLabel)
|
||||
validationWarningLabel.autoPinHeightToSuperview()
|
||||
validationWarningLabel.autoPinEdge(toSuperviewEdge: .trailing)
|
||||
|
||||
// TODO: Finalize copy.
|
||||
|
||||
let nextButton = self.button(title: NSLocalizedString("BUTTON_NEXT",
|
||||
|
@ -107,6 +119,8 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
countryRow,
|
||||
UIView.spacer(withHeight: 8),
|
||||
phoneNumberRow,
|
||||
UIView.spacer(withHeight: 8),
|
||||
validationWarningRow,
|
||||
bottomSpacer,
|
||||
nextButton
|
||||
])
|
||||
|
@ -115,34 +129,43 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
stackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
view.addSubview(stackView)
|
||||
stackView.autoPinWidthToSuperviewMargins()
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
|
||||
autoPinView(toBottomOfViewControllerOrKeyboard: stackView, avoidNotch: true)
|
||||
|
||||
// Ensure whitespace is balanced, so inputs are vertically centered.
|
||||
topSpacer.autoMatch(.height, to: .height, of: bottomSpacer)
|
||||
|
||||
validationWarningLabel.autoPinEdge(.leading, to: .leading, of: phoneNumberTextField)
|
||||
}
|
||||
|
||||
private func addBottomStroke(_ view: UIView) {
|
||||
private func addBottomStroke(_ view: UIView) -> UIView {
|
||||
return addBottomStroke(view, color: Theme.middleGrayColor, strokeWidth: CGHairlineWidth())
|
||||
}
|
||||
|
||||
private func addBottomStroke(_ view: UIView, color: UIColor, strokeWidth: CGFloat) -> UIView {
|
||||
let strokeView = UIView()
|
||||
strokeView.backgroundColor = Theme.middleGrayColor
|
||||
strokeView.backgroundColor = color
|
||||
view.addSubview(strokeView)
|
||||
strokeView.autoSetDimension(.height, toSize: CGHairlineWidth())
|
||||
strokeView.autoSetDimension(.height, toSize: strokeWidth)
|
||||
strokeView.autoPinWidthToSuperview()
|
||||
strokeView.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
return strokeView
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = false
|
||||
isPhoneNumberInvalid = false
|
||||
|
||||
updateViewState()
|
||||
}
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = false
|
||||
|
||||
phoneNumberTextField.becomeFirstResponder()
|
||||
|
||||
if tsAccountManager.isReregistering() {
|
||||
|
@ -202,11 +225,12 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
let countryState = OnboardingCountryState(countryName: countryName, callingCode: callingCode, countryCode: countryCode)
|
||||
onboardingController.update(countryState: countryState)
|
||||
|
||||
updateState()
|
||||
|
||||
phoneNumberTextField.text = phoneNumberWithoutCallingCode
|
||||
|
||||
// Don't let user edit their phone number while re-registering.
|
||||
phoneNumberTextField.isEnabled = false
|
||||
|
||||
updateViewState()
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
@ -236,18 +260,30 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
lastRegisteredPhoneNumber.count > 0,
|
||||
lastRegisteredPhoneNumber.hasPrefix(callingCode) {
|
||||
phoneNumberTextField.text = lastRegisteredPhoneNumber.substring(from: callingCode.count)
|
||||
} else if let phoneNumber = onboardingController.phoneNumber {
|
||||
phoneNumberTextField.text = phoneNumber.userInput
|
||||
}
|
||||
|
||||
updateState()
|
||||
updateViewState()
|
||||
}
|
||||
|
||||
private func updateState() {
|
||||
private func updateViewState() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
countryNameLabel.text = countryName
|
||||
callingCodeLabel.text = callingCode
|
||||
|
||||
self.phoneNumberTextField.placeholder = ViewControllerUtils.examplePhoneNumber(forCountryCode: countryCode, callingCode: callingCode)
|
||||
|
||||
updateValidationWarnings()
|
||||
}
|
||||
|
||||
private func updateValidationWarnings() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
phoneStrokeNormal?.isHidden = isPhoneNumberInvalid
|
||||
phoneStrokeError?.isHidden = !isPhoneNumberInvalid
|
||||
validationWarningLabel.isHidden = !isPhoneNumberInvalid
|
||||
}
|
||||
|
||||
// MARK: - Events
|
||||
|
@ -291,6 +327,10 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
private func parseAndTryToRegister() {
|
||||
guard let phoneNumberText = phoneNumberTextField.text?.ows_stripped(),
|
||||
phoneNumberText.count > 0 else {
|
||||
|
||||
isPhoneNumberInvalid = false
|
||||
updateValidationWarnings()
|
||||
|
||||
OWSAlerts.showAlert(title:
|
||||
NSLocalizedString("REGISTRATION_VIEW_NO_PHONE_NUMBER_ALERT_TITLE",
|
||||
comment: "Title of alert indicating that users needs to enter a phone number to register."),
|
||||
|
@ -304,6 +344,10 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
guard let localNumber = PhoneNumber.tryParsePhoneNumber(fromUserSpecifiedText: phoneNumber),
|
||||
localNumber.toE164().count > 0,
|
||||
PhoneNumberValidator().isValidForRegistration(phoneNumber: localNumber) else {
|
||||
|
||||
isPhoneNumberInvalid = false
|
||||
updateValidationWarnings()
|
||||
|
||||
OWSAlerts.showAlert(title:
|
||||
NSLocalizedString("REGISTRATION_VIEW_INVALID_PHONE_NUMBER_ALERT_TITLE",
|
||||
comment: "Title of alert indicating that users needs to enter a valid phone number to register."),
|
||||
|
@ -339,6 +383,9 @@ extension OnboardingPhoneNumberViewController: UITextFieldDelegate {
|
|||
// TODO: Fix auto-format of phone numbers.
|
||||
ViewControllerUtils.phoneNumber(textField, shouldChangeCharactersIn: range, replacementString: string, countryCode: countryCode)
|
||||
|
||||
isPhoneNumberInvalid = false
|
||||
updateValidationWarnings()
|
||||
|
||||
// Inform our caller that we took care of performing the change.
|
||||
return false
|
||||
}
|
||||
|
@ -370,7 +417,7 @@ extension OnboardingPhoneNumberViewController: CountryCodeViewControllerDelegate
|
|||
|
||||
onboardingController.update(countryState: countryState)
|
||||
|
||||
updateState()
|
||||
updateViewState()
|
||||
|
||||
// Trigger the formatting logic with a no-op edit.
|
||||
_ = textField(phoneNumberTextField, shouldChangeCharactersIn: NSRange(location: 0, length: 0), replacementString: "")
|
||||
|
|
|
@ -14,9 +14,6 @@ public class OnboardingSplashViewController: OnboardingBaseViewController {
|
|||
view.backgroundColor = Theme.backgroundColor
|
||||
view.layoutMargins = .zero
|
||||
|
||||
// TODO:
|
||||
// navigationItem.title = NSLocalizedString("SETTINGS_BACKUP", comment: "Label for the backup view in app settings.")
|
||||
|
||||
let heroImage = UIImage(named: "onboarding_splash_hero")
|
||||
let heroImageView = UIImageView(image: heroImage)
|
||||
heroImageView.contentMode = .scaleAspectFit
|
||||
|
@ -29,12 +26,16 @@ public class OnboardingSplashViewController: OnboardingBaseViewController {
|
|||
view.addSubview(titleLabel)
|
||||
titleLabel.autoPinEdges(toSuperviewMarginsExcludingEdge: .bottom)
|
||||
|
||||
// TODO: Finalize copy.
|
||||
let explanationLabel = self.explanationLabel(explanationText: NSLocalizedString("ONBOARDING_SPLASH_EXPLANATION",
|
||||
comment: "Explanation in the 'onboarding splash' view."),
|
||||
linkText: NSLocalizedString("ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY",
|
||||
comment: "Link to the 'terms and privacy policy' in the 'onboarding splash' view."),
|
||||
selector: #selector(explanationLabelTapped))
|
||||
let explanationLabel = UILabel()
|
||||
explanationLabel.text = NSLocalizedString("ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY",
|
||||
comment: "Link to the 'terms and privacy policy' in the 'onboarding splash' view.")
|
||||
explanationLabel.textColor = .ows_materialBlue
|
||||
explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
||||
explanationLabel.numberOfLines = 0
|
||||
explanationLabel.textAlignment = .center
|
||||
explanationLabel.lineBreakMode = .byWordWrapping
|
||||
explanationLabel.isUserInteractionEnabled = true
|
||||
explanationLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(explanationLabelTapped)))
|
||||
|
||||
// TODO: Make sure this all fits if dynamic font sizes are maxed out.
|
||||
let continueButton = self.button(title: NSLocalizedString("BUTTON_CONTINUE",
|
||||
|
@ -46,9 +47,9 @@ public class OnboardingSplashViewController: OnboardingBaseViewController {
|
|||
heroImageView,
|
||||
UIView.spacer(withHeight: 22),
|
||||
titleLabel,
|
||||
UIView.spacer(withHeight: 56),
|
||||
UIView.spacer(withHeight: 92),
|
||||
explanationLabel,
|
||||
UIView.spacer(withHeight: 40),
|
||||
UIView.spacer(withHeight: 24),
|
||||
continueButton
|
||||
])
|
||||
stackView.axis = .vertical
|
||||
|
@ -56,23 +57,11 @@ public class OnboardingSplashViewController: OnboardingBaseViewController {
|
|||
stackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
view.addSubview(stackView)
|
||||
stackView.autoPinWidthToSuperviewMargins()
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
|
||||
stackView.autoPin(toBottomLayoutGuideOf: self, withInset: 0)
|
||||
}
|
||||
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = true
|
||||
}
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
self.navigationController?.isNavigationBarHidden = true
|
||||
}
|
||||
|
||||
// MARK: - Events
|
||||
|
||||
@objc func explanationLabelTapped(sender: UIGestureRecognizer) {
|
||||
|
|
|
@ -1511,29 +1511,26 @@
|
|||
/* Title of the 'onboarding Captcha' view. */
|
||||
"ONBOARDING_CAPTCHA_TITLE" = "We need to verify that you're human";
|
||||
|
||||
/* Explanation in the 'onboarding permissions' view. */
|
||||
"ONBOARDING_PERMISSIONS_EXPLANATION" = "ONBOARDING_PERMISSIONS_EXPLANATION";
|
||||
|
||||
/* Label for the 'give access' button in the 'onboarding permissions' view. */
|
||||
"ONBOARDING_PERMISSIONS_GIVE_ACCESS_BUTTON" = "Give Access";
|
||||
"ONBOARDING_PERMISSIONS_ENABLE_PERMISSIONS_BUTTON" = "Enable Permissions";
|
||||
|
||||
/* Link to the 'learn more' in the 'onboarding permissions' view. */
|
||||
"ONBOARDING_PERMISSIONS_LEARN_MORE_LINK" = "Learn More";
|
||||
/* Explanation in the 'onboarding permissions' view. */
|
||||
"ONBOARDING_PERMISSIONS_EXPLANATION" = "Your contact information is always transmitted securely.";
|
||||
|
||||
/* Label for the 'not now' button in the 'onboarding permissions' view. */
|
||||
"ONBOARDING_PERMISSIONS_NOT_NOW_BUTTON" = "Not Now";
|
||||
|
||||
/* Title of the 'onboarding permissions' view. */
|
||||
"ONBOARDING_PERMISSIONS_TITLE" = "We need access to your contacts and notifications";
|
||||
"ONBOARDING_PERMISSIONS_TITLE" = "Signal can let you know when you get a message (and who it is from)";
|
||||
|
||||
/* Title of the 'onboarding phone number' view. */
|
||||
"ONBOARDING_PHONE_NUMBER_TITLE" = "Enter your phone number to get started";
|
||||
|
||||
/* Explanation in the 'onboarding splash' view. */
|
||||
"ONBOARDING_SPLASH_EXPLANATION" = "By continuing, you agree to Signal's terms.";
|
||||
/* Label indicating that the phone number is invalid in the 'onboarding phone number' view. */
|
||||
"ONBOARDING_PHONE_NUMBER_VALIDATION_WARNING" = "Invalid number";
|
||||
|
||||
/* Link to the 'terms and privacy policy' in the 'onboarding splash' view. */
|
||||
"ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY" = "Terms and Privacy Policy";
|
||||
"ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY" = "Terms & Privacy Policy";
|
||||
|
||||
/* Title of the 'onboarding splash' view. */
|
||||
"ONBOARDING_SPLASH_TITLE" = "Signal is the private messenger for everybody";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
@ -36,6 +36,18 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeCaption1Font;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeCaption2Font;
|
||||
|
||||
#pragma mark - Dynamic Type Clamped
|
||||
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeTitle1ClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeTitle2ClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeTitle3ClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeHeadlineClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeBodyClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeSubheadlineClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeFootnoteClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeCaption1ClampedFont;
|
||||
@property (class, readonly, nonatomic) UIFont *ows_dynamicTypeCaption2ClampedFont;
|
||||
|
||||
#pragma mark - Styles
|
||||
|
||||
- (UIFont *)ows_italic;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIFont+OWS.h"
|
||||
|
@ -97,6 +97,86 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2];
|
||||
}
|
||||
|
||||
#pragma mark - Dynamic Type Clamped
|
||||
|
||||
+ (UIFont *)preferredFontForTextStyleClamped:(UIFontTextStyle)fontTextStyle
|
||||
{
|
||||
// We clamp the dynamic type sizes at the max size available
|
||||
// without "larger accessibility sizes" enabled.
|
||||
static NSDictionary<UIFontTextStyle, NSNumber *> *maxPointSizeMap = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
maxPointSizeMap = @{
|
||||
UIFontTextStyleTitle1 : @(34.0),
|
||||
UIFontTextStyleTitle2 : @(28.0),
|
||||
UIFontTextStyleTitle3 : @(26.0),
|
||||
UIFontTextStyleHeadline : @(23.0),
|
||||
UIFontTextStyleBody : @(23.0),
|
||||
UIFontTextStyleSubheadline : @(21.0),
|
||||
UIFontTextStyleFootnote : @(19.0),
|
||||
UIFontTextStyleCaption1 : @(18.0),
|
||||
UIFontTextStyleCaption2 : @(17.0),
|
||||
};
|
||||
});
|
||||
|
||||
UIFont *font = [UIFont preferredFontForTextStyle:fontTextStyle];
|
||||
NSNumber *_Nullable maxPointSize = maxPointSizeMap[fontTextStyle];
|
||||
if (maxPointSize) {
|
||||
if (maxPointSize.floatValue < font.pointSize) {
|
||||
return [font fontWithSize:maxPointSize.floatValue];
|
||||
}
|
||||
} else {
|
||||
OWSFailDebug(@"Missing max point size for style: %@", fontTextStyle);
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeTitle1ClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleTitle1];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeTitle2ClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleTitle2];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeTitle3ClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleTitle3];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeHeadlineClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleHeadline];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeBodyClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleBody];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeSubheadlineClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleSubheadline];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeFootnoteClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleFootnote];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeCaption1ClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleCaption1];
|
||||
}
|
||||
|
||||
+ (UIFont *)ows_dynamicTypeCaption2ClampedFont
|
||||
{
|
||||
return [UIFont preferredFontForTextStyleClamped:UIFontTextStyleCaption2];
|
||||
}
|
||||
|
||||
#pragma mark - Styles
|
||||
|
||||
- (UIFont *)ows_italic
|
||||
|
|
Loading…
Reference in a new issue