322 lines
14 KiB
Swift
322 lines
14 KiB
Swift
//
|
|
// CreateWalletViewController.swift
|
|
// Malinka
|
|
//
|
|
// Created by Nut.Tech on 27.07.2022.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
final class CreateWalletViewController: UIViewController {
|
|
|
|
// MARK: - Constants
|
|
|
|
private enum Geometry {
|
|
enum Common {
|
|
static let left: CGFloat = 12
|
|
static let cornerRadius: CGFloat = 2
|
|
static let standartFontSize: CGFloat = 12
|
|
static let mediumFontSize: CGFloat = 14
|
|
static let titleFontSize: CGFloat = 24
|
|
static let inputLength = 12
|
|
}
|
|
enum Header {
|
|
static let commonHeight: CGFloat = 4
|
|
static let indicatorsInterval: CGFloat = 4
|
|
static let indicatorTop: CGFloat = 10
|
|
static let stepTextTop: CGFloat = 16
|
|
static let stepTextHeight: CGFloat = 14
|
|
static let stepTitleTop: CGFloat = 4
|
|
static let stepTitleHeight: CGFloat = 29
|
|
}
|
|
enum InputStack {
|
|
static let labelTop: CGFloat = 30
|
|
static let stackTop: CGFloat = 15
|
|
static let stackHeight: CGFloat = 20
|
|
}
|
|
enum AttentionView {
|
|
static let top: CGFloat = 25
|
|
static let cornerRadius: CGFloat = 8
|
|
}
|
|
enum ErrorLabel {
|
|
static let top: CGFloat = 8
|
|
}
|
|
enum SubmitButton {
|
|
static let top: CGFloat = 25
|
|
static let height: CGFloat = 48
|
|
}
|
|
}
|
|
|
|
// MARK: - Properties
|
|
|
|
private var isPresented: Bool {
|
|
if let navVc = self.navigationController {
|
|
return navVc.viewControllers.firstIndex(of: self) == 0
|
|
} else {
|
|
return self.presentingViewController != nil
|
|
}
|
|
}
|
|
|
|
private lazy var attentionView: UIView = {
|
|
let attentionView = CommonViewAlert()
|
|
attentionView.translatesAutoresizingMaskIntoConstraints = false
|
|
attentionView.containerView?.backgroundColor = Asset.marble.color
|
|
attentionView.textLbl.text = L10n.Account.Onboarding.limitationsWarning
|
|
attentionView.textLbl.font = FontFamily.GolosUI.regular.font(size: Geometry.Common.standartFontSize)
|
|
attentionView.textLbl.textColor = Asset.dark.color
|
|
attentionView.imgView.image = Asset.appartmentsWarning.image
|
|
attentionView.imgView.tintColor = Asset.dark.color
|
|
attentionView.clipsToBounds = true
|
|
attentionView.layer.cornerRadius = Geometry.AttentionView.cornerRadius
|
|
return attentionView
|
|
}()
|
|
|
|
private lazy var submitButton: UIButton = {
|
|
let action = CommonMenuAction { [weak self] _ in
|
|
self?.onSubmit()
|
|
}
|
|
let button = CommonButtonAction(action: action, height: Geometry.SubmitButton.height)
|
|
button.lzTitle = L10n.Common.Button.continue
|
|
button.isEnabled = false
|
|
button.translatesAutoresizingMaskIntoConstraints = false
|
|
return button
|
|
}()
|
|
|
|
private lazy var inputStack: WalletTextInputView = {
|
|
let inputView = WalletTextInputView(length: Geometry.Common.inputLength, delegate: self)
|
|
inputView.translatesAutoresizingMaskIntoConstraints = false
|
|
return inputView
|
|
}()
|
|
|
|
private lazy var stepTitle: UILabel = {
|
|
let stepTitle = UILabel()
|
|
stepTitle.translatesAutoresizingMaskIntoConstraints = false
|
|
stepTitle.font = FontFamily.GolosUI.bold.font(size: Geometry.Common.titleFontSize)
|
|
stepTitle.textColor = Asset.dark.color
|
|
stepTitle.text = L10n.Account.Onboarding.Step1.title
|
|
return stepTitle
|
|
}()
|
|
|
|
private lazy var errorLabel: UILabel = {
|
|
let errorLabel = UILabel()
|
|
errorLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
errorLabel.font = FontFamily.GolosUI.regular.font(size: Geometry.Common.mediumFontSize)
|
|
errorLabel.textColor = Asset.liSTRedEnd.color
|
|
return errorLabel
|
|
}()
|
|
|
|
private var walletIdentifier: String?
|
|
private var errorLabelHeight: NSLayoutConstraint?
|
|
|
|
private let caseWalletService: CaseWalletService
|
|
|
|
// MARK: - Init
|
|
|
|
init(with service: CaseWalletService) {
|
|
self.caseWalletService = service
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
// MARK: - Lifecycle
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
self.title = L10n.Account.Onboarding.freeTitle
|
|
self.view.backgroundColor = .white
|
|
self.overrideUserInterfaceStyle = .light
|
|
self.setupNavigationBar()
|
|
self.setupHeader()
|
|
self.setupAttetionView()
|
|
self.setupTextInputStackView()
|
|
self.setupErrorLabel()
|
|
self.setupSubmitButton()
|
|
|
|
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
|
|
tap.cancelsTouchesInView = false
|
|
view.addGestureRecognizer(tap)
|
|
}
|
|
|
|
private func setupHeader() {
|
|
let stepIndicatorFull = UIView()
|
|
stepIndicatorFull.translatesAutoresizingMaskIntoConstraints = false
|
|
stepIndicatorFull.backgroundColor = Asset.deepWater.color
|
|
stepIndicatorFull.clipsToBounds = true
|
|
stepIndicatorFull.layer.cornerRadius = Geometry.Common.cornerRadius
|
|
|
|
let stepIndicatorEmpty = UIView()
|
|
stepIndicatorEmpty.translatesAutoresizingMaskIntoConstraints = false
|
|
stepIndicatorEmpty.backgroundColor = Asset.disabled.color
|
|
stepIndicatorEmpty.clipsToBounds = true
|
|
stepIndicatorEmpty.layer.cornerRadius = Geometry.Common.cornerRadius
|
|
|
|
let stepText = UILabel()
|
|
stepText.translatesAutoresizingMaskIntoConstraints = false
|
|
stepText.font = FontFamily.GolosUI.bold.font(size: Geometry.Common.standartFontSize)
|
|
stepText.textColor = Asset.lightGray.color
|
|
stepText.text = L10n.Account.Onboarding.Step1.step
|
|
|
|
self.view.addSubview(stepIndicatorFull)
|
|
self.view.addSubview(stepIndicatorEmpty)
|
|
self.view.addSubview(stepText)
|
|
self.view.addSubview(self.stepTitle)
|
|
|
|
NSLayoutConstraint.activate([
|
|
stepIndicatorFull.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: Geometry.Header.indicatorTop),
|
|
stepIndicatorFull.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
stepIndicatorFull.heightAnchor.constraint(equalToConstant: Geometry.Header.commonHeight),
|
|
stepIndicatorFull.rightAnchor.constraint(equalTo: stepIndicatorEmpty.leftAnchor, constant: -Geometry.Header.indicatorsInterval),
|
|
|
|
stepIndicatorEmpty.lastBaselineAnchor.constraint(equalTo: stepIndicatorFull.lastBaselineAnchor),
|
|
stepIndicatorEmpty.heightAnchor.constraint(equalToConstant: Geometry.Header.commonHeight),
|
|
stepIndicatorEmpty.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -Geometry.Common.left),
|
|
stepIndicatorEmpty.widthAnchor.constraint(equalTo: stepIndicatorFull.widthAnchor),
|
|
|
|
stepText.topAnchor.constraint(equalTo: stepIndicatorFull.bottomAnchor, constant: Geometry.Header.stepTextTop),
|
|
stepText.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
stepText.heightAnchor.constraint(equalToConstant: Geometry.Header.stepTextHeight),
|
|
|
|
self.stepTitle.topAnchor.constraint(equalTo: stepText.bottomAnchor, constant: Geometry.Header.stepTitleTop),
|
|
self.stepTitle.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
self.stepTitle.heightAnchor.constraint(equalToConstant: Geometry.Header.stepTitleHeight)
|
|
])
|
|
}
|
|
|
|
private func setupTextInputStackView() {
|
|
let inputInvitationLabel = UILabel()
|
|
inputInvitationLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
inputInvitationLabel.textColor = Asset.dark.color
|
|
inputInvitationLabel.font = FontFamily.GolosUI.medium.font(size: Geometry.Common.mediumFontSize)
|
|
inputInvitationLabel.text = L10n.Account.Onboarding.Step1.typeAnyInfo
|
|
inputInvitationLabel.numberOfLines = 0
|
|
self.view.addSubview(inputInvitationLabel)
|
|
self.view.addSubview(self.inputStack)
|
|
|
|
NSLayoutConstraint.activate([
|
|
inputInvitationLabel.topAnchor.constraint(equalTo: self.attentionView.bottomAnchor, constant: Geometry.InputStack.labelTop),
|
|
inputInvitationLabel.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
inputInvitationLabel.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -Geometry.Common.left),
|
|
|
|
self.inputStack.topAnchor.constraint(equalTo: inputInvitationLabel.bottomAnchor, constant: Geometry.InputStack.stackTop),
|
|
self.inputStack.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
self.inputStack.rightAnchor.constraint(lessThanOrEqualTo: self.view.rightAnchor, constant: -Geometry.Common.left),
|
|
self.inputStack.heightAnchor.constraint(equalToConstant: Geometry.InputStack.stackHeight)
|
|
])
|
|
}
|
|
|
|
private func setupAttetionView() {
|
|
self.view.addSubview(self.attentionView)
|
|
|
|
NSLayoutConstraint.activate([
|
|
self.attentionView.topAnchor.constraint(equalTo: self.stepTitle.bottomAnchor, constant: Geometry.AttentionView.top),
|
|
self.attentionView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
self.attentionView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -Geometry.Common.left)
|
|
])
|
|
}
|
|
|
|
private func setupErrorLabel() {
|
|
self.view.addSubview(self.errorLabel)
|
|
|
|
NSLayoutConstraint.activate([
|
|
self.errorLabel.topAnchor.constraint(equalTo: self.inputStack.bottomAnchor, constant: Geometry.ErrorLabel.top),
|
|
self.errorLabel.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
self.errorLabel.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -Geometry.Common.left)
|
|
])
|
|
}
|
|
|
|
private func setupSubmitButton() {
|
|
self.view.addSubview(self.submitButton)
|
|
|
|
NSLayoutConstraint.activate([
|
|
self.submitButton.topAnchor.constraint(equalTo: self.errorLabel.bottomAnchor, constant: Geometry.SubmitButton.top),
|
|
self.submitButton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: Geometry.Common.left),
|
|
self.submitButton.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -Geometry.Common.left)
|
|
])
|
|
}
|
|
|
|
private func setupNavigationBar() {
|
|
self.navigationItem.leftBarButtonItem = .back { [weak self] in
|
|
if self?.isPresented ?? false {
|
|
self?.navigationController?.dismiss(animated: true)
|
|
} else {
|
|
self?.navigationController?.popViewController(animated: true)
|
|
}
|
|
}
|
|
|
|
if self.isPresented {
|
|
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
|
|
self.navigationController?.navigationBar.shadowImage = UIImage()
|
|
self.navigationController?.navigationBar.isTranslucent = true
|
|
}
|
|
}
|
|
|
|
@objc private func dismissKeyboard() {
|
|
self.inputStack.hideKeyboard()
|
|
}
|
|
|
|
private func onSubmit() {
|
|
|
|
guard let name = self.walletIdentifier else {
|
|
self.onErrorAccountAlreadyExists(message: "account.create.name.empty.error".localized)
|
|
return
|
|
}
|
|
|
|
self.submitButton.isEnabled = false
|
|
|
|
Task {
|
|
do {
|
|
let controller = try await self.caseWalletService.createPrivateKeyController(for: name,
|
|
manualCreate: !self.isPresented)
|
|
DispatchQueue.main.async {
|
|
self.navigationController?.pushViewController(controller, animated: true)
|
|
}
|
|
} catch CaseWalletService.ServiceError.exists {
|
|
self.onErrorAccountAlreadyExists(message: "account.create.name.exists.error".localized)
|
|
} catch CaseWalletService.ServiceError.system {
|
|
self.onErrorAlertWindow(message: "account.create.name.reserve.error".localized)
|
|
}
|
|
|
|
DispatchQueue.main.async {
|
|
self.submitButton.isEnabled = true
|
|
}
|
|
}
|
|
}
|
|
|
|
private func onErrorAccountAlreadyExists(message: String) {
|
|
guard !message.isEmpty || !(self.errorLabel.text?.isEmpty ?? true) else { return }
|
|
self.errorLabel.text = message
|
|
UIView.animate(withDuration: 0.3) {
|
|
self.view.layoutIfNeeded()
|
|
}
|
|
self.submitButton.isEnabled = false
|
|
}
|
|
|
|
private func onErrorAlertWindow(message: String) {
|
|
guard !message.isEmpty || !(self.errorLabel.text?.isEmpty ?? true) else { return }
|
|
self.errorLabel.text = ""
|
|
UIView.animate(withDuration: 0.3) {
|
|
self.view.layoutIfNeeded()
|
|
}
|
|
Alert.error(text: message)
|
|
self.submitButton.isEnabled = false
|
|
}
|
|
}
|
|
|
|
extension CreateWalletViewController: WalletTextInputViewDelegate {
|
|
|
|
func walletUpdateTextOutput(wallet: WalletTextInputView, text: String?) {
|
|
|
|
guard text != nil else {
|
|
self.onErrorAccountAlreadyExists(message: "")
|
|
self.submitButton.isEnabled = false
|
|
return
|
|
}
|
|
|
|
self.walletIdentifier = text
|
|
self.submitButton.isEnabled = true
|
|
}
|
|
}
|