196 lines
8.7 KiB
Swift
196 lines
8.7 KiB
Swift
//
|
|
// CredentialsViewIPAD.swift
|
|
// PrivadoVPN
|
|
//
|
|
// Created by Lizaveta Malinouskaya on 25.10.21.
|
|
// Copyright © 2021 Privado LLC. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class CredentialsViewIPAD: BaseView {
|
|
|
|
// MARK: - Constant
|
|
enum Constant {
|
|
enum Geometry {
|
|
static let viewRadius: CGFloat = 16
|
|
static let buttonSize = CGSize(width: 464, height: 70)
|
|
static let centerShift: CGFloat = 4
|
|
static let promptLeading: CGFloat = 29
|
|
static let credentialLeading: CGFloat = 188
|
|
static let copyButtonTrailing: CGFloat = 13
|
|
static let distanceBetweenViews: CGFloat = 1.47
|
|
}
|
|
enum Color {
|
|
static let buttonBg = Colors.Base.primaryDarkBlue.color
|
|
static let credentialsText = Colors.SystemCTA.green.color
|
|
static let baseText = Colors.basicText.color
|
|
}
|
|
enum Image {
|
|
static let copy = UIImage(named: "credentials.copy")
|
|
}
|
|
enum Font {
|
|
static let text = UIFont.primary(size: 22, weight: .regular)
|
|
}
|
|
enum LocalizedString {
|
|
static let password = NSLocalizedString("credentials.password", comment: "Password")
|
|
static let username = NSLocalizedString("credentials.username", comment: "Username")
|
|
}
|
|
}
|
|
|
|
// MARK: - Property
|
|
var usernameButton: UIView?
|
|
var passwordButton: UIView?
|
|
let output: CredentialsControllerOutput
|
|
|
|
enum CredentialLabelType {
|
|
case prompt(isUsername: Bool)
|
|
case credential(isUsername: Bool)
|
|
}
|
|
|
|
// MARK: - Init
|
|
public init(with output: CredentialsControllerOutput) {
|
|
self.output = output
|
|
super.init()
|
|
|
|
self.setupUI()
|
|
self.layoutEmitter.addReaction { [weak self] isLandscape -> ShouldContinueReceiveNotifications in
|
|
guard let self = self else { return false }
|
|
self.setRoundCorners(isLandscape: isLandscape)
|
|
return true
|
|
}
|
|
}
|
|
|
|
// MARK: - UI
|
|
|
|
private func setupUI() {
|
|
self.translatesAutoresizingMaskIntoConstraints = false
|
|
self.usernameButton = self.setupUsernameView(with: self)
|
|
self.passwordButton = self.setupPasswordView(with: self)
|
|
guard let usernameView = self.usernameButton,
|
|
let passwordView = self.passwordButton else { return }
|
|
self.portraitConstraints.append(contentsOf: [
|
|
self.heightAnchor.constraint(equalToConstant: 2 * Constant.Geometry.buttonSize.height),
|
|
usernameView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
|
|
usernameView.topAnchor.constraint(equalTo: self.topAnchor),
|
|
passwordView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
|
|
passwordView.topAnchor.constraint(equalTo: usernameView.bottomAnchor, constant: Constant.Geometry.distanceBetweenViews)
|
|
])
|
|
self.landscapeConstraints.append(contentsOf: [
|
|
self.heightAnchor.constraint(equalToConstant: Constant.Geometry.buttonSize.height),
|
|
usernameView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
|
|
usernameView.trailingAnchor.constraint(equalTo: self.centerXAnchor, constant: -5),
|
|
passwordView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
|
|
passwordView.leadingAnchor.constraint(equalTo: self.centerXAnchor, constant: 5)
|
|
])
|
|
}
|
|
|
|
private func setupUsernameView(with container: UIView) -> UIView {
|
|
let view = UIView()
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
view.backgroundColor = Constant.Color.buttonBg
|
|
let prompt = self.createLabel(of: .prompt(isUsername: true), container: view)
|
|
let username = self.createLabel(of: .credential(isUsername: true), container: view)
|
|
let copyButton = self.createCopyButton(container: view)
|
|
copyButton.addTarget(self, action: #selector(self.didTapCopyUsername), for: .touchUpInside)
|
|
self.setupCredentialViewConstraints(view: view, promptLabel: prompt, credentialLabel: username, copyButton: copyButton)
|
|
container.addSubview(view)
|
|
return view
|
|
}
|
|
|
|
private func setupPasswordView(with container: UIView) -> UIView {
|
|
let view = UIView()
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
view.backgroundColor = Constant.Color.buttonBg
|
|
let prompt = self.createLabel(of: .prompt(isUsername: false), container: view)
|
|
let username = self.createLabel(of: .credential(isUsername: false), container: view)
|
|
let copyButton = self.createCopyButton(container: view)
|
|
copyButton.addTarget(self, action: #selector(self.didTapCopyPassword), for: .touchUpInside)
|
|
self.setupCredentialViewConstraints(view: view, promptLabel: prompt, credentialLabel: username, copyButton: copyButton)
|
|
container.addSubview(view)
|
|
return view
|
|
}
|
|
|
|
private func setupCredentialViewConstraints(view: UIView, promptLabel: UIView, credentialLabel: UIView, copyButton: UIButton) {
|
|
NSLayoutConstraint.activate([
|
|
view.heightAnchor.constraint(equalToConstant: Constant.Geometry.buttonSize.height),
|
|
view.widthAnchor.constraint(equalToConstant: Constant.Geometry.buttonSize.width),
|
|
|
|
promptLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: Constant.Geometry.centerShift),
|
|
promptLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: Constant.Geometry.promptLeading),
|
|
|
|
credentialLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: Constant.Geometry.centerShift),
|
|
credentialLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: Constant.Geometry.credentialLeading),
|
|
|
|
copyButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
|
|
copyButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -Constant.Geometry.copyButtonTrailing)
|
|
])
|
|
}
|
|
|
|
private func createLabel(of type: CredentialLabelType, container: UIView) -> UIView {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = Constant.Font.text
|
|
switch type {
|
|
case .prompt(let isUsername):
|
|
label.textColor = Constant.Color.baseText
|
|
label.text = isUsername
|
|
? Constant.LocalizedString.username
|
|
: Constant.LocalizedString.password
|
|
case .credential(let isUsername):
|
|
label.textColor = Constant.Color.credentialsText
|
|
label.text = isUsername
|
|
? output.username
|
|
: output.password
|
|
}
|
|
container.addSubview(label)
|
|
return label
|
|
}
|
|
|
|
private func createCopyButton(container: UIView) -> UIButton {
|
|
let button = UIButton()
|
|
button.translatesAutoresizingMaskIntoConstraints = false
|
|
button.setImage(Constant.Image.copy, for: .normal)
|
|
container.addSubview(button)
|
|
return button
|
|
}
|
|
|
|
private func setRoundCorners(isLandscape: Bool) {
|
|
guard let passwordView = self.passwordButton,
|
|
let usernameView = self.usernameButton else { return }
|
|
|
|
let radius = Constant.Geometry.viewRadius
|
|
let passwordCorners: UIRectCorner = [UIRectCorner.bottomLeft, UIRectCorner.bottomRight]
|
|
let usernameCorners: UIRectCorner = [UIRectCorner.topLeft, UIRectCorner.topRight]
|
|
let allCorners = UIRectCorner.allCorners
|
|
|
|
if isLandscape {
|
|
passwordView.layer.mask = self.createMask(for: passwordView, roundingCorners: allCorners, radius: radius)
|
|
usernameView.layer.mask = self.createMask(for: usernameView, roundingCorners: allCorners, radius: radius)
|
|
} else {
|
|
passwordView.layer.mask = self.createMask(for: passwordView, roundingCorners: passwordCorners, radius: radius)
|
|
usernameView.layer.mask = self.createMask(for: usernameView, roundingCorners: usernameCorners, radius: radius)
|
|
}
|
|
}
|
|
|
|
private func createMask(for view: UIView, roundingCorners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
|
|
let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: roundingCorners, cornerRadii: CGSize(width: radius, height: radius))
|
|
let mask = CAShapeLayer()
|
|
mask.path = path.cgPath
|
|
return mask
|
|
}
|
|
|
|
// MARK: - objc methods
|
|
|
|
@objc func didTapCopyUsername() {
|
|
UINotificationFeedbackGenerator().notificationOccurred(.success)
|
|
UIPasteboard.general.string = self.output.username
|
|
}
|
|
|
|
@objc func didTapCopyPassword() {
|
|
UINotificationFeedbackGenerator().notificationOccurred(.success)
|
|
UIPasteboard.general.string = self.output.password
|
|
}
|
|
|
|
}
|