Files
2021-10-25 15:42:54 +03:00

260 lines
12 KiB
Swift

//
// CredentialsControllerIPAD.swift
// PrivadoVPN
//
// Created by Lizaveta Malinouskaya on 21.10.21.
// Copyright © 2021 Privado LLC. All rights reserved.
//
import UIKit
class CredentialsControllerIPAD: BaseViewController {
// MARK: - Constant
enum Constant {
enum Geometry {
enum Shared {
static let buttonSize = CGSize(width: 418, height: 60)
static let labelWidth: CGFloat = 407
static let lineSpacing: CGFloat = 15
}
enum Portrait {
static let logoTop: CGFloat = 130
static let titleTop: CGFloat = 88
static let subtitleTop: CGFloat = 19
static let emailTop: CGFloat = 63
static let credentialsTop: CGFloat = 52
static let bottomTitleTop: CGFloat = 28
static let bottomSubtitleTop: CGFloat = 50
static let buttonTop: CGFloat = 32
}
enum Landscape {
static let logoTop: CGFloat = 90
static let titleTop: CGFloat = 31
static let subtitleTop: CGFloat = 19
static let emailTop: CGFloat = 34
static let credentialsTop: CGFloat = 33
static let bottomTitleTop: CGFloat = 38
static let bottomSubtitleTop: CGFloat = 27
static let buttonTop: CGFloat = 41
}
}
enum Font {
static let title = UIFont.primary(size: 30, weight: .semibold)
static let subtitle = UIFont.primary(size: 24, weight: .medium)
static let email = UIFont.primary(size: 28, weight: .medium)
static let bottomTitle = UIFont.primary(size: 16, weight: .semibold)
static let bottomSubtitle = UIFont.primary(size: 16, weight: .regular)
static let button = UIFont.primary(size: 16, weight: .bold)
}
enum Color {
static let title = Colors.basicText.color
static let subtitle = Colors.SystemCTA.lightPurple.color
static let button = Colors.Button.background.color
static let gradientTop = Colors.SystemBackgrounds.GradientActive.top.color
static let gradientBottom = Colors.SystemBackgrounds.GradientActive.bottom.color
}
enum Image {
static let title = UIImage(named: "logo.signup.notext")
}
enum LocalizedString {
static let title = NSLocalizedString("credentials.header.title.ipad", comment: "Welcome to PrivadoVPN")
static let subtitle = NSLocalizedString("credentials.heades.subtitle.ipad", comment: "Login to connect to the PrivadoVPN network.")
static let username = NSLocalizedString("credentials.username", comment: "Username")
static let password = NSLocalizedString("credentials.password", comment: "Password")
static let titleFooter = NSLocalizedString("credentials.footer.title.ipad", comment: "")
static let subtitleFooter = NSLocalizedString("credentials.footer.subtitle.ipad", comment: "")
static let button = NSLocalizedString("credentials.button.useApp", comment: "Use the app")
}
}
// MARK: - Property
private let output: CredentialsControllerOutput
// MARK: - init
init(output: CredentialsControllerOutput) {
self.output = output
super.init()
}
required init?(coder: NSCoder) { nil }
// MARK: - Life-cycle
override func viewDidLoad() {
super.viewDidLoad()
self.createUI()
}
// MARK: - UI
// swiftlint:disable function_body_length
private func createUI() {
let gradientView = self.initializeBackgroundGradient(using: self.view)
let logoView = self.initializeLogoView(using: self.view)
let titleView = self.initializeLabel(using: self.view,
text: Constant.LocalizedString.title,
font: Constant.Font.title,
textColor: Constant.Color.title)
let subtitleView = self.initializeLabel(using: self.view,
text: Constant.LocalizedString.subtitle,
font: Constant.Font.subtitle,
textColor: Constant.Color.subtitle)
let emailView = self.initializeLabel(using: self.view,
text: self.output.email ?? "",
font: Constant.Font.email,
textColor: Constant.Color.title)
let credentialsView = self.initializeCredentialsView(using: self.view)
let footerTitleView = self.initializeAttributedLabel(
using: self.view,
text: Constant.LocalizedString.titleFooter,
font: Constant.Font.bottomTitle,
textColor: Constant.Color.title)
let footerSubtitleView = self.initializeAttributedLabel(
using: self.view,
text: Constant.LocalizedString.subtitleFooter,
font: Constant.Font.bottomSubtitle,
textColor: Constant.Color.subtitle)
let buttonView = self.initializeUseAppButton(using: self.view)
self.setupBasicConstraints(for: titleView,
viewAbove: logoView,
distanceBetween: (Constant.Geometry.Portrait.titleTop, Constant.Geometry.Landscape.titleTop))
self.setupBasicConstraints(for: subtitleView,
viewAbove: titleView,
distanceBetween: (Constant.Geometry.Portrait.subtitleTop, Constant.Geometry.Landscape.subtitleTop))
self.setupBasicConstraints(for: emailView,
viewAbove: subtitleView,
distanceBetween: (Constant.Geometry.Portrait.emailTop, Constant.Geometry.Landscape.emailTop))
self.setupBasicConstraints(for: credentialsView,
viewAbove: emailView,
distanceBetween: (Constant.Geometry.Portrait.credentialsTop, Constant.Geometry.Landscape.credentialsTop))
self.setupBasicConstraints(for: footerTitleView,
viewAbove: credentialsView,
distanceBetween: (Constant.Geometry.Portrait.bottomSubtitleTop, Constant.Geometry.Landscape.bottomSubtitleTop))
self.setupBasicConstraints(for: footerSubtitleView,
viewAbove: footerTitleView,
distanceBetween: (Constant.Geometry.Portrait.bottomSubtitleTop, Constant.Geometry.Landscape.bottomSubtitleTop))
self.setupBasicConstraints(for: buttonView,
viewAbove: footerSubtitleView,
distanceBetween: (Constant.Geometry.Portrait.buttonTop, Constant.Geometry.Landscape.buttonTop))
self.sharedConstraints.append(contentsOf: [
buttonView.widthAnchor.constraint(equalToConstant: Constant.Geometry.Shared.buttonSize.width),
buttonView.heightAnchor.constraint(equalToConstant: Constant.Geometry.Shared.buttonSize.height),
gradientView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
gradientView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
gradientView.topAnchor.constraint(equalTo: self.view.topAnchor),
gradientView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
footerTitleView.widthAnchor.constraint(equalToConstant: Constant.Geometry.Shared.labelWidth),
credentialsView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
credentialsView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
logoView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
footerSubtitleView.widthAnchor.constraint(equalToConstant: Constant.Geometry.Shared.labelWidth)
])
self.portraitConstraints.append(contentsOf: [
logoView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: Constant.Geometry.Portrait.logoTop)
])
self.landscapeConstraints.append(contentsOf: [
logoView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: Constant.Geometry.Landscape.logoTop)
])
let landscape = DeviceInfoProvider.isLandscapeOrienation && self.traitCollection.horizontalSizeClass == .regular
self.layoutEmitter.invoke(landscape)
}
// swiftlint:enable function_body_length
private func setupBasicConstraints(for view: UIView, viewAbove: UIView, distanceBetween: (portrait: CGFloat, landscape: CGFloat)) {
self.sharedConstraints.append(contentsOf: [
view.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
])
self.portraitConstraints.append(contentsOf: [
view.topAnchor.constraint(equalTo: viewAbove.bottomAnchor, constant: distanceBetween.portrait)
])
self.landscapeConstraints.append(contentsOf: [
view.topAnchor.constraint(equalTo: viewAbove.bottomAnchor, constant: distanceBetween.landscape)
])
}
private func initializeAttributedLabel(using container: UIView, text: String, font: UIFont, textColor: UIColor) -> UILabel {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = Constant.Geometry.Shared.lineSpacing
let attributedString = NSAttributedString(string: text, attributes: [.paragraphStyle: paragraphStyle, .foregroundColor: textColor, .font: font])
label.attributedText = attributedString
label.textAlignment = .center
label.numberOfLines = 2
container.addSubview(label)
return label
}
private func initializeLabel(using container: UIView, text: String, font: UIFont, textColor: UIColor) -> UILabel {
let title = UILabel()
title.translatesAutoresizingMaskIntoConstraints = false
title.text = text
title.font = font
title.textColor = textColor
title.textAlignment = .center
container.addSubview(title)
return title
}
private func initializeBackgroundGradient(using container: UIView) -> UIView {
let gradientView = GradientView()
gradientView.translatesAutoresizingMaskIntoConstraints = false
gradientView.horizontalMode = false
gradientView.stops = [
.init(color: Constant.Color.gradientTop, location: 0),
.init(color: Constant.Color.gradientBottom, location: 1)
]
container.addSubview(gradientView)
return gradientView
}
private func initializeLogoView(using container: UIView) -> UIView {
let view = UIImageView(image: Constant.Image.title)
view.translatesAutoresizingMaskIntoConstraints = false
view.contentMode = .scaleAspectFit
container.addSubview(view)
return view
}
private func initializeCredentialsView(using container: UIView) -> UIView {
let view = CredentialsViewIPAD(with: self.output)
container.addSubview(view)
return view
}
private func initializeUseAppButton(using container: UIView) -> UIView {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(Constant.LocalizedString.button, for: .normal)
button.backgroundColor = Constant.Color.button
button.layer.cornerRadius = 30
button.titleLabel?.textColor = Constant.Color.title
button.titleLabel?.font = Constant.Font.button
button.addTarget(self, action: #selector(self.didTapUseAppButton), for: .touchUpInside)
container.addSubview(button)
return button
}
@objc func didTapUseAppButton() {
self.output.didTapSkip()
}
}