424 lines
18 KiB
Swift
424 lines
18 KiB
Swift
//
|
|
// P2PControllerRequestDetails.swift
|
|
// Wallet
|
|
//
|
|
// Created by Igor Danich on 07.09.2020.
|
|
// Copyright © 2020 List. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import class RealmSwift.List
|
|
import RealmSwift
|
|
|
|
class P2PControllerDeal: UIViewController {
|
|
|
|
@IBOutlet private weak var tokenLbl: UILabel!
|
|
@IBOutlet private weak var tokenView: CommonViewCard!
|
|
|
|
@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 weak var orderOwnerView: OrderOvnewView!
|
|
@IBOutlet weak var orderDetailView: OrderDetailView!
|
|
@IBOutlet weak var cardView: CommonViewCard!
|
|
@IBOutlet weak var linkViewContainer: UIView!
|
|
@IBOutlet weak var linkTxtFld: CommonTextField!
|
|
@IBOutlet weak var recieverAccountTxtFld: CommonTextField!
|
|
@IBOutlet weak var cryptoAccountTxtFld: CommonTextField!
|
|
|
|
@IBOutlet weak var virtualCardContainer: UIStackView!
|
|
|
|
@IBOutlet private weak var vcardNumberTxtFld: CommonTextField!
|
|
@IBOutlet private weak var vcardNameTxtFld: CommonTextField!
|
|
@IBOutlet private weak var vcardExpirationTxtFld: CommonTextField!
|
|
@IBOutlet weak var vcardCvvTxtFld: CommonTextField!
|
|
|
|
@IBOutlet private weak var countryView: CardView!
|
|
@IBOutlet private weak var bankView: CardView!
|
|
|
|
@IBOutlet private weak var submitBtn: CommonButtonAction!
|
|
|
|
private var didOpenChat = false
|
|
|
|
var service: P2P.Service.Deal!
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
service.didUpdate = { [weak self] in self?.update(animated: true) }
|
|
|
|
title = service.kind == .sell ? L10n.P2p.Deal.Sell.title : L10n.P2p.Deal.Buy.title
|
|
navigationItem.leftBarButtonItem = .pop(self)
|
|
|
|
for field in [amountTxtFld, amountToken2View] {
|
|
field?.isEnabled = !service.order.hasEqualAmount
|
|
field?.accessoryView = service.order.hasEqualAmount ? UIImageView(image: Asset.p2pLockIcon.image) : nil
|
|
field?.delegate = self
|
|
field?.keyboardType = .decimalPad
|
|
}
|
|
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)
|
|
}
|
|
|
|
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 = .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.flatMap { 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: "") }).first
|
|
self?.navigationController?.popViewController(animated: true)
|
|
}
|
|
self?.navigationController?.pushViewController(vc, animated: true)
|
|
}
|
|
|
|
amountTxtFld.lzPlaceholder = service.token.symbol
|
|
amountTxtFld.lzTitle = service.token.symbol
|
|
amountTxtFld.precision = service.token1Precision
|
|
|
|
amountToken2View.lzPlaceholder = service.order.currency?.name ?? ""
|
|
amountToken2View.lzTitle = service.order.currency?.name ?? ""
|
|
amountToken2View.precision = service.token2Precision
|
|
|
|
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)
|
|
tokenView.action = .action(icon: nil, selected: service.token.toMenu())
|
|
|
|
submitBtn.lzTitle = L10n.Common.Button.confirm
|
|
|
|
update(animated: false)
|
|
orderOwnerView.openChat = { [weak self] in
|
|
self?.didOpenChat = true
|
|
self?.onChat()
|
|
}
|
|
orderOwnerView.update(order: service.order)
|
|
orderDetailView.update(order: service.order)
|
|
|
|
if service.kind == .sell {
|
|
leftAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.buy
|
|
rightAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.sell
|
|
} else {
|
|
leftAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.sell
|
|
rightAmountLbl.lzText = L10n.P2p.Order.TokenGet.Title.buy
|
|
}
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
navigationController?.setNavigationBarHidden(false, animated: true)
|
|
navigationController?.navigationBar.clear()
|
|
if didOpenChat {
|
|
didOpenChat = false
|
|
mainController.barNav.popItem(animated: true)
|
|
}
|
|
Accounts().isLocked = true
|
|
if service.card == nil {
|
|
service.card = Cards.shared.default
|
|
}
|
|
update(animated: false)
|
|
}
|
|
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
super.viewWillDisappear(animated)
|
|
Accounts().isLocked = false
|
|
navigationController?.navigationBar.reset()
|
|
}
|
|
|
|
private func update(animated: Bool) {
|
|
|
|
cardView.superview?.superview?.isHidden = true
|
|
linkTxtFld.superview?.isHidden = true
|
|
linkViewContainer.isHidden = true
|
|
virtualCardContainer.isHidden = true
|
|
recieverAccountTxtFld.superview?.isHidden = true
|
|
cryptoAccountTxtFld.superview?.isHidden = true
|
|
|
|
switch service.order.contentType {
|
|
case .card:
|
|
cardView.superview?.superview?.isHidden = service.kind == .buy
|
|
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
|
|
}
|
|
}
|
|
case .cash: break
|
|
case .crypto:
|
|
cryptoAccountTxtFld.superview?.isHidden = service.kind == .buy
|
|
case .emoney:
|
|
recieverAccountTxtFld.superview?.isHidden = service.kind == .buy
|
|
case .url:
|
|
linkTxtFld.superview?.isHidden = service.kind == .buy
|
|
linkViewContainer.isHidden = service.kind == .buy
|
|
// linkTxtFld.value = service.order.paymentUrl ?? ""
|
|
case .vcard:
|
|
virtualCardContainer.isHidden = service.kind != .buy
|
|
|
|
countryView.descriptionLabel.isHidden = false
|
|
countryView.titleLabel.lzText = L10n.P2p.Order.Country.topTitle
|
|
countryView.descriptionLabel.lzText = service.country?.title
|
|
|
|
bankView.isHidden = service.country == nil
|
|
bankView.descriptionLabel.isHidden = false
|
|
bankView.titleLabel.lzText = L10n.P2p.Order.Bank.topTitle
|
|
bankView.descriptionLabel.lzText = service.bank?.title
|
|
}
|
|
|
|
if !amountTxtFld.isFirstResponder {
|
|
amountTxtFld.value = service.amount
|
|
}
|
|
|
|
if !amountToken2View.isFirstResponder {
|
|
amountToken2View.value = service.amountToken2
|
|
}
|
|
amountTxtFld.error = service.error
|
|
submitBtn.isEnabled = service.isValid
|
|
animated ? UIView.animate(withDuration: Animation.medium) { self.view.layoutIfNeeded() } : view.layoutIfNeeded()
|
|
}
|
|
|
|
@IBAction private func onSubmit(_ : AnyObject?) {
|
|
view.endEditing(true)
|
|
|
|
var views: [UIView] = [
|
|
.label(
|
|
text: (service.kind == .sell ? L10n.P2p.Deal.Confirm.Sell.text : L10n.P2p.Deal.Confirm.Buy.text)
|
|
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
|
|
numberOfLines: 0
|
|
),
|
|
.warning(text: "p2p.deal.confirm.\(service.kind.rawValue.lowercased()).warning.\(service.order.contentType.rawValue.lowercased())".localized),
|
|
.field(
|
|
title: service.kind == .sell ? L10n.P2p.Deal.Confirm.Sell.amount : L10n.P2p.Deal.Confirm.Buy.amount,
|
|
text: (service.kind == .sell
|
|
? service.amount.toDecimal() + service.insurance
|
|
: service.insurance)
|
|
.toString(max: service.token)
|
|
),
|
|
.field(
|
|
title: L10n.P2p.Deal.Confirm.Sell.insurance,
|
|
text: service.insurance.toString(max: service.token)
|
|
)
|
|
]
|
|
|
|
if service.kind != .sell {
|
|
views.removeLast()
|
|
}
|
|
|
|
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)
|
|
|
|
let tabIndex = self.service.kind == .buy ? 3 : 2
|
|
((self.mainController.content.viewControllers?[tabIndex] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?.setTabWithSroll(index: 0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func onChat() {
|
|
AccountViewAuthorize.showGetPrivateKey(in: self) {
|
|
guard
|
|
let user = Accounts().current,
|
|
let service = try? CryptoChat.Service.MsgsHistory(username: user.name, encryptionKey: $0)
|
|
else { return }
|
|
self.didOpenChat = true
|
|
let ctrl = CryptoChatControllerChat(username: self.service.order.owner, unreadCount: 0, service: service)
|
|
self.navigationController?.pushViewController(ctrl, animated: true)
|
|
}
|
|
}
|
|
|
|
@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.order.paymentUrl = 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
|
|
)
|
|
}
|
|
|
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
|
view.endEditing(true)
|
|
}
|
|
|
|
}
|
|
|
|
extension P2PControllerDeal: 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 amountTxtFld, amountToken2View:
|
|
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 amountTxtFld:
|
|
service.amount = textField.value
|
|
case amountToken2View:
|
|
if let amount2 = textField.value.toOptionalDecimal() {
|
|
service.amount = (
|
|
service.order.rateIsReversed
|
|
? amount2 * service.order.rate.decimalValue
|
|
: amount2 / service.order.rate.decimalValue
|
|
).toReadebleString(precisionMax: service.token1Precision)
|
|
} else {
|
|
service.amount = ""
|
|
}
|
|
|
|
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 recieverAccountTxtFld, cryptoAccountTxtFld:
|
|
service.account = textField.value
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
extension P2PControllerDeal: 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)
|
|
}
|
|
}
|