Files
2023-01-27 11:23:51 +03:00

816 lines
38 KiB
Swift

//
// P2PControllerOrder.swift
// Wallet
//
// Created by Igor Danich on 31.08.2020.
// Copyright © 2020 List. All rights reserved.
//
import UIKit
import RealmSwift
final class P2PControllerOrder: UIViewController {
@IBOutlet private weak var contentTypeView: CardView!
@IBOutlet private weak var tokenLbl: UILabel!
@IBOutlet private weak var tokenView: CommonViewCard!
@IBOutlet private weak var rateLbl: UILabel!
@IBOutlet private weak var cardView: CommonViewCard!
@IBOutlet private weak var paymentSystemView: CardView!
@IBOutlet private weak var tokenGetLbl: UILabel!
@IBOutlet private weak var tokenGetView: CardView!
@IBOutlet private weak var blockchainView: CardView!
@IBOutlet private weak var rateToken1View: CommonTextField!
@IBOutlet private weak var rateToken2View: CommonTextField!
@IBOutlet private weak var amountTxtFld: CommonTextField!
@IBOutlet private weak var leftAmountLbl: UILabel!
@IBOutlet private weak var amountToken2View: CommonTextField!
@IBOutlet private weak var rightAmountLbl: UILabel!
@IBOutlet private weak var limitLbl: UILabel!
@IBOutlet private weak var limitMin: CommonTextField!
@IBOutlet private weak var limitMax: CommonTextField!
@IBOutlet private weak var limitMinSubLbl: UILabel!
@IBOutlet private weak var limitMaxSubLbl: UILabel!
@IBOutlet private weak var linkTxtFld: CommonTextField!
@IBOutlet private weak var vcardNumberTxtFld: CommonTextField!
@IBOutlet private weak var vcardNameTxtFld: CommonTextField!
@IBOutlet private weak var vcardExpirationTxtFld: CommonTextField!
@IBOutlet private weak var vcardCVVTxtFld: CommonTextField!
@IBOutlet private weak var countryView: CardView!
@IBOutlet private weak var cityView: CardView!
@IBOutlet private weak var bankView: CardView!
@IBOutlet private weak var accountTxtFld: CommonTextField!
@IBOutlet private weak var memoTxtFld: CommonTextField!
@IBOutlet private weak var submitBtn: UIButton!
@IBOutlet private weak var maxBtn: CommonButtonAction!
var service: P2P.Service.Order!
// swiftlint:disable function_body_length
override func viewDidLoad() {
super.viewDidLoad()
title = service.order == nil ? L10n.P2p.Order.title : L10n.P2p.Order.editTitle
self.submitBtn.lzTitle = service.order.isExist ? L10n.P2p.Dashboard.Order.Action.MoreEdit.Confirm.confirm : L10n.P2p.Dashboard.newOrder
navigationItem.leftBarButtonItem = service.order == nil ? .pop(self) : .back({ [weak self] in
guard let self = self else { return }
Popup.show(
title: L10n.P2p.Dashboard.Order.Action.MoreEdit.Back.title,
views: [
.label(
text: L10n.P2p.Dashboard.Order.Action.MoreEdit.Back.description
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
)
],
buttons: [
.button(title: L10n.P2p.Dashboard.Order.Action.MoreEdit.Back.confirmResume, action: { }),
.button(style: .secondary, title: L10n.P2p.Dashboard.Order.Action.MoreEdit.Back.confirmPause, action: { })
],
buttonsActions: [
{ _ in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
self.service.order?.resume(privateKey: $0) { (error) in
Loader.hide()
Popup.hide()
Alert.notify(error)
self.navigationController?.popViewController(animated: true)
}
}
},
{ _ in
Popup.hide()
self.navigationController?.popViewController(animated: true)
}
],
in: self
)
})
contentTypeView.rightImageView.image = Asset.commonMenuHorizontal.image
contentTypeView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
Popup.show(content: OrderTypeSelectionPopupViewController(kind: service.kind) {
service.contentType = $0
}, contentScrollIsEnabled: false)
}
updateTokenSelector()
paymentSystemView.imageView.image = Asset.p2pPaymentSystem.image
paymentSystemView.rightImageView.image = Asset.commonMenuHorizontal.image
paymentSystemView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
let vc = FilterSelectViewController()
vc.clearButtonTitle = L10n.P2p.Filter.clear
vc.selectionType = .radio
vc.title = L10n.P2p.Order.PaymentSystem.title
vc.modelsArray = service.p2pListsService.paymentSystems
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: "") })
service.paymentSystem.flatMap { vc.selectedModels.insert(FilterItem(id: $0.id, title: $0.title)) }
vc.applyButtonAction = {
service.paymentSystem = $0.map { (id: $0.id, title: $0.title, description: "") }.first
self?.navigationController?.popViewController(animated: true)
}
self?.navigationController?.pushViewController(vc, animated: true)
}
tokenGetView.rightImageView.image = Asset.commonMenuHorizontal.image
tokenGetView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
let vc = FilterSelectViewController()
vc.clearButtonTitle = L10n.P2p.Filter.clear
vc.selectionType = .radio
vc.title = service.contentType == .crypto
? L10n.P2p.Order.TokenCryptoGet.title : L10n.P2p.Order.TokenGet.title
if service.contentType == .emoney {
if let paymentSystemId = service.paymentSystem?.id {
vc.modelsArray = service.p2pListsService.paymentSystems
.where({ $0.id == paymentSystemId }).first?.currencies
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: $0.descriptn) }) ?? []
} else {
vc.modelsArray = []
}
} else {
let currencyType: P2PCurrencyType = service.contentType == .crypto ? .crypto : .fiat
vc.modelsArray = service.p2pListsService.currencies
.where({ $0.type == currencyType })
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: $0.descriptn) })
}
service.tokenGet.flatMap { vc.selectedModels.insert(FilterItem(id: $0.id, title: $0.title, subtitle: $0.description)) }
vc.applyButtonAction = {
service.tokenGet = $0.map({ (id: $0.id, title: $0.title, description: $0.subtitle ?? "") }).first
self?.navigationController?.popViewController(animated: true)
}
self?.navigationController?.pushViewController(vc, animated: true)
}
if service.order == nil && (service.contentType == .card || service.contentType == .url ||
service.contentType == .cash || service.contentType == .vcard) {
if let currency = service.p2pListsService.currencies.first(where: { $0.name == service.token?.symbol.uppercased().replacingOccurrences(of: "CASH", with: "") ?? "" && $0.type == .fiat }) {
service.tokenGet = (id: currency.id, title: currency.name, description: currency.descriptn ?? "")
}
}
blockchainView.imageView.image = Asset.p2pBlockchain.image
blockchainView.rightImageView.image = Asset.commonMenuHorizontal.image
blockchainView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
let vc = FilterSelectViewController()
vc.clearButtonTitle = L10n.P2p.Filter.clear
vc.selectionType = .radio
vc.title = L10n.P2p.Order.Blockchain.title
vc.modelsArray = service.p2pListsService.currencies
.where({ $0.id == service.tokenGet?.id ?? -1 }).first?.blockchains
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: $0.descriptn) }) ?? []
service.blockchain.flatMap { vc.selectedModels.insert(FilterItem(id: $0.id, title: $0.title, subtitle: $0.description)) }
vc.applyButtonAction = {
service.blockchain = $0.map({ (id: $0.id, title: $0.title, description: $0.subtitle ?? "") }).first
self?.navigationController?.popViewController(animated: true)
}
self?.navigationController?.pushViewController(vc, animated: true)
}
for field in [amountTxtFld, amountToken2View, limitMin, limitMax, rateToken1View, rateToken2View] {
field?.keyboardType = .decimalPad
field?.precision = service.token1Precision
}
rateToken1View.precision = 10
rateToken2View.precision = 10
for field in [vcardNumberTxtFld, vcardCVVTxtFld, vcardExpirationTxtFld] {
field?.keyboardType = .numberPad
}
countryView.imageView.image = Asset.p2pCountry.image
countryView.rightImageView.image = Asset.commonMenuHorizontal.image
countryView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
let vc = FilterSelectViewController()
vc.clearButtonTitle = L10n.P2p.Filter.clear
vc.selectionType = .radio
vc.title = L10n.P2p.Order.Country.topTitle
vc.modelsArray = service.p2pListsService.countries
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: nil) })
service.country.flatMap { vc.selectedModels.insert(FilterItem(id: $0.id, title: $0.title)) }
vc.otherId = 1
vc.applyButtonAction = {
service.country = $0.map({ (id: $0.id, title: $0.title, description: "") }).first
self?.navigationController?.popViewController(animated: true)
}
self?.navigationController?.pushViewController(vc, animated: true)
}
cityView.imageView.image = Asset.p2pCity.image
cityView.rightImageView.image = Asset.commonMenuHorizontal.image
cityView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
let vc = FilterSelectViewController()
vc.clearButtonTitle = L10n.P2p.Filter.clear
vc.selectionType = .radio
vc.title = L10n.P2p.Order.City.topTitle
vc.modelsArray = service.p2pListsService.cities
.where({ $0.country.id == (service.country?.id ?? 1) || $0.id == 1 })
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: nil) })
service.city.flatMap { vc.selectedModels.insert(FilterItem(id: $0.id, title: $0.title)) }
vc.otherId = 1
vc.applyButtonAction = {
service.city = $0.map({ (id: $0.id, title: $0.title, description: "") }).first
self?.navigationController?.popViewController(animated: true)
}
self?.navigationController?.pushViewController(vc, animated: true)
}
bankView.imageView.image = Asset.p2pBank.image
bankView.rightImageView.image = Asset.commonMenuHorizontal.image
bankView.action = { [weak self] in
guard let service = self?.service else { return }
self?.view.endEditing(true)
let vc = FilterSelectViewController()
vc.clearButtonTitle = L10n.P2p.Filter.clear
vc.selectionType = service.contentType == .card ? .checkBox : .radio
vc.title = L10n.P2p.Order.Bank.topTitle
vc.modelsArray = service.p2pListsService.banks
.where({ $0.country.id == (service.country?.id ?? 1) || $0.id == 1 })
.map({ FilterItem(id: $0.id, title: $0.name, subtitle: nil) })
// .where({ $0.id == service.country?.id ?? -1 }).first?.banks
// .map({ FilterItem(id: $0.id, title: $0.name, subtitle: nil) }) ?? []
service.bank.forEach { vc.selectedModels.insert(FilterItem(id: $0.id, title: $0.title)) }
vc.otherId = 1
vc.applyButtonAction = {
service.bank = $0.map({ (id: $0.id, title: $0.title, description: "") })
self?.navigationController?.popViewController(animated: true)
}
self?.navigationController?.pushViewController(vc, animated: true)
}
service.didUpdate = { [weak self] in self?.update(animated: true) }
service.didReload = { [weak self] in
guard let self else { return }
// rateToken1View.value = service.rateToken1
// rateToken2View.value = service.rateToken2
// amountTxtFld.value = service.amount
// amountToken2View.value = service.amountToken2
self.limitMin.value = self.service.limitMin
self.limitMax.value = self.service.limitMax
self.linkTxtFld.value = self.service.link
self.vcardNumberTxtFld.value = self.service.vcardNumber
self.vcardNameTxtFld.value = self.service.vcardName
self.vcardExpirationTxtFld.value = self.service.vcardExpiration
self.vcardCVVTxtFld.value = self.service.vcardCVV
self.accountTxtFld.value = self.service.account
// countryTxtFld.value = service.country?.title ?? ""
// bankTxtFld.value = service.bank?.title ?? ""
}
update(animated: false)
let btn = UIButton(type: .custom)
btn.setImage(Asset.p2pOrderMaxButton.image, for: .normal)
btn.frame.size = Asset.p2pOrderMaxButton.image.size
btn.addTarget(self, action: #selector(onMax), for: .touchUpInside)
amountTxtFld.accessoryView = btn
Notification.subscribe(name: .didUpdateBalances) { [weak self] _ in
self?.updateTokenSelector()
}
}
// swiftlint:enable function_body_length
private func updateTokenSelector() {
tokenView.action = service.order == nil
? .cards(tokens: P2P.Service.tokens, selected: service.token) { [weak self] menu in
guard let self else { return }
self.view.endEditing(true)
self.service.token = P2P.Service.tokens.object(menu: menu)
self.update(animated: true) }
: .select(icon: Asset.commonLock.image, kind: .cards,
title: L10n.Common.Card.Token.title,
empty: .cardsTokensEmpty(),
collection: P2P.Service.tokens.map({ $0.toMenu() }),
selected: service.token?.toMenu(),
completion: { _ in })
tokenView.isUserInteractionEnabled = service.order == nil
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in [contentTypeView, paymentSystemView, tokenGetView,
blockchainView, countryView, cityView, bankView] {
view?.makeShadowStyle()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationGlobalHack = self.navigationController
navigationController?.navigationBar.clear()
navigationController?.setNavigationBarHidden(false, animated: true)
if service.card == nil {
service.card = Cards.shared.default
}
Accounts().isLocked = true
Wallet.Service.Tokens.shared.balances.fetch()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.navigationBar.reset()
Accounts().isLocked = false
navigationGlobalHack = nil
}
// swiftlint:disable cyclomatic_complexity
private func update(animated: Bool) {
contentTypeView.titleLabel.lzText = "p2p.order.type.\(service.contentType.rawValue.lowercased()).title".localized
contentTypeView.descriptionLabel.lzText = "p2p.order.type.\(service.contentType.rawValue.lowercased()).description".localized
contentTypeView.imageView.image = UIImage(named: "p2p-order-type-\(service.contentType.rawValue.lowercased())")
tokenLbl.attributedText = (service.kind == .sell ? L10n.P2p.Order.Token.Title.sell : L10n.P2p.Order.Token.Title.buy)
.attributed(style: .medium, size: 16, color: Asset.textGranite.color)
tokenGetView.imageView.image = service.contentType == .crypto
? UIImage(named: "p2p-order-type-\(service.contentType.rawValue.lowercased())")
: Asset.p2pCurrencyGet.image
cardView.superview?.superview?.isHidden = service.kind != .sell || service.contentType != .card
cardView.action = .cards(selected: service.card, in: self) { [weak self] menu in
guard let self else { return }
if let card = Cards.shared.collection.filter({ $0.uuid == menu.uuid }).first {
self.dismiss(animated: true)
self.service.card = card
}
}
paymentSystemView.superview?.isHidden = service.contentType != .emoney
if let paymentSystem = service.paymentSystem {
paymentSystemView.descriptionLabel.isHidden = false
paymentSystemView.titleLabel.lzText = L10n.P2p.Order.PaymentSystem.title
paymentSystemView.descriptionLabel.lzText = paymentSystem.title
} else {
paymentSystemView.titleLabel.lzText = L10n.P2p.Order.PaymentSystem.placeholder
paymentSystemView.descriptionLabel.isHidden = true
}
tokenGetView.isHidden = service.contentType == .emoney && service.paymentSystem == nil
tokenGetLbl.isHidden = service.contentType == .emoney && service.paymentSystem == nil
amountToken2View.precision = service.token2Precision
if let tokenGet = service.tokenGet {
tokenGetView.descriptionLabel.isHidden = false
tokenGetView.titleLabel.lzText = tokenGet.title
tokenGetView.descriptionLabel.lzText = tokenGet.description
rateToken1View.superview?.superview?.superview?.superview?.isHidden = false
} else {
tokenGetView.titleLabel.lzText = service.contentType == .crypto
? L10n.P2p.Order.TokenCryptoGet.placeholder : L10n.P2p.Order.TokenGet.placeholder
tokenGetView.descriptionLabel.isHidden = true
rateToken1View.superview?.superview?.superview?.superview?.isHidden = true
}
if service.kind == .buy {
leftAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.sell
rightAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.buy
tokenGetLbl.attributedText = L10n.P2p.Order.TokenGet.Title.buy
.attributed(style: .medium, size: 16, color: Asset.textGranite.color)
} else if service.contentType == .url && service.kind == .sell {
leftAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.buy
rightAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.sellURL
tokenGetLbl.attributedText = L10n.P2p.Order.TokenGet.Title.sellURLHeader
.attributed(style: .medium, size: 16, color: Asset.textGranite.color)
} else {
leftAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.buy
rightAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.sell
tokenGetLbl.attributedText = L10n.P2p.Order.TokenGet.Title.sell
.attributed(style: .medium, size: 16, color: Asset.textGranite.color)
}
if service.token == nil {
rateToken1View.superview?.superview?.superview?.superview?.isHidden = true
}
blockchainView.superview?.isHidden = service.contentType != .crypto || service.tokenGet == nil
if let blockchain = service.blockchain {
blockchainView.descriptionLabel.isHidden = false
blockchainView.titleLabel.lzText = L10n.P2p.Order.Blockchain.title
blockchainView.descriptionLabel.lzText = blockchain.title
} else {
blockchainView.titleLabel.lzText = L10n.P2p.Order.Blockchain.placeholder
blockchainView.descriptionLabel.isHidden = true
}
rateToken1View.lzPlaceholder = service.token?.symbol ?? ""
rateToken1View.lzTitle = service.token?.symbol ?? ""
if !rateToken1View.isFirstResponder {
rateToken1View.value = service.rateToken1
}
rateToken2View.lzPlaceholder = service.tokenGet?.title ?? ""
rateToken2View.lzTitle = service.tokenGet?.title ?? ""
if !rateToken2View.isFirstResponder {
rateToken2View.value = service.rateToken2
}
amountTxtFld.precision = service.token1Precision
amountTxtFld.lzPlaceholder = service.token?.symbol ?? ""
amountTxtFld.lzTitle = service.token?.symbol ?? ""
if !amountTxtFld.isFirstResponder {
if service.amount.precision > service.token1Precision {
service.amount = service.amount.toNormalizedString(precisionMax: service.token1Precision)
}
amountTxtFld.value = service.amount
}
amountToken2View.precision = service.token2Precision
amountToken2View.lzPlaceholder = service.tokenGet?.title ?? ""
amountToken2View.lzTitle = service.tokenGet?.title ?? ""
if !amountToken2View.isFirstResponder {
amountToken2View.value = service.amountToken2
}
limitMin.superview?.superview?.superview?.isHidden = (service.kind == .sell && service.contentType == .url) || (service.kind == .buy && service.contentType == .vcard)
limitLbl.lzText = L10n.P2p.Order.Limits.title(service.token?.symbol ?? "")
limitMin.lzPlaceholder = L10n.P2p.Order.Limits.Min.placeholder("")
limitMin.lzTitle = L10n.P2p.Order.Limits.Min.placeholder(service.token?.symbol ?? "")
limitMax.lzPlaceholder = L10n.P2p.Order.Limits.Max.placeholder("")
limitMax.lzTitle = L10n.P2p.Order.Limits.Max.placeholder(service.token?.symbol ?? "")
limitMinSubLbl.lzText = "\(service.limitMinToken2) \(service.tokenGet?.title ?? "")"
limitMaxSubLbl.lzText = "\(service.limitMaxToken2) \(service.tokenGet?.title ?? "")"
linkTxtFld.superview?.isHidden = service.kind != .sell || service.contentType != .url
vcardNumberTxtFld.superview?.superview?.superview?.isHidden = service.kind != .buy || service.contentType != .vcard
countryView.isHidden = service.contentType != .url && service.contentType != .cash
&& service.contentType != .vcard && !(service.kind == .buy && service.contentType == .card)
if let country = service.country {
countryView.descriptionLabel.isHidden = false
countryView.titleLabel.lzText = L10n.P2p.Order.Country.topTitle
countryView.descriptionLabel.lzText = country.title
} else {
countryView.titleLabel.lzText = L10n.P2p.Order.Country.placeholder
countryView.descriptionLabel.isHidden = true
}
cityView.isHidden = service.contentType != .cash || service.country == nil
if let city = service.city {
cityView.descriptionLabel.isHidden = false
cityView.titleLabel.lzText = L10n.P2p.Order.City.topTitle
cityView.descriptionLabel.lzText = city.title
} else {
cityView.titleLabel.lzText = L10n.P2p.Order.City.placeholder
cityView.descriptionLabel.isHidden = true
}
bankView.isHidden = service.kind != .buy || !(service.contentType == .card || service.contentType == .vcard) || service.country == nil
if !service.bank.isEmpty {
bankView.descriptionLabel.isHidden = false
bankView.titleLabel.lzText = L10n.P2p.Order.Bank.topTitle
bankView.descriptionLabel.lzText = service.bank.map(\.title).joined(separator: ", ")
} else {
bankView.titleLabel.lzText = L10n.P2p.Order.Bank.placeholder
bankView.descriptionLabel.isHidden = true
}
countryView.superview?.isHidden = countryView.isHidden
&& cityView.isHidden
&& bankView.isHidden
&& (vcardNumberTxtFld.superview?.superview?.superview?.isHidden ?? true)
accountTxtFld.superview?.isHidden = service.kind != .sell || !(service.contentType == .emoney || service.contentType == .crypto)
accountTxtFld.lzTitle = service.contentType == .emoney
? L10n.P2p.Order.Account.topTitle : L10n.P2p.Order.Address.topTitle
accountTxtFld.lzPlaceholder = service.contentType == .emoney
? L10n.P2p.Order.Account.placeholder : L10n.P2p.Order.Address.placeholder
// maxBtn.superview?.isHidden = service.kind != .sell || service.contentType != .card
if service.isFast {
limitMin.superview?.superview?.superview?.isHidden = true
limitMin.superview?.superview?.superview?.isHidden = true
}
if !limitMin.isFirstResponder {
limitMin.value = service.limitMin
}
if !limitMax.isFirstResponder {
limitMax.value = service.limitMax
}
if !linkTxtFld.isFirstResponder {
linkTxtFld.value = service.link
}
if !vcardNumberTxtFld.isFirstResponder {
vcardNumberTxtFld.value = Cards.Model.formmated(number: service.vcardNumber)
}
if !vcardNameTxtFld.isFirstResponder {
vcardNameTxtFld.value = service.vcardName
}
if !vcardExpirationTxtFld.isFirstResponder {
vcardExpirationTxtFld.value = service.vcardExpiration
}
if !vcardCVVTxtFld.isFirstResponder {
vcardCVVTxtFld.value = service.vcardCVV
}
if !accountTxtFld.isFirstResponder {
accountTxtFld.value = service.account
}
if !memoTxtFld.isFirstResponder {
memoTxtFld.value = service.memo
}
submitBtn.isEnabled = service.isValid
animated ? UIView.animate(withDuration: Animation.medium) { self.view.layoutIfNeeded() } : view.layoutIfNeeded()
// rateLbl.attributedText = service.rate.attributed(style: .bold, size: 16, color: Asset.textCoal.color)
// amountTxtFld.lzTitle = service.kind == .sell
// ? service.contentType == .card
// ? L10n.P2p.Order.Amount.Sell.Card.title : L10n.P2p.Order.Amount.Sell.Link.title
// : L10n.P2p.Order.Amount.Buy.title
// amountTxtFld.lzPlaceholder = service.kind == .sell
// ? service.contentType == .card
// ? L10n.P2p.Order.Amount.Sell.Card.placeholder : L10n.P2p.Order.Amount.Sell.Link.placeholder
// : L10n.P2p.Order.Amount.Buy.placeholder
amountTxtFld.error = service.amountError
limitMin.error = service.minError
limitMax.error = service.maxError
}
@IBAction func onMax(_: AnyObject?) {
service.amount = service.maxValue
amountTxtFld.value = service.amount
}
@IBAction func onQR(_ btn: AnyObject?) {
view.endEditing(true)
guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else {
let ctrl = ScannerViewController()
ctrl.navigationItem.leftBarButtonItem = .close { [weak self] in self?.dismiss(animated: true) }
ctrl.didCapture = { [weak self] string in
guard let self else { return }
self.dismiss(animated: true)
self.service.link = string
self.linkTxtFld.value = string
}
let navCtrl = UINavigationController(rootViewController: ctrl)
navCtrl.modalPresentationStyle = .fullScreen
UIViewController.topController().present(navCtrl, animated: true)
return
}
Alert.system(
actions: [
.init(title: L10n.Wallet.Send.qrCamera, style: .default) { [weak self] _ in
guard let self else { return }
let ctrl = ScannerViewController()
ctrl.navigationItem.leftBarButtonItem = .close(self)
ctrl.didCapture = { [weak self] string in
guard let self else { return }
self.dismiss(animated: true)
self.service.link = string
self.linkTxtFld.value = string
}
let navCtrl = UINavigationController(rootViewController: ctrl)
navCtrl.modalPresentationStyle = .fullScreen
UIViewController.topController().present(navCtrl, animated: true)
},
.init(title: L10n.Wallet.Send.qrLibrary, style: .default) { [weak self] _ in
guard let self else { return }
let ctrl = UIImagePickerController()
ctrl.delegate = self
ctrl.sourceType = .photoLibrary
UIViewController.topController().present(ctrl, animated: true)
},
.init(title: L10n.Common.Button.cancel, style: .cancel)
],
style: .actionSheet,
in: self
)
}
@IBAction private func onSubmit(_ : AnyObject?) {
view.endEditing(true)
if service.order != nil {
Popup.show(
title: L10n.P2p.Dashboard.Order.Action.MoreEdit.Confirm.title,
views: [
.label(
text: L10n.P2p.Dashboard.Order.Action.MoreEdit.Confirm.description
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
)
],
submit: L10n.P2p.Dashboard.Order.Action.MoreEdit.Confirm.confirm,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.submit(privateKey: $0) { (error) in
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true)
Alert.notify(error, pop: self)
}
}
}
return
}
var views: [UIView] = [
.label(
text: (service.kind == .sell ? L10n.P2p.Order.Confirm.Sell.text : L10n.P2p.Order.Confirm.Buy.text)
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
)
]
if service.kind == .sell {
views.append(contentsOf: [
.warning(text: L10n.P2p.Order.Confirm.Sell.warning),
.field(
title: L10n.P2p.Order.Confirm.Sell.amount,
text: (service.amount.toDecimal() + service.insurance).toString(max: service.token?.precision ?? 0, symbol: service.token?.symbol)
),
.field(title: L10n.P2p.Order.Confirm.Sell.insurance, text: service.insurance.toString(max: service.token?.precision ?? 0, symbol: service.token?.symbol))
])
} else {
views.append(contentsOf: [
.field(
title: L10n.P2p.Order.Confirm.Sell.amount2,
text: service.insurance.toString(max: service.token?.precision ?? 0, symbol: service.token?.symbol)
)
])
}
Popup.show(title: L10n.P2p.Order.Confirm.title, views: views, submit: L10n.P2p.Order.Confirm.submit, in: self) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.submit(privateKey: $0) { (error) in
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true)
Alert.notify(error, pop: self)
if !self.service.isFast {
let tabIndex = self.service.kind == .buy ? 3 : 2
((self.mainController.content.viewControllers?[tabIndex] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?.setTabWithSroll(index: 1)
((self.mainController.content.viewControllers?[2] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?
.setToken(token: self.service.token)
((self.mainController.content.viewControllers?[3] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?
.setToken(token: self.service.token)
}
}
}
}
}
}
extension P2PControllerOrder: CommonTextFieldDelegate {
func textFieldDidEndEditing(_ textField: CommonTextField) {
if (textField == vcardNumberTxtFld) {
vcardNumberTxtFld.error = service.cardNumberError
} else if (textField == vcardExpirationTxtFld) {
vcardExpirationTxtFld.error = service.cardExpiryError
}
}
func textField(_ textField: CommonTextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = (textField.value as NSString).replacingCharacters(in: range, with: string)
switch textField {
case rateToken1View, rateToken2View:
return newString.removingWhitespaceAndNewlines().rangeOfCharacter(from: .decimalDigits.union(CharacterSet(charactersIn: ",.")).inverted) == nil &&
newString.count <= 12
case amountTxtFld, amountToken2View,
limitMin, limitMax:
return newString.removingWhitespaceAndNewlines().rangeOfCharacter(from: .decimalDigits.union(CharacterSet(charactersIn: ",.")).inverted) == nil
case vcardNumberTxtFld:
return newString.rangeOfCharacter(from: CharacterSet.decimalDigits.union(CharacterSet(charactersIn: " ")).inverted) == nil && Cards.Model.cleaned(number: newString).count <= 19
case vcardNameTxtFld:
return newString.rangeOfCharacter(from: CharacterSet.letters.union(CharacterSet(charactersIn: " ")).inverted) == nil
case vcardCVVTxtFld:
return newString.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil && newString.count <= 3
case vcardExpirationTxtFld:
return newString.rangeOfCharacter(from: CharacterSet.decimalDigits.union(CharacterSet(charactersIn: "/")).inverted) == nil && newString.count <= 5
default:
break
}
return true
}
func textFieldDidChange(_ textField: CommonTextField) {
switch textField {
case rateToken1View:
service.rateToken1 = textField.value
service.rateToken2 = "1"
case rateToken2View:
service.rateToken2 = textField.value
service.rateToken1 = "1"
case amountTxtFld:
service.amount = textField.value
case amountToken2View:
if let amount2 = textField.value.toOptionalDecimal() {
service.amount = (amount2 / service.rate).toReadebleString(precisionMax: service.token1Precision)
} else {
service.amount = ""
}
case limitMin:
service.limitMin = textField.value
case limitMax:
service.limitMax = textField.value
case vcardNumberTxtFld:
textField.value = Cards.Model.formmated(number: textField.value)
service.vcardNumber = textField.value
case vcardNameTxtFld:
service.vcardName = textField.value
case vcardExpirationTxtFld:
if service.vcardExpiration.count > textField.value.count {
if textField.value.count == 2 {
textField.value = String(textField.value.dropLast())
service.vcardExpiration = textField.value
} else {
service.vcardExpiration = textField.value
}
} else {
if textField.value.count == 2 {
// swiftlint:disable shorthand_operator
textField.value = textField.value + "/"
service.vcardExpiration = textField.value
} else if textField.value.count <= 5 {
service.vcardExpiration = textField.value
} else {
textField.value = String(textField.value.dropLast())
}
}
case vcardCVVTxtFld:
service.vcardCVV = textField.value
case linkTxtFld:
service.link = textField.value
case accountTxtFld:
service.account = textField.value
case memoTxtFld:
service.memo = textField.value
default:
break
}
}
}
extension P2PControllerOrder: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey:Any]) {
picker.dismiss(animated: true)
if let selectedImage = info[.originalImage] as? UIImage,
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]),
let ciImage = CIImage(image: selectedImage) {
var qrCodeLink = ""
for feature in (detector.features(in: ciImage) as? [CIQRCodeFeature]) ?? [] {
qrCodeLink += feature.messageString ?? ""
}
if !qrCodeLink.isEmpty {
service.link = qrCodeLink
linkTxtFld.value = qrCodeLink
}
}
dismiss(animated: true)
}
}