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 ...@@ -2,7 +2,6 @@ import UIKit
import Shared import Shared
import Combine import Combine
import InputField import InputField
import ScrollViewController
public final class BackupPassphraseController: UIViewController { public final class BackupPassphraseController: UIViewController {
lazy private var screenView = BackupPassphraseView() lazy private var screenView = BackupPassphraseView()
...@@ -21,7 +20,6 @@ public final class BackupPassphraseController: UIViewController { ...@@ -21,7 +20,6 @@ public final class BackupPassphraseController: UIViewController {
private let cancelClosure: EmptyClosure private let cancelClosure: EmptyClosure
private let stringClosure: StringClosure private let stringClosure: StringClosure
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
private let keyboardListener = KeyboardFrameChangeListener(notificationCenter: .default)
public init( public init(
_ cancelClosure: @escaping EmptyClosure, _ cancelClosure: @escaping EmptyClosure,
...@@ -35,66 +33,41 @@ public final class BackupPassphraseController: UIViewController { ...@@ -35,66 +33,41 @@ public final class BackupPassphraseController: UIViewController {
required init?(coder: NSCoder) { nil } required init?(coder: NSCoder) { nil }
public override func loadView() { public override func loadView() {
let view = UIView() view = screenView
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
} }
public override func viewDidLoad() { public override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setupKeyboard()
setupBindings() 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() { private func setupBindings() {
screenView.inputField.returnPublisher screenView
.sink { [unowned self] in screenView.inputField.endEditing(true) } .inputField
.store(in: &cancellables) .returnPublisher
.sink { [unowned self] in
screenView.cancelButton screenView.inputField.endEditing(true)
.publisher(for: .touchUpInside) }.store(in: &cancellables)
.sink { [unowned self] in dismiss(animated: true) { self.cancelClosure() }}
.store(in: &cancellables)
screenView.inputField screenView
.inputField
.textPublisher .textPublisher
.sink { [unowned self] in passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines) } .sink { [unowned self] in
.store(in: &cancellables) 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) .publisher(for: .touchUpInside)
.sink { [unowned self] in .sink { [unowned self] in
dismiss(animated: true) { dismiss(animated: true) { self.cancelClosure() }
self.stringClosure(self.passphrase)
}
}.store(in: &cancellables) }.store(in: &cancellables)
} }
} }
import UIKit import UIKit
import Shared import Shared
import Presentation import Presentation
import ScrollViewController
public protocol BackupCoordinating { public protocol BackupCoordinating {
func toDrawer( func toDrawer(
...@@ -16,12 +17,18 @@ public protocol BackupCoordinating { ...@@ -16,12 +17,18 @@ public protocol BackupCoordinating {
} }
public struct BackupCoordinator: 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( public init(
passphraseFactory: @escaping (@escaping EmptyClosure, @escaping StringClosure) -> UIViewController passphraseFactory: @escaping (
@escaping EmptyClosure,
@escaping StringClosure
) -> UIViewController
) { ) {
self.passphraseFactory = passphraseFactory self.passphraseFactory = passphraseFactory
} }
...@@ -32,7 +39,8 @@ public extension BackupCoordinator { ...@@ -32,7 +39,8 @@ public extension BackupCoordinator {
_ screen: UIViewController, _ screen: UIViewController,
from parent: UIViewController from parent: UIViewController
) { ) {
bottomPresenter.present(screen, from: parent) let target = ScrollViewController.embedding(screen)
fullscreenPresenter.present(target, from: parent)
} }
func toPassphrase( func toPassphrase(
...@@ -41,6 +49,21 @@ public extension BackupCoordinator { ...@@ -41,6 +49,21 @@ public extension BackupCoordinator {
passphraseClosure: @escaping StringClosure passphraseClosure: @escaping StringClosure
) { ) {
let screen = passphraseFactory(cancelClosure, passphraseClosure) 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 ...@@ -4,49 +4,62 @@ import InputField
final class BackupPassphraseView: UIView { final class BackupPassphraseView: UIView {
let titleLabel = UILabel() let titleLabel = UILabel()
let subtitleLabel = UILabel()
let inputField = InputField()
let stackView = UIStackView() let stackView = UIStackView()
let continueButton = CapsuleButton() let inputField = InputField()
let subtitleLabel = UILabel()
let cancelButton = CapsuleButton() let cancelButton = CapsuleButton()
let continueButton = CapsuleButton()
init() { init() {
super.init(frame: .zero) super.init(frame: .zero)
setup()
}
required init?(coder: NSCoder) { nil }
private func setup() {
layer.cornerRadius = 40 layer.cornerRadius = 40
backgroundColor = Asset.neutralWhite.color backgroundColor = Asset.neutralWhite.color
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
subtitleLabel.numberOfLines = 0 setupInput()
titleLabel.textColor = Asset.neutralActive.color setupLabels()
subtitleLabel.textColor = Asset.neutralActive.color setupButtons()
setupStackView()
}
required init?(coder: NSCoder) { nil }
private func setupInput() {
inputField.setup( inputField.setup(
style: .regular, style: .regular,
title: "Passphrase", title: Localized.Backup.Passphrase.Input.title,
placeholder: "* * * * * *", placeholder: Localized.Backup.Passphrase.Input.placeholder,
subtitleColor: Asset.neutralDisabled.color rightView: .toggleSecureEntry,
subtitleColor: Asset.neutralDisabled.color,
allowsEmptySpace: false,
autocapitalization: .none,
contentType: .newPassword
) )
}
titleLabel.text = "Secure your backup" private func setupLabels() {
titleLabel.textAlignment = .left titleLabel.textAlignment = .left
titleLabel.text = Localized.Backup.Passphrase.title
titleLabel.textColor = Asset.neutralActive.color
titleLabel.font = Fonts.Mulish.bold.font(size: 26.0) 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.textAlignment = .left
subtitleLabel.textColor = Asset.neutralActive.color
subtitleLabel.text = Localized.Backup.Passphrase.subtitle
subtitleLabel.font = Fonts.Mulish.regular.font(size: 16.0) subtitleLabel.font = Fonts.Mulish.regular.font(size: 16.0)
}
continueButton.setStyle(.brandColored) private func setupButtons() {
continueButton.setTitle("Set password and continue", for: .normal)
cancelButton.setStyle(.seeThrough) 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.spacing = 20
stackView.axis = .vertical stackView.axis = .vertical
stackView.addArrangedSubview(titleLabel) stackView.addArrangedSubview(titleLabel)
...@@ -57,11 +70,11 @@ final class BackupPassphraseView: UIView { ...@@ -57,11 +70,11 @@ final class BackupPassphraseView: UIView {
addSubview(stackView) addSubview(stackView)
stackView.snp.makeConstraints { make in stackView.snp.makeConstraints {
make.top.equalToSuperview().offset(60) $0.top.equalToSuperview().offset(60)
make.left.equalToSuperview().offset(50) $0.left.equalToSuperview().offset(50)
make.right.equalToSuperview().offset(-50) $0.right.equalToSuperview().offset(-50)
make.bottom.equalToSuperview().offset(-70) $0.bottom.equalToSuperview().offset(-70)
} }
} }
} }
...@@ -197,7 +197,9 @@ public final class InputField: UIView { ...@@ -197,7 +197,9 @@ public final class InputField: UIView {
} }
private func hideButtonImage(isSecureEntry: Bool) -> UIImage? { 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() { private func setup() {
......
...@@ -274,6 +274,22 @@ public enum Localized { ...@@ -274,6 +274,22 @@ public enum Localized {
/// Backup settings /// Backup settings
public static let title = Localized.tr("Localizable", "backup.config.title") 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 { public enum Setup {
/// Setup your #backup service#. /// Setup your #backup service#.
public static let title = Localized.tr("Localizable", "backup.setup.title") public static let title = Localized.tr("Localizable", "backup.setup.title")
......
...@@ -656,6 +656,19 @@ ...@@ -656,6 +656,19 @@
"backup.config.infrastructure" "backup.config.infrastructure"
= "Backup over"; = "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" "backup.iCloud"
= "iCloud"; = "iCloud";
"backup.dropbox" "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