Files
raspberry/iOS/Wallet/Sources/Account/Controller/AccountControllerPin.swift
2022-05-27 20:21:01 +03:00

297 lines
12 KiB
Swift

//
// AccountControllerPin.swift
// PayCash
//
// Created by Saveliy Stavitsky on 12/4/20.
// Copyright © 2020 List. All rights reserved.
//
import UIKit
class AccountControllerPin: UIViewController {
enum AccountControllerPinType {
case old
case new
case protectionNew
}
@IBOutlet weak var logoTopConstraint: NSLayoutConstraint!
@IBOutlet var headerTitleLabel: UILabel!
@IBOutlet var headerDescriptionLabel: UILabel!
@IBOutlet var pinStackView: UIStackView!
@IBOutlet private weak var submitBtn: UIButton!
@IBOutlet private weak var haveWalletButton: UIButton!
@IBOutlet var leftButton: UIButton!
@IBOutlet var errorTopConstraint: NSLayoutConstraint!
@IBOutlet var errorTitleLabel: UILabel!
@IBOutlet var errorTryLabel: UILabel!
@IBOutlet var timeoutTitleLabel: UILabel!
@IBOutlet var timeoutLabel: UILabel!
@IBOutlet var timeoutView: UIView!
@IBOutlet private var warningView: CommonViewWarning!
var type: AccountControllerPinType = .new
var pinValidate: ((String) -> Bool)?
var faceSubmit: (() -> Void)?
var showBackButton = true
var repeatPin: [Int] = []
var pin: [Int] = [Int]() {
didSet {
for stack in (pinStackView.arrangedSubviews as? [UIStackView]) ?? [] {
(stack.arrangedSubviews.first as? UIImageView)?.image = Asset.accountPinStarEmpty.image
}
errorTitleLabel.isHidden = true
for index in pin.indices where index < pinStackView.arrangedSubviews.count {
if let stack = pinStackView.arrangedSubviews[index] as? UIStackView {
(stack.arrangedSubviews.first as? UIImageView)?.image = Asset.accountPinStarFill.image
}
}
if repeatPin.count == 4 && pin.count == 4 && repeatPin != pin {
for stack in (pinStackView.arrangedSubviews as? [UIStackView]) ?? [] {
(stack.arrangedSubviews.first as? UIImageView)?.image = Asset.accountPinStarError.image
}
errorTitleLabel.isHidden = false
}
}
}
@IBOutlet var numbersStackView: UIStackView!
@IBOutlet var numberButtons: [UIButton]!
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
print(UIApplication.shared.windows.first?.safeAreaInsets.top)
// if (UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0) < 50 {
// logoTopConstraint.constant = 0
// }
timeoutTitleLabel.textAlignment = .center
warningView.makeCritical()
print(UIScreen.main.bounds.height)
numbersStackView.spacing = UIScreen.main.bounds.height < 570 ? 8 : 24
timer = delayed(1, repeats: true) { [weak self] in
guard let self = self, self.pinValidate != nil else { return }
// let timeout = 3 * 60 - (Account.Service.Authorize.shared.lastPinTryTimeout() ?? 0)
// let seconds = timeout % 60 < 10 ? "0\(timeout % 60)" : "\(timeout % 60)"
// self.timeoutLabel.text = "\(timeout / 60):\(seconds)"
self.errorTryLabel.text = L10n.Account.Pin.tryCount(5 - Account.Service.Authorize.shared.getPinTries().count)
if Account.Service.Authorize.shared.getPinTries().count >= 5 {
// if Account.Service.Authorize.shared.lastPinTryTimeout()! < 3 * 60 {
self.timeoutView.isHidden = false
Accounts().removeAll()
Accounts().removePassword()
// } else {
// Account.Service.Authorize.shared.clearPinTries()
// self.timeoutView.isHidden = true
// }
} else {
self.timeoutView.isHidden = true
}
}
timer?.fire()
if pinValidate != nil {
if faceSubmit != nil {
title = ""//L10n.Account.Authorize.title
headerTitleLabel.text = L10n.Account.Pin.Enter.title
logoTopConstraint.constant = -40
} else {
title = ""//L10n.Account.Password.title
headerTitleLabel.text = type == .new ? L10n.Account.Pin.Enter.titleNew : L10n.Account.Pin.Enter.titleOld
logoTopConstraint.constant = -40
}
if showBackButton {
navigationItem.leftBarButtonItem = .back { [unowned self] in
timer?.invalidate()
timer = nil
navigationController?.dismiss(animated: true)
}
}
// Clear the background image.
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
// Clear the shadow image.
navigationController?.navigationBar.shadowImage = UIImage()
// Ensure the navigation bar is translucent.
navigationController?.navigationBar.isTranslucent = true
// navigationController?.navigationBar.layer.shadowColor = Asset.lightGray.color.cgColor
// navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
// navigationController?.navigationBar.layer.shadowRadius = 4.0
// navigationController?.navigationBar.layer.shadowOpacity = 1.0
// navigationController?.navigationBar.layer.masksToBounds = false
leftButton.isHidden = !Accounts().isBiometricksEnabled || faceSubmit == nil
leftButton.lzTitle = ""
leftButton.setImage(Asset.accountPinFaceId.image, for: .normal)
headerTitleLabel.font = .font(style: .regular, size: 14)
headerTitleLabel.textColor = Asset.textGranite.color.withAlphaComponent(0.7)
headerDescriptionLabel.isHidden = true
} else {
headerTitleLabel.font = .font(style: .bold, size: 24)
headerTitleLabel.textColor = Asset.textGranite.color
headerDescriptionLabel.isHidden = false
leftButton.lzTitle = L10n.Common.Button.back
if repeatPin.count == 0 {
leftButton.isHidden = true
} else {
leftButton.isHidden = false
headerTitleLabel.text = L10n.Account.Pin.Repeat.title
}
}
headerDescriptionLabel.font = .font(style: .regular, size: 14)
for button in numberButtons {
button.titleLabel?.font = .font(style: .regular, size: 28)
button.setTitleColor(Asset.textGranite.color, for: .normal)
// button.setBackgroundImage(Asset.accountPinNumberBackground.image, for: .highlighted)
}
leftButton.titleLabel?.font = .font(style: .medium, size: 18)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.callBiometricsSignInIfEnabled()
}
private func callBiometricsSignInIfEnabled() {
if Accounts().isBiometricksEnabled {
self.faceSubmit?()
}
}
@IBAction private func onSubmit(_ : AnyObject?) {
}
@IBAction private func onUnderstand(_ : AnyObject?) {
Account.Service.Authorize.shared.clearPinTries()
self.dismiss(animated: true, completion: nil)
}
@IBAction func haveWalletPrssed(_: AnyObject?) {
Alert.hint(text: L10n.Account.Onboarding.Password.hint)
}
@IBAction func numberPressed(_ sender: Any) {
if let value = (sender as? UIButton)?.tag {
switch value {
case -4:
leftButton.isHidden = faceSubmit == nil
if faceSubmit == nil {
headerTitleLabel.text = L10n.Account.Pin.Enter.title
}
repeatPin = []
pin = []
faceSubmit?()
case -1:
pin = pin.dropLast()
default:
if pin.count < 4 {
pin += [value]
} else {
return
}
}
print(pin)
if let pinValidate = pinValidate, pin.count == 4 {
let password = "\(pin[0])\(pin[1])\(pin[2])\(pin[3])"
if pinValidate(password) {
} else {
for stack in (pinStackView.arrangedSubviews as? [UIStackView]) ?? [] {
(stack.arrangedSubviews.first as? UIImageView)?.image = Asset.accountPinStarError.image
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
self?.pin = []
self?.timer?.fire()
self?.errorTryLabel.text = L10n.Account.Pin.tryCount(5 - Account.Service.Authorize.shared.getPinTries().count)
self?.errorTryLabel.isHidden = false
self?.errorTitleLabel.isHidden = false
self?.warningView.isHidden = false
}
}
} else {
if repeatPin.count == 0 && pin.count == 4 {
leftButton.isHidden = false
headerTitleLabel.text = L10n.Account.Pin.Repeat.title
self.repeatPin = pin
pin = []
} else if repeatPin.count == 4 && pin.count == 4 && repeatPin == pin {
Account.Service.Authorize.shared.password = "\(pin[0])\(pin[1])\(pin[2])\(pin[3])"
successShow()
}
}
}
}
func successShow() {
let password = "\(pin[0])\(pin[1])\(pin[2])\(pin[3])"
UserDefaults.standard.setValue(true, forKey: "isPinPwdMode")
Accounts().update(password: password)
Popup.show(
title: L10n.Account.Onboarding.Success.title,
description: L10n.Account.Onboarding.Success.description,
submit: Accounts().isBiometricksAvailable ? L10n.Account.Onboarding.Success.submit : L10n.Common.Button.ok,
in: self, { ctrl in
ctrl.dismiss(animated: true)
guard Accounts().isBiometricksAvailable else {
self.dismiss(animated: true)
return
}
let submit: (UIViewController) -> Void = { ctrl in
ctrl.dismiss(animated: true)
Accounts().checkBiometricks { (success) in
if success {
Accounts().isBiometricksEnabled = true
Alert.success()
self.dismiss(animated: true)
} else {
Alert.error(text: L10n.Account.Onboarding.Bimetricks.error)
self.dismiss(animated: true)
}
}
}
let result: () -> Void = { self.dismiss(animated: true) }
if Accounts().isFaceIdAvailable {
Popup.show(
title: L10n.Account.Onboarding.FaceId.title,
image: Asset.commonFaceId.image,
description: L10n.Account.Onboarding.FaceId.description,
submit: L10n.Account.Onboarding.FaceId.submit,
in: self,
submit,
result
)
} else {
Popup.show(
title: L10n.Account.Onboarding.TouchId.title,
image: Asset.commonTouchId.image,
description: L10n.Account.Onboarding.TouchId.description,
submit: L10n.Account.Onboarding.TouchId.submit,
in: self,
submit,
result
)
}
}
) { self.dismiss(animated: true) }
}
}