Sketch out the 'onboarding profile' view.
This commit is contained in:
parent
d81e9d41fb
commit
afcacbb55c
|
@ -166,6 +166,7 @@
|
|||
3496957421A301A100DCFE74 /* OWSBackupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496956B21A301A100DCFE74 /* OWSBackupAPI.swift */; };
|
||||
349EA07C2162AEA800F7B17F /* OWS111UDAttributesMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */; };
|
||||
34A4C61E221613D00042EF2E /* OnboardingVerificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */; };
|
||||
34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A4C61F22175C5C0042EF2E /* OnboardingProfileViewController.swift */; };
|
||||
34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; };
|
||||
34A6C28021E503E700B5B12E /* OWSImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A6C27F21E503E600B5B12E /* OWSImagePickerController.swift */; };
|
||||
34A8B3512190A40E00218A25 /* MediaAlbumCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34A8B3502190A40E00218A25 /* MediaAlbumCellView.swift */; };
|
||||
|
@ -848,6 +849,7 @@
|
|||
3496956D21A301A100DCFE74 /* OWSBackupIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBackupIO.h; sourceTree = "<group>"; };
|
||||
349EA07B2162AEA700F7B17F /* OWS111UDAttributesMigration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWS111UDAttributesMigration.swift; sourceTree = "<group>"; };
|
||||
34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingVerificationViewController.swift; sourceTree = "<group>"; };
|
||||
34A4C61F22175C5C0042EF2E /* OnboardingProfileViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingProfileViewController.swift; sourceTree = "<group>"; };
|
||||
34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWS2FARegistrationViewController.m; sourceTree = "<group>"; };
|
||||
34A55F3620485464002CC6DE /* OWS2FARegistrationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWS2FARegistrationViewController.h; sourceTree = "<group>"; };
|
||||
34A6C27F21E503E600B5B12E /* OWSImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSImagePickerController.swift; sourceTree = "<group>"; };
|
||||
|
@ -1474,6 +1476,7 @@
|
|||
3448E15D221333F5004B052E /* OnboardingController.swift */,
|
||||
3448E15B22133274004B052E /* OnboardingPermissionsViewController.swift */,
|
||||
3448E16322135FFA004B052E /* OnboardingPhoneNumberViewController.swift */,
|
||||
34A4C61F22175C5C0042EF2E /* OnboardingProfileViewController.swift */,
|
||||
3448E15F22134C88004B052E /* OnboardingSplashViewController.swift */,
|
||||
34A4C61D221613D00042EF2E /* OnboardingVerificationViewController.swift */,
|
||||
346E9D5321B040B600562252 /* RegistrationController.swift */,
|
||||
|
@ -3491,6 +3494,7 @@
|
|||
343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */,
|
||||
34386A51207D0C01009F5D9C /* HomeViewController.m in Sources */,
|
||||
34D1F0A91F867BFC0066283D /* ConversationViewCell.m in Sources */,
|
||||
34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */,
|
||||
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
|
||||
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */,
|
||||
45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// Separate iOS Frameworks from other imports.
|
||||
#import "AppSettingsViewController.h"
|
||||
#import "AttachmentUploadView.h"
|
||||
#import "AvatarViewHelper.h"
|
||||
#import "ContactCellView.h"
|
||||
#import "ContactTableViewCell.h"
|
||||
#import "ConversationViewCell.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@protocol AvatarViewHelperDelegate <NSObject>
|
||||
|
||||
- (NSString *)avatarActionSheetTitle;
|
||||
- (nullable NSString *)avatarActionSheetTitle;
|
||||
|
||||
- (void)avatarDidChange:(UIImage *)image;
|
||||
|
||||
|
|
|
@ -482,6 +482,19 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
|
|||
[self.searchResultsController viewDidAppear:animated];
|
||||
|
||||
self.hasEverAppeared = YES;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
OnboardingController *onboardingController = [OnboardingController new];
|
||||
[onboardingController
|
||||
updateWithPhoneNumber:[[OnboardingPhoneNumber alloc] initWithE164:@"+13213214321" userInput:@"3213214321"]];
|
||||
|
||||
// UIViewController *view = [onboardingController initialViewController];
|
||||
UIViewController *view =
|
||||
[[OnboardingProfileViewController alloc] initWithOnboardingController:onboardingController];
|
||||
OWSNavigationController *navigationController =
|
||||
[[OWSNavigationController alloc] initWithRootViewController:view];
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated
|
||||
|
|
|
@ -612,7 +612,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - AvatarViewHelperDelegate
|
||||
|
||||
- (NSString *)avatarActionSheetTitle
|
||||
- (nullable NSString *)avatarActionSheetTitle
|
||||
{
|
||||
return NSLocalizedString(
|
||||
@"NEW_GROUP_ADD_PHOTO_ACTION", @"Action Sheet title prompting the user for a group avatar");
|
||||
|
|
|
@ -573,7 +573,7 @@ NSString *const kProfileView_LastPresentedDate = @"kProfileView_LastPresentedDat
|
|||
|
||||
#pragma mark - AvatarViewHelperDelegate
|
||||
|
||||
- (NSString *)avatarActionSheetTitle
|
||||
- (nullable NSString *)avatarActionSheetTitle
|
||||
{
|
||||
return NSLocalizedString(
|
||||
@"PROFILE_VIEW_AVATAR_ACTIONSHEET_TITLE", @"Action Sheet title prompting the user for a profile avatar");
|
||||
|
|
|
@ -450,3 +450,21 @@ public class OnboardingController: NSObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
public extension UIView {
|
||||
public func addBottomStroke() -> UIView {
|
||||
return addBottomStroke(color: Theme.middleGrayColor, strokeWidth: CGHairlineWidth())
|
||||
}
|
||||
|
||||
public func addBottomStroke(color: UIColor, strokeWidth: CGFloat) -> UIView {
|
||||
let strokeView = UIView()
|
||||
strokeView.backgroundColor = color
|
||||
addSubview(strokeView)
|
||||
strokeView.autoSetDimension(.height, toSize: strokeWidth)
|
||||
strokeView.autoPinWidthToSuperview()
|
||||
strokeView.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
return strokeView
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
countryRow.isUserInteractionEnabled = true
|
||||
countryRow.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(countryRowTapped)))
|
||||
countryRow.autoSetDimension(.height, toSize: rowHeight)
|
||||
_ = addBottomStroke(countryRow)
|
||||
_ = countryRow.addBottomStroke()
|
||||
|
||||
callingCodeLabel.textColor = Theme.primaryColor
|
||||
callingCodeLabel.font = UIFont.ows_dynamicTypeBodyClamped
|
||||
|
@ -70,7 +70,7 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
callingCodeLabel.setCompressionResistanceHorizontalHigh()
|
||||
callingCodeLabel.isUserInteractionEnabled = true
|
||||
callingCodeLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(countryCodeTapped)))
|
||||
_ = addBottomStroke(callingCodeLabel)
|
||||
_ = callingCodeLabel.addBottomStroke()
|
||||
callingCodeLabel.autoSetDimension(.width, toSize: rowHeight, relation: .greaterThanOrEqual)
|
||||
|
||||
phoneNumberTextField.textAlignment = .left
|
||||
|
@ -81,8 +81,8 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
phoneNumberTextField.setContentHuggingHorizontalLow()
|
||||
phoneNumberTextField.setCompressionResistanceHorizontalLow()
|
||||
|
||||
phoneStrokeNormal = addBottomStroke(phoneNumberTextField)
|
||||
phoneStrokeError = addBottomStroke(phoneNumberTextField, color: .ows_destructiveRed, strokeWidth: 2)
|
||||
phoneStrokeNormal = phoneNumberTextField.addBottomStroke()
|
||||
phoneStrokeError = phoneNumberTextField.addBottomStroke(color: .ows_destructiveRed, strokeWidth: 2)
|
||||
|
||||
let phoneNumberRow = UIStackView(arrangedSubviews: [
|
||||
callingCodeLabel,
|
||||
|
@ -140,20 +140,6 @@ public class OnboardingPhoneNumberViewController: OnboardingBaseViewController {
|
|||
validationWarningLabel.autoPinEdge(.leading, to: .leading, of: phoneNumberTextField)
|
||||
}
|
||||
|
||||
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 = color
|
||||
view.addSubview(strokeView)
|
||||
strokeView.autoSetDimension(.height, toSize: strokeWidth)
|
||||
strokeView.autoPinWidthToSuperview()
|
||||
strokeView.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
return strokeView
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objc
|
||||
public class OnboardingProfileViewController: OnboardingBaseViewController {
|
||||
|
||||
// private var titleLabel: UILabel?
|
||||
// private let phoneNumberTextField = UITextField()
|
||||
// private let onboardingCodeView = OnboardingCodeView()
|
||||
// private var codeStateLink: OWSFlatButton?
|
||||
// private let errorLabel = UILabel()
|
||||
private let avatarView = AvatarImageView()
|
||||
private let nameTextfield = UITextField()
|
||||
private var avatar: UIImage?
|
||||
private let cameraCircle = UIView.container()
|
||||
|
||||
private let avatarViewHelper = AvatarViewHelper()
|
||||
|
||||
override public func loadView() {
|
||||
super.loadView()
|
||||
|
||||
avatarViewHelper.delegate = self
|
||||
|
||||
view.backgroundColor = Theme.backgroundColor
|
||||
view.layoutMargins = .zero
|
||||
|
||||
let titleLabel = self.titleLabel(text: NSLocalizedString("ONBOARDING_PROFILE_TITLE", comment: "Title of the 'onboarding profile' view."))
|
||||
|
||||
let explanationLabel = self.explanationLabel(explanationText: NSLocalizedString("ONBOARDING_PROFILE_EXPLANATION",
|
||||
comment: "Explanation in the 'onboarding profile' view."))
|
||||
|
||||
let nextButton = self.button(title: NSLocalizedString("BUTTON_NEXT",
|
||||
comment: "Label for the 'next' button."),
|
||||
selector: #selector(nextPressed))
|
||||
|
||||
avatarView.autoSetDimensions(to: CGSize(width: CGFloat(avatarSize), height: CGFloat(avatarSize)))
|
||||
|
||||
let cameraImageView = UIImageView()
|
||||
cameraImageView.image = UIImage(named: "settings-avatar-camera")
|
||||
cameraCircle.backgroundColor = Theme.backgroundColor
|
||||
cameraCircle.addSubview(cameraImageView)
|
||||
let cameraCircleDiameter: CGFloat = 40
|
||||
cameraCircle.autoSetDimensions(to: CGSize(width: cameraCircleDiameter, height: cameraCircleDiameter))
|
||||
cameraCircle.layer.shadowColor = UIColor(white: 0, alpha: 0.15).cgColor
|
||||
cameraCircle.layer.shadowRadius = 5
|
||||
cameraCircle.layer.shadowOffset = CGSize(width: 1, height: 1)
|
||||
cameraCircle.layer.shadowOpacity = 1
|
||||
cameraCircle.layer.cornerRadius = cameraCircleDiameter * 0.5
|
||||
cameraCircle.clipsToBounds = false
|
||||
cameraImageView.autoCenterInSuperview()
|
||||
|
||||
let avatarWrapper = UIView.container()
|
||||
avatarWrapper.isUserInteractionEnabled = true
|
||||
avatarWrapper.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(avatarTapped)))
|
||||
avatarWrapper.addSubview(avatarView)
|
||||
avatarView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: 4, leading: 4, bottom: 4, trailing: 4))
|
||||
avatarWrapper.addSubview(cameraCircle)
|
||||
cameraCircle.autoPinEdge(toSuperviewEdge: .trailing)
|
||||
cameraCircle.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
|
||||
nameTextfield.textAlignment = .left
|
||||
nameTextfield.delegate = self
|
||||
nameTextfield.returnKeyType = .done
|
||||
nameTextfield.textColor = Theme.primaryColor
|
||||
// nameTextfield.tintColor = UIColor.ows_materialBlue
|
||||
nameTextfield.font = UIFont.ows_dynamicTypeBodyClamped
|
||||
nameTextfield.placeholder = NSLocalizedString("ONBOARDING_PROFILE_NAME_PLACEHOLDER",
|
||||
comment: "Placeholder text for the profile name in the 'onboarding profile' view.")
|
||||
nameTextfield.setContentHuggingHorizontalLow()
|
||||
nameTextfield.setCompressionResistanceHorizontalLow()
|
||||
|
||||
let nameWrapper = UIView.container()
|
||||
nameWrapper.setCompressionResistanceHorizontalLow()
|
||||
nameWrapper.setContentHuggingHorizontalLow()
|
||||
nameWrapper.addSubview(nameTextfield)
|
||||
nameTextfield.autoPinWidthToSuperview()
|
||||
nameTextfield.autoPinEdge(toSuperviewEdge: .top, withInset: 8)
|
||||
nameTextfield.autoPinEdge(toSuperviewEdge: .bottom, withInset: 8)
|
||||
_ = nameWrapper.addBottomStroke()
|
||||
|
||||
let profileRow = UIStackView(arrangedSubviews: [
|
||||
avatarWrapper,
|
||||
nameWrapper
|
||||
])
|
||||
profileRow.axis = .horizontal
|
||||
profileRow.alignment = .center
|
||||
profileRow.spacing = 8
|
||||
|
||||
let topSpacer = UIView.vStretchingSpacer()
|
||||
let bottomSpacer = UIView.vStretchingSpacer()
|
||||
|
||||
let stackView = UIStackView(arrangedSubviews: [
|
||||
titleLabel,
|
||||
topSpacer,
|
||||
profileRow,
|
||||
UIView.spacer(withHeight: 25),
|
||||
explanationLabel,
|
||||
UIView.spacer(withHeight: 20),
|
||||
nextButton,
|
||||
bottomSpacer
|
||||
])
|
||||
stackView.axis = .vertical
|
||||
stackView.alignment = .fill
|
||||
stackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
|
||||
stackView.isLayoutMarginsRelativeArrangement = true
|
||||
view.addSubview(stackView)
|
||||
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)
|
||||
|
||||
updateAvatarView()
|
||||
}
|
||||
|
||||
private let avatarSize: UInt = 80
|
||||
|
||||
private func updateAvatarView() {
|
||||
if let avatar = avatar {
|
||||
avatarView.image = avatar
|
||||
cameraCircle.isHidden = true
|
||||
return
|
||||
}
|
||||
|
||||
let defaultAvatar = OWSContactAvatarBuilder(forLocalUserWithDiameter: avatarSize).buildDefaultImage()
|
||||
avatarView.image = defaultAvatar
|
||||
cameraCircle.isHidden = false
|
||||
}
|
||||
|
||||
// // MARK: - Code State
|
||||
//
|
||||
// private let countdownDuration: TimeInterval = 60
|
||||
// private var codeCountdownTimer: Timer?
|
||||
// private var codeCountdownStart: NSDate?
|
||||
//
|
||||
// deinit {
|
||||
// if let codeCountdownTimer = codeCountdownTimer {
|
||||
// codeCountdownTimer.invalidate()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private func startCodeCountdown() {
|
||||
// codeCountdownStart = NSDate()
|
||||
// codeCountdownTimer = Timer.weakScheduledTimer(withTimeInterval: 1, target: self, selector: #selector(codeCountdownTimerFired), userInfo: nil, repeats: true)
|
||||
// }
|
||||
//
|
||||
// @objc
|
||||
// public func codeCountdownTimerFired() {
|
||||
// guard let codeCountdownStart = codeCountdownStart else {
|
||||
// owsFailDebug("Missing codeCountdownStart.")
|
||||
// return
|
||||
// }
|
||||
// guard let codeCountdownTimer = codeCountdownTimer else {
|
||||
// owsFailDebug("Missing codeCountdownTimer.")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// let countdownInterval = abs(codeCountdownStart.timeIntervalSinceNow)
|
||||
//
|
||||
// guard countdownInterval < countdownDuration else {
|
||||
// // Countdown complete.
|
||||
// codeCountdownTimer.invalidate()
|
||||
// self.codeCountdownTimer = nil
|
||||
//
|
||||
// if codeState != .pending {
|
||||
// owsFailDebug("Unexpected codeState: \(codeState)")
|
||||
// }
|
||||
// codeState = .possiblyNotDelivered
|
||||
// updateCodeState()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // Update the "code state" UI to reflect the countdown.
|
||||
// updateCodeState()
|
||||
// }
|
||||
//
|
||||
// private func updateCodeState() {
|
||||
// AssertIsOnMainThread()
|
||||
//
|
||||
// guard let codeCountdownStart = codeCountdownStart else {
|
||||
// owsFailDebug("Missing codeCountdownStart.")
|
||||
// return
|
||||
// }
|
||||
// guard let titleLabel = titleLabel else {
|
||||
// owsFailDebug("Missing titleLabel.")
|
||||
// return
|
||||
// }
|
||||
// guard let codeStateLink = codeStateLink else {
|
||||
// owsFailDebug("Missing codeStateLink.")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// var e164PhoneNumber = ""
|
||||
// if let phoneNumber = onboardingController.phoneNumber {
|
||||
// e164PhoneNumber = phoneNumber.e164
|
||||
// }
|
||||
// let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: e164PhoneNumber)
|
||||
//
|
||||
// // Update titleLabel
|
||||
// switch codeState {
|
||||
// case .pending, .possiblyNotDelivered:
|
||||
// titleLabel.text = String(format: NSLocalizedString("ONBOARDING_VERIFICATION_TITLE_DEFAULT_FORMAT",
|
||||
// comment: "Format for the title of the 'onboarding verification' view. Embeds {{the user's phone number}}."),
|
||||
// formattedPhoneNumber)
|
||||
// case .resent:
|
||||
// titleLabel.text = String(format: NSLocalizedString("ONBOARDING_VERIFICATION_TITLE_RESENT_FORMAT",
|
||||
// comment: "Format for the title of the 'onboarding verification' view after the verification code has been resent. Embeds {{the user's phone number}}."),
|
||||
// formattedPhoneNumber)
|
||||
// }
|
||||
//
|
||||
// // Update codeStateLink
|
||||
// switch codeState {
|
||||
// case .pending:
|
||||
// let countdownInterval = abs(codeCountdownStart.timeIntervalSinceNow)
|
||||
// let countdownRemaining = max(0, countdownDuration - countdownInterval)
|
||||
// let formattedCountdown = OWSFormat.formatDurationSeconds(Int(round(countdownRemaining)))
|
||||
// let text = String(format: NSLocalizedString("ONBOARDING_VERIFICATION_CODE_COUNTDOWN_FORMAT",
|
||||
// comment: "Format for the label of the 'pending code' label of the 'onboarding verification' view. Embeds {{the time until the code can be resent}}."),
|
||||
// formattedCountdown)
|
||||
// codeStateLink.setTitle(title: text, font: .ows_dynamicTypeBodyClamped, titleColor: Theme.secondaryColor)
|
||||
//// codeStateLink.setBackgroundColors(upColor: Theme.backgroundColor)
|
||||
// case .possiblyNotDelivered:
|
||||
// codeStateLink.setTitle(title: NSLocalizedString("ONBOARDING_VERIFICATION_ORIGINAL_CODE_MISSING_LINK",
|
||||
// comment: "Label for link that can be used when the original code did not arrive."),
|
||||
// font: .ows_dynamicTypeBodyClamped,
|
||||
// titleColor: .ows_materialBlue)
|
||||
// case .resent:
|
||||
// codeStateLink.setTitle(title: NSLocalizedString("ONBOARDING_VERIFICATION_RESENT_CODE_MISSING_LINK",
|
||||
// comment: "Label for link that can be used when the resent code did not arrive."),
|
||||
// font: .ows_dynamicTypeBodyClamped,
|
||||
// titleColor: .ows_materialBlue)
|
||||
// }
|
||||
// }
|
||||
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
_ = nameTextfield.becomeFirstResponder()
|
||||
}
|
||||
|
||||
// MARK: - Events
|
||||
|
||||
@objc func avatarTapped(sender: UIGestureRecognizer) {
|
||||
guard sender.state == .recognized else {
|
||||
return
|
||||
}
|
||||
showAvatarActionSheet()
|
||||
}
|
||||
|
||||
@objc func nextPressed() {
|
||||
Logger.info("")
|
||||
|
||||
// TODO:
|
||||
// parseAndTryToRegister()
|
||||
}
|
||||
|
||||
private func showAvatarActionSheet() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
Logger.info("")
|
||||
|
||||
avatarViewHelper.showChangeAvatarUI()
|
||||
|
||||
// let alert = UIAlertController(title: NSLocalizedString("CHECK_FOR_BACKUP_FAILED_TITLE",
|
||||
// comment: "Title for alert shown when the app failed to check for an existing backup."),
|
||||
// message: NSLocalizedString("CHECK_FOR_BACKUP_FAILED_MESSAGE",
|
||||
// comment: "Message for alert shown when the app failed to check for an existing backup."),
|
||||
// preferredStyle: .alert)
|
||||
// alert.addAction(UIAlertAction(title: NSLocalizedString("REGISTER_FAILED_TRY_AGAIN", comment: ""),
|
||||
// style: .default) { (_) in
|
||||
// self.checkCanImportBackup(fromView: view)
|
||||
// })
|
||||
// alert.addAction(UIAlertAction(title: NSLocalizedString("CHECK_FOR_BACKUP_DO_NOT_RESTORE", comment: "The label for the 'do not restore backup' button."),
|
||||
// style: .destructive) { (_) in
|
||||
// self.showProfileView(fromView: view)
|
||||
// })
|
||||
// view.present(alert, animated: true)
|
||||
}
|
||||
|
||||
// @objc func backLinkTapped() {
|
||||
// Logger.info("")
|
||||
//
|
||||
// self.navigationController?.popViewController(animated: true)
|
||||
// }
|
||||
//
|
||||
// @objc func resendCodeLinkTapped() {
|
||||
// Logger.info("")
|
||||
//
|
||||
// switch codeState {
|
||||
// case .pending:
|
||||
// // Ignore taps until the countdown expires.
|
||||
// break
|
||||
// case .possiblyNotDelivered, .resent:
|
||||
// showResendActionSheet()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private func showResendActionSheet() {
|
||||
// Logger.info("")
|
||||
//
|
||||
// let actionSheet = UIAlertController(title: NSLocalizedString("ONBOARDING_VERIFICATION_RESEND_CODE_ALERT_TITLE",
|
||||
// comment: "Title for the 'resend code' alert in the 'onboarding verification' view."),
|
||||
// message: NSLocalizedString("ONBOARDING_VERIFICATION_RESEND_CODE_ALERT_MESSAGE",
|
||||
// comment: "Message for the 'resend code' alert in the 'onboarding verification' view."),
|
||||
// preferredStyle: .actionSheet)
|
||||
//
|
||||
// actionSheet.addAction(UIAlertAction(title: NSLocalizedString("ONBOARDING_VERIFICATION_RESEND_CODE_BY_SMS_BUTTON",
|
||||
// comment: "Label for the 'resend code by SMS' button in the 'onboarding verification' view."),
|
||||
// style: .default) { _ in
|
||||
// self.onboardingController.tryToRegister(fromViewController: self, smsVerification: true)
|
||||
// })
|
||||
// actionSheet.addAction(UIAlertAction(title: NSLocalizedString("ONBOARDING_VERIFICATION_RESEND_CODE_BY_VOICE_BUTTON",
|
||||
// comment: "Label for the 'resend code by voice' button in the 'onboarding verification' view."),
|
||||
// style: .default) { _ in
|
||||
// self.onboardingController.tryToRegister(fromViewController: self, smsVerification: false)
|
||||
// })
|
||||
// actionSheet.addAction(OWSAlerts.cancelAction)
|
||||
//
|
||||
// self.present(actionSheet, animated: true)
|
||||
// }
|
||||
//
|
||||
// private func tryToVerify() {
|
||||
// Logger.info("")
|
||||
//
|
||||
// guard onboardingCodeView.isComplete else {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// setHasInvalidCode(false)
|
||||
//
|
||||
// onboardingController.tryToVerify(fromViewController: self, verificationCode: onboardingCodeView.verificationCode, pin: nil, isInvalidCodeCallback: {
|
||||
// self.setHasInvalidCode(true)
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// private func setHasInvalidCode(_ value: Bool) {
|
||||
// onboardingCodeView.setHasError(value)
|
||||
// errorLabel.isHidden = !value
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// MARK: -
|
||||
//
|
||||
//extension OnboardingProfileViewController: OnboardingCodeViewDelegate {
|
||||
// public func codeViewDidChange() {
|
||||
// AssertIsOnMainThread()
|
||||
//
|
||||
// setHasInvalidCode(false)
|
||||
//
|
||||
// tryToVerify()
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
extension OnboardingProfileViewController: UITextFieldDelegate {
|
||||
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
// // 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 true
|
||||
}
|
||||
|
||||
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
// parseAndTryToRegister()
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
extension OnboardingProfileViewController: AvatarViewHelperDelegate {
|
||||
public func avatarActionSheetTitle() -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func avatarDidChange(_ image: UIImage) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
let maxDiameter = CGFloat(kOWSProfileManager_MaxAvatarDiameter)
|
||||
avatar = image.resizedImage(toFillPixelSize: CGSize(width: maxDiameter,
|
||||
height: maxDiameter))
|
||||
|
||||
updateAvatarView()
|
||||
}
|
||||
|
||||
public func fromViewController() -> UIViewController {
|
||||
return self
|
||||
}
|
||||
|
||||
public func hasClearAvatarAction() -> Bool {
|
||||
return avatar != nil
|
||||
}
|
||||
|
||||
public func clearAvatar() {
|
||||
avatar = nil
|
||||
|
||||
updateAvatarView()
|
||||
}
|
||||
|
||||
public func clearAvatarActionLabel() -> String {
|
||||
return NSLocalizedString("PROFILE_VIEW_CLEAR_AVATAR", comment: "Label for action that clear's the user's profile avatar")
|
||||
}
|
||||
}
|
|
@ -133,14 +133,8 @@ private class OnboardingCodeView: UIView {
|
|||
digitView.addSubview(digitLabel)
|
||||
digitLabel.autoCenterInSuperview()
|
||||
|
||||
let strokeView = UIView.container()
|
||||
if hasStroke {
|
||||
strokeView.backgroundColor = Theme.primaryColor
|
||||
digitView.addSubview(strokeView)
|
||||
strokeView.autoPinWidthToSuperview()
|
||||
strokeView.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
strokeView.autoSetDimension(.height, toSize: 1)
|
||||
}
|
||||
let strokeColor = (hasStroke ? Theme.primaryColor : UIColor.clear)
|
||||
let strokeView = digitView.addBottomStroke(color: strokeColor, strokeWidth: 1)
|
||||
|
||||
let vMargin: CGFloat = 4
|
||||
let cellHeight: CGFloat = digitLabel.font.lineHeight + vMargin * 2
|
||||
|
|
|
@ -485,7 +485,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - AvatarViewHelperDelegate
|
||||
|
||||
- (NSString *)avatarActionSheetTitle
|
||||
- (nullable NSString *)avatarActionSheetTitle
|
||||
{
|
||||
return NSLocalizedString(
|
||||
@"NEW_GROUP_ADD_PHOTO_ACTION", @"Action Sheet title prompting the user for a group avatar");
|
||||
|
|
|
@ -1529,6 +1529,15 @@
|
|||
/* Label indicating that the phone number is invalid in the 'onboarding phone number' view. */
|
||||
"ONBOARDING_PHONE_NUMBER_VALIDATION_WARNING" = "Invalid number";
|
||||
|
||||
/* Explanation in the 'onboarding profile' view. */
|
||||
"ONBOARDING_PROFILE_EXPLANATION" = "Signal profiles are end-to-end encrypted and the Signal service never has access to this information.";
|
||||
|
||||
/* Placeholder text for the profile name in the 'onboarding profile' view. */
|
||||
"ONBOARDING_PROFILE_NAME_PLACEHOLDER" = "Your Name";
|
||||
|
||||
/* Title of the 'onboarding profile' view. */
|
||||
"ONBOARDING_PROFILE_TITLE" = "Set up your profile";
|
||||
|
||||
/* Link to the 'terms and privacy policy' in the 'onboarding splash' view. */
|
||||
"ONBOARDING_SPLASH_TERM_AND_PRIVACY_POLICY" = "Terms & Privacy Policy";
|
||||
|
||||
|
|
Loading…
Reference in New Issue