Skip to content
Snippets Groups Projects
Commit d074afa3 authored by Bruno Muniz's avatar Bruno Muniz :apple:
Browse files

Merge branch 'fix/backup-drawer' into 'development'

Fix backup password drawer resizing

See merge request elixxir/client-ios!72
parents 43cefcf6 30cfebac
No related branches found
No related tags found
2 merge requests!72Fix backup password drawer resizing,!71Releasing v1.1.5 (214)
......@@ -2,7 +2,6 @@ import UIKit
import Shared
import Combine
import InputField
import ScrollViewController
public final class BackupPassphraseController: UIViewController {
lazy private var screenView = BackupPassphraseView()
......@@ -21,7 +20,6 @@ public final class BackupPassphraseController: UIViewController {
private let cancelClosure: EmptyClosure
private let stringClosure: StringClosure
private var cancellables = Set<AnyCancellable>()
private let keyboardListener = KeyboardFrameChangeListener(notificationCenter: .default)
public init(
_ cancelClosure: @escaping EmptyClosure,
......@@ -35,66 +33,41 @@ public final class BackupPassphraseController: UIViewController {
required init?(coder: NSCoder) { nil }
public override func loadView() {
let view = UIView()
view.addSubview(screenView)
screenView.snp.makeConstraints { make in
make.top.equalToSuperview()
make.left.equalToSuperview()
make.right.equalToSuperview()
make.bottom.equalToSuperview().offset(0)
}
self.view = view
view = screenView
}
public override func viewDidLoad() {
super.viewDidLoad()
setupKeyboard()
setupBindings()
screenView.continueButton.isEnabled = false
}
private func setupKeyboard() {
keyboardListener.keyboardFrameWillChange = { [weak self] keyboard in
guard let self = self else { return }
let inset = self.view.frame.height - self.view.convert(keyboard.frame, from: nil).minY
self.screenView.snp.updateConstraints {
$0.bottom.equalToSuperview().offset(-inset)
}
self.view.setNeedsLayout()
UIView.animate(withDuration: keyboard.animationDuration) {
self.view.layoutIfNeeded()
}
}
}
private func setupBindings() {
screenView.inputField.returnPublisher
.sink { [unowned self] in screenView.inputField.endEditing(true) }
.store(in: &cancellables)
screenView.cancelButton
.publisher(for: .touchUpInside)
.sink { [unowned self] in dismiss(animated: true) { self.cancelClosure() }}
.store(in: &cancellables)
screenView
.inputField
.returnPublisher
.sink { [unowned self] in
screenView.inputField.endEditing(true)
}.store(in: &cancellables)
screenView.inputField
screenView
.inputField
.textPublisher
.sink { [unowned self] in passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.store(in: &cancellables)
.sink { [unowned self] in
passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines)
}.store(in: &cancellables)
screenView
.continueButton
.publisher(for: .touchUpInside)
.sink { [unowned self] in
dismiss(animated: true) { self.stringClosure(self.passphrase) }
}.store(in: &cancellables)
screenView.continueButton
screenView
.cancelButton
.publisher(for: .touchUpInside)
.sink { [unowned self] in
dismiss(animated: true) {
self.stringClosure(self.passphrase)
}
dismiss(animated: true) { self.cancelClosure() }
}.store(in: &cancellables)
}
}
import UIKit
import Shared
import Presentation
import ScrollViewController
public protocol BackupCoordinating {
func toDrawer(
......@@ -16,12 +17,18 @@ public protocol BackupCoordinating {
}
public struct BackupCoordinator: BackupCoordinating {
var bottomPresenter: Presenting = BottomPresenter()
var fullscreenPresenter: Presenting = FullscreenPresenter()
var passphraseFactory: (@escaping EmptyClosure, @escaping StringClosure) -> UIViewController
var passphraseFactory: (
@escaping EmptyClosure,
@escaping StringClosure
) -> UIViewController
public init(
passphraseFactory: @escaping (@escaping EmptyClosure, @escaping StringClosure) -> UIViewController
passphraseFactory: @escaping (
@escaping EmptyClosure,
@escaping StringClosure
) -> UIViewController
) {
self.passphraseFactory = passphraseFactory
}
......@@ -32,7 +39,8 @@ public extension BackupCoordinator {
_ screen: UIViewController,
from parent: UIViewController
) {
bottomPresenter.present(screen, from: parent)
let target = ScrollViewController.embedding(screen)
fullscreenPresenter.present(target, from: parent)
}
func toPassphrase(
......@@ -41,6 +49,21 @@ public extension BackupCoordinator {
passphraseClosure: @escaping StringClosure
) {
let screen = passphraseFactory(cancelClosure, passphraseClosure)
bottomPresenter.present(screen, from: parent)
let target = ScrollViewController.embedding(screen)
fullscreenPresenter.present(target, from: parent)
}
}
extension ScrollViewController {
static func embedding(_ viewController: UIViewController) -> ScrollViewController {
let scrollViewController = ScrollViewController()
scrollViewController.addChild(viewController)
scrollViewController.contentView = viewController.view
scrollViewController.wrapperView.handlesTouchesOutsideContent = false
scrollViewController.wrapperView.alignContentToBottom = true
scrollViewController.scrollView.bounces = false
viewController.didMove(toParent: scrollViewController)
return scrollViewController
}
}
......@@ -4,49 +4,62 @@ import InputField
final class BackupPassphraseView: UIView {
let titleLabel = UILabel()
let subtitleLabel = UILabel()
let inputField = InputField()
let stackView = UIStackView()
let continueButton = CapsuleButton()
let inputField = InputField()
let subtitleLabel = UILabel()
let cancelButton = CapsuleButton()
let continueButton = CapsuleButton()
init() {
super.init(frame: .zero)
setup()
}
required init?(coder: NSCoder) { nil }
private func setup() {
layer.cornerRadius = 40
backgroundColor = Asset.neutralWhite.color
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
subtitleLabel.numberOfLines = 0
titleLabel.textColor = Asset.neutralActive.color
subtitleLabel.textColor = Asset.neutralActive.color
setupInput()
setupLabels()
setupButtons()
setupStackView()
}
required init?(coder: NSCoder) { nil }
private func setupInput() {
inputField.setup(
style: .regular,
title: "Passphrase",
placeholder: "* * * * * *",
subtitleColor: Asset.neutralDisabled.color
title: Localized.Backup.Passphrase.Input.title,
placeholder: Localized.Backup.Passphrase.Input.placeholder,
rightView: .toggleSecureEntry,
subtitleColor: Asset.neutralDisabled.color,
allowsEmptySpace: false,
autocapitalization: .none,
contentType: .newPassword
)
}
titleLabel.text = "Secure your backup"
private func setupLabels() {
titleLabel.textAlignment = .left
titleLabel.text = Localized.Backup.Passphrase.title
titleLabel.textColor = Asset.neutralActive.color
titleLabel.font = Fonts.Mulish.bold.font(size: 26.0)
subtitleLabel.text = "Please select a password for your backup. If you lose this password, you will not be able to restore your account. Make sure to keep a record somewhere safe. Your password needs to be at least 8 characters with at least 1 uppercase, 1 lowercase and 1 number characters"
subtitleLabel.numberOfLines = 0
subtitleLabel.textAlignment = .left
subtitleLabel.textColor = Asset.neutralActive.color
subtitleLabel.text = Localized.Backup.Passphrase.subtitle
subtitleLabel.font = Fonts.Mulish.regular.font(size: 16.0)
}
continueButton.setStyle(.brandColored)
continueButton.setTitle("Set password and continue", for: .normal)
private func setupButtons() {
cancelButton.setStyle(.seeThrough)
cancelButton.setTitle("Cancel", for: .normal)
cancelButton.setTitle(Localized.Backup.Passphrase.cancel, for: .normal)
continueButton.isEnabled = false
continueButton.setStyle(.brandColored)
continueButton.setTitle(Localized.Backup.Passphrase.continue, for: .normal)
}
private func setupStackView() {
stackView.spacing = 20
stackView.axis = .vertical
stackView.addArrangedSubview(titleLabel)
......@@ -57,11 +70,11 @@ final class BackupPassphraseView: UIView {
addSubview(stackView)
stackView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(60)
make.left.equalToSuperview().offset(50)
make.right.equalToSuperview().offset(-50)
make.bottom.equalToSuperview().offset(-70)
stackView.snp.makeConstraints {
$0.top.equalToSuperview().offset(60)
$0.left.equalToSuperview().offset(50)
$0.right.equalToSuperview().offset(-50)
$0.bottom.equalToSuperview().offset(-70)
}
}
}
......@@ -197,7 +197,9 @@ public final class InputField: UIView {
}
private func hideButtonImage(isSecureEntry: Bool) -> UIImage? {
isSecureEntry ? Asset.eyeClosed.image : Asset.eyeOpen.image
let openImage = Asset.eyeOpen.image.withTintColor(Asset.neutralWeak.color)
let closedImage = Asset.eyeClosed.image.withTintColor(Asset.neutralWeak.color)
return isSecureEntry ? closedImage : openImage
}
private func setup() {
......
......@@ -274,6 +274,22 @@ public enum Localized {
/// Backup settings
public static let title = Localized.tr("Localizable", "backup.config.title")
}
public enum Passphrase {
/// Cancel
public static let cancel = Localized.tr("Localizable", "backup.passphrase.cancel")
/// Set password and continue
public static let `continue` = Localized.tr("Localizable", "backup.passphrase.continue")
/// Please select a password for your backup. If you lose this password, you will not be able to restore your account. Make sure to keep a record somewhere safe. Your password needs to be at least 8 characters with at least 1 uppercase, 1 lowercase and 1 number characters
public static let subtitle = Localized.tr("Localizable", "backup.passphrase.subtitle")
/// Secure your backup
public static let title = Localized.tr("Localizable", "backup.passphrase.title")
public enum Input {
/// * * * * * *
public static let placeholder = Localized.tr("Localizable", "backup.passphrase.input.placeholder")
/// Passphrase
public static let title = Localized.tr("Localizable", "backup.passphrase.input.title")
}
}
public enum Setup {
/// Setup your #backup service#.
public static let title = Localized.tr("Localizable", "backup.setup.title")
......
......@@ -656,6 +656,19 @@
"backup.config.infrastructure"
= "Backup over";
"backup.passphrase.title"
= "Secure your backup";
"backup.passphrase.subtitle"
= "Please select a password for your backup. If you lose this password, you will not be able to restore your account. Make sure to keep a record somewhere safe. Your password needs to be at least 8 characters with at least 1 uppercase, 1 lowercase and 1 number characters";
"backup.passphrase.input.title"
= "Passphrase";
"backup.passphrase.input.placeholder"
= "* * * * * *";
"backup.passphrase.continue"
= "Set password and continue";
"backup.passphrase.cancel"
= "Cancel";
"backup.iCloud"
= "iCloud";
"backup.dropbox"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment