Files
raspberry/iOS/Wallet/Sources/P2P/Controller/P2PLockedFundsController.swift

446 lines
22 KiB
Swift

//
// P2PLockedFundsController.swift
// Wallet
//
// Created by Saveliy Stavitsky on 7/9/21.
// Copyright © 2021 AM. All rights reserved.
//
import UIKit
import WalletFoundation
class P2PLockedFundsController: UITableViewController {
let service = P2PMainLockedFundsService()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = L10n.P2p.Main.LockedFunds.headerTitle
navigationItem.leftBarButtonItem = .pop(self)
tableView.showsVerticalScrollIndicator = false
tableView.separatorStyle = .none
tableView.allowsSelection = false
tableView.backgroundColor = Asset.gypsum.color
tableView.register(cell: DealTableViewCell.self)
tableView.register(cell: P2PBalanceTableViewCell.self)
tableView.register(cell: P2PCellOrder.self)
service.didUpdate = { [weak self] in self?.update() }
service.combineList()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
Accounts().isLocked = true
self.navigationController >>- {
$0.navigationBar.isTranslucent = false
$0.navigationBar.backgroundColor = Asset.snow.color
$0.setNavigationBarHidden(false, animated: true)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
Accounts().isLocked = false
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
}
private func update() {
Loader.hide()
tableView.reloadData()
}
func edit(order: P2POrder) {
let ctrl = StoryboardScene.P2P.order.instantiate()
let token = P2P.Service.tokens.first(where: { $0.symbol == order.symbol })!
ctrl.service = .init(kind: order.kind, contentType: order.contentType, token: token, order: P2POrder(value: order))
ctrl.service.card = Cards.shared.collection
.first(where: { $0.number == order.cardNumber ?? "" }) ?? Cards.shared.default
ctrl.service.paymentSystem = order.paymentSystem.map({ (id: $0.id, title: $0.name, description: "") })
ctrl.service.tokenGet = order.currency.map({ (id: $0.id, title: $0.name, description: $0.descriptn ?? "") })
ctrl.service.blockchain = order.blockchain.map({ (id: $0.id, title: $0.name, description: $0.descriptn ?? "") })
ctrl.service.rateToken1 = order.rateIsReversed
? order.rate.decimalValue.toReadebleString(precisionMax: 12) : "1"
ctrl.service.rateToken2 = order.rateIsReversed
? "1" : order.rate.decimalValue.toReadebleString(precisionMax: 12)
ctrl.service.amount = order.volume.decimalValue.toReadebleString(precisionMax: 2)
ctrl.service.limitMin = order.min.decimalValue.toReadebleString(precisionMax: 2)
ctrl.service.limitMax = order.max.decimalValue.toReadebleString(precisionMax: 2)
ctrl.service.link = order.paymentUrl ?? ""
ctrl.service.vcardNumber = order.cardNumber ?? ""
ctrl.service.vcardName = order.cardName ?? ""
ctrl.service.vcardExpiration = order.cardDate ?? ""
ctrl.service.vcardCVV = order.cvv ?? ""
ctrl.service.country = order.country.map({ (id: $0.id, title: $0.name, description: "") })
ctrl.service.city = order.city.map({ (id: $0.id, title: $0.name, description: "") })
ctrl.service.bank = order.banks.map({ (id: $0.id, title: $0.name, description: "") })
ctrl.service.account = order.walletNumber ?? order.walletAddress ?? ""
ctrl.service.memo = order.memo ?? ""
self.mainController.content.push(ctrl, animated: true)
}
}
extension P2PLockedFundsController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
service.items.count
}
//swiftlint:disable:next function_body_length
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard indexPath.row < service.items.count else { return UITableViewCell() }
switch service.items[indexPath.row] {
case let deal as P2PDeal:
let cell = tableView.dequeueReusableCell(DealTableViewCell.self, indexPath: indexPath)
cell.p2pDealView.tableView = tableView
cell.p2pDealView.completionTopSection = { [weak self] in
let tabIndex = deal.seller == Accounts().current?.name ? 2 : 3
self?.mainController.content.selectedIndex = tabIndex
((self?.mainController.content.viewControllers?[tabIndex] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?.service.token =
Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.isCashContract && $0.symbol == deal.symbol })
}
// guard indexPath.row < service.deals.dealsToShow.count else { return cell }
// let deal = service.deals.dealsToShow[indexPath.row]
cell.p2pDealView.setup(model: deal, lockedFunds: true) { [weak self] action in
guard let self else { return }
switch action {
case .complete:
if deal.isExpired && deal.seller == Accounts().current?.name && deal.status != .dispute {
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
self.service.service.complete(privateKey: $0, deal: deal) { (error) in
Loader.hide()
Alert.notify(error)
}
}
} else if deal.isExpired && deal.buyer == Accounts().current?.name && deal.status != .dispute {
Popup.show(
title: L10n.P2p.Dashboard.Deal.Confirm.title,
views: [
.label(
text: L10n.P2p.Dashboard.Deal.Confirm.Complete.Text.expired
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.warning(text: L10n.P2p.Dashboard.Deal.Confirm.Complete.Warning.expired),
.field(
title: L10n.P2p.Dashboard.Deal.Confirm.Complete.Amount.expired,
text: (deal.volume.decimalValue + deal.insurance.decimalValue).toString(max: deal.precision, symbol: deal.symbol)
),
.field(
title: L10n.P2p.Dashboard.Deal.Confirm.Complete.Insurance.expired,
text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol)
)
],
submit: L10n.P2p.Dashboard.Deal.Confirm.submit,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.service.complete(privateKey: $0, deal: deal) { (error) in
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true)
Alert.notify(error)
}
}
}
} else {
Popup.show(
title: L10n.P2p.Dashboard.Deal.Confirm.title,
views: [
.label(
text: L10n.P2p.Dashboard.Deal.Confirm.Complete.text(deal.volume.decimalValue.toString(max: deal.precision, symbol: deal.symbol))
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.warning(text: L10n.P2p.Dashboard.Deal.Confirm.Complete.warning),
.field(
title: L10n.P2p.Dashboard.Deal.Confirm.Complete.amount,
text: deal.volume.decimalValue.toString(max: deal.precision, symbol: deal.symbol)
),
.field(
title: L10n.P2p.Dashboard.Deal.Confirm.Complete.insurance,
text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol)
)
],
submit: L10n.P2p.Dashboard.Deal.Confirm.submit,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.service.complete(privateKey: $0, deal: deal) { (error) in
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true)
Alert.notify(error)
}
}
}
}
case .dispute:
Popup.show(
title: L10n.P2p.Dashboard.Deal.Confirm.title,
views: [
.label(
text: L10n.P2p.Dashboard.Deal.Confirm.Dispute.text1.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.warning(text: L10n.P2p.Dashboard.Deal.Confirm.Dispute.warning),
.label(
text: L10n.P2p.Dashboard.Deal.Confirm.Dispute.text2.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
)
],
submit: L10n.P2p.Dashboard.Deal.Confirm.submit,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.service.dispute(privateKey: $0, deal: deal) { (error) in
Loader.hide(in: ctrl)
Alert.notify(error, dismiss: ctrl)
}
}
}
case .cancel:
if deal.seller == Accounts().current?.name || !deal.isExpired {
Popup.show(
title: L10n.P2p.Dashboard.Deal.Confirm.title,
views: [
.label(
text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.text("100").attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.warning(text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.warning),
.field(
title: L10n.P2p.Dashboard.Deal.Confirm.Cancel.insurance,
text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol)
)
],
submit: L10n.P2p.Dashboard.Deal.Confirm.submit,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.service.cancel(privateKey: $0, deal: deal) { (error) in
Loader.hide(in: ctrl)
Alert.notify(error, dismiss: ctrl)
}
}
}
} else {
Popup.show(
title: L10n.P2p.Dashboard.Deal.Confirm.title,
views: [
.label(
text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.text("100").attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.warning(text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.warning),
.field(
title: L10n.P2p.Dashboard.Deal.Confirm.Cancel.insurance,
text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol)
)
],
submit: L10n.P2p.Dashboard.Deal.Confirm.submit,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show(in: ctrl)
self.service.service.cancel(privateKey: $0, deal: deal) { (error) in
Loader.hide(in: ctrl)
Alert.notify(error, dismiss: ctrl)
}
}
}
}
case .withdraw:
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
self.service.service.withdraw(privateKey: $0, deal: deal) { (error) in
Loader.hide()
Alert.notify(error)
}
}
case .pay:
Loader.show()
self.service.service.pay(deal: deal) { (error) in
Loader.hide()
Alert.notify(error)
}
case .chat:
break
}
}
return cell
case let order as P2POrder:
let cell = tableView.dequeueReusableCell(P2PCellOrder.self, indexPath: indexPath)
cell.tableView = tableView
cell.completionTopSection = { [weak self] in
let tabIndex = order.kind == .buy ? 3 : 2
self?.mainController.content.selectedIndex = tabIndex
((self?.mainController.content.viewControllers?[tabIndex] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?.service.token =
Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.isCashContract && $0.symbol == order.symbol })
}
// guard indexPath.row < service.orders.collection.count else { return cell }
// let order = service.orders.collection[indexPath.row]
cell.setup(model: order, lockedFunds: true) { [weak self] action in
guard let self else { return }
switch action {
case .buy, .sell:
break
case .pause:
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
order.pause(privateKey: $0) { (error) in
Loader.hide()
Alert.notify(error)
}
}
case .resume:
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
order.resume(privateKey: $0) { (error) in
Loader.hide()
Alert.notify(error)
}
}
case .cancel:
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
order.cancel(privateKey: $0) { (error) in
Loader.hide()
Alert.notify(error)
}
}
case .chat:
break
case .more:
let ctrl = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
ctrl.addAction(.init(title: L10n.P2p.Dashboard.Order.Action.moreEdit, style: .default) { [weak self] _ in
guard let self = self else { return }
// if order.status == .inactive {
// edit(order: order)
// return
// }
Popup.show(
title: L10n.P2p.Dashboard.Order.Action.MoreEdit.title,
views: [
.label(
text: (order.kind == .buy
? L10n.P2p.Dashboard.Order.Action.MoreEdit.descriptionBuy
: L10n.P2p.Dashboard.Order.Action.MoreEdit.descriptionSell)
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.warning(text: L10n.P2p.Dashboard.Order.Action.MoreEdit.warning),
],
submit: order.status == .inactive
? L10n.P2p.Dashboard.Order.Action.MoreEdit.edit
: L10n.P2p.Dashboard.Order.Action.MoreEdit.stopAndEdit,
cancel: L10n.Common.Button.cancel,
cancelStyle: .tertiary,
cancelSize: .small,
in: self
) { [weak self] ctrl in
guard let self = self else {
Popup.hide()
return
}
if order.status == .active {
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
order.pause(privateKey: $0) { (error) in
Loader.hide()
Popup.hide()
Alert.notify(error)
self.edit(order: order)
}
}
} else {
Popup.hide()
self.edit(order: order)
}
}
})
ctrl.addAction(.init(title: L10n.P2p.Dashboard.Order.Action.moreCancel, style: .default) { [weak self] _ in
guard let self = self else { return }
Popup.show(
title: L10n.Common.Title.confirmation,
views: [
.label(
text: (order.kind == .buy
? L10n.P2p.Dashboard.Order.Action.MoreCancel.descriptionBuy
: L10n.P2p.Dashboard.Order.Action.MoreCancel.descriptionSell)
.attributed(style: .regular, size: 14, color: Asset.textCoal.color),
numberOfLines: 0
),
.field(
title: L10n.P2p.Dashboard.Order.Action.MoreCancel.get,
text: (order.kind == .buy ? order.insurance.decimalValue : order.volume.decimalValue).toReadebleString(precisionMax: order.precision, symbol: order.symbol)
),
.field(
title: L10n.P2p.Dashboard.Order.Action.MoreCancel.deposit,
text: (order.volume.decimalValue * 0.1).toReadebleString(precisionMax: order.precision, symbol: order.symbol)
)
].dropLast(order.kind == .buy ? 1 : 0),
submit: L10n.Common.Button.confirm,
in: self
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
order.cancel(privateKey: $0) { (error) in
Loader.hide()
Popup.hide()
Alert.notify(error)
}
}
}
})
ctrl.addAction(.init(title: L10n.Common.Button.cancel, style: .cancel, handler: nil))
self.present(ctrl, animated: true)
}
}
return cell
case let balance as P2PBalance:
let cell = tableView.dequeueReusableCell(P2PBalanceTableViewCell.self, indexPath: indexPath)
cell.setup(model: balance) { [weak self] action in
self?.withrawBalance(symbol: balance.symbol, precision: balance.precision)
}
return cell
default:
return UITableViewCell()
}
}
}
extension P2PLockedFundsController {
private func withrawBalance(symbol: String, precision: Int) {
AccountViewAuthorize.showGetPrivateKey(in: self) {
Loader.show()
self.service.p2pBalancesService.withdraw(privateKey: $0, symbol: symbol, precision: precision) { (error) in
Loader.hide()
Alert.notify(error, pop: self)
}
}
}
}