357 lines
16 KiB
Swift
357 lines
16 KiB
Swift
//
|
|
// CCCPControllerDestroyTokens.swift
|
|
// List
|
|
//
|
|
// Created by Saveliy Stavitsky on 7/23/20.
|
|
// Copyright © 2020 List. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
private typealias Contract = Network.Model.Contract
|
|
private typealias BlockchainAction = Network.Model.Blockchain.Action
|
|
|
|
class CCCPControllerDestroyTokens: UIViewController {
|
|
|
|
var bill: CashBillsService.Bill?
|
|
|
|
@IBOutlet private var mainStackView: UIStackView!
|
|
@IBOutlet private weak var certificateGiveView: CommonViewCard!
|
|
@IBOutlet private weak var tokeGiveView: CommonViewCard!
|
|
@IBOutlet private weak var amountTextField: CommonTextField!
|
|
@IBOutlet private var labelsStackView: UIStackView!
|
|
@IBOutlet private weak var youGiveInfoLbl: CommonViewInfoLabel!
|
|
@IBOutlet private weak var youGetInfoLbl: CommonViewInfoLabel!
|
|
|
|
@IBOutlet var youGiveTokenSelectorView: CCCPViewTokenSelector!
|
|
@IBOutlet var youGetTokenSelectorView: CCCPViewTokenSelector!
|
|
|
|
@IBOutlet var destroyTokensButton: CommonButtonAction!
|
|
|
|
var selectSymbol = ""
|
|
|
|
var tokensIncome: [Network.Model.TokenSmall] = []
|
|
var tokensIncomeCoef: Decimal? {
|
|
if let certificateGive = youGiveTokenSelectorView.selectedToken,
|
|
let tokenGet = Wallet.Service.Tokens.shared.certificateToList(certificateGive) {
|
|
return tokensIncome
|
|
.first(where: { $0.quantity.symbol == tokenGet.symbol })?
|
|
.quantity.amount.toDecimal()
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
var cashBillsService: CashBillsService?
|
|
|
|
// var cashTokens: [Network.Model.Token] { Wallet.Service.Tokens.shared.cashTokens }
|
|
var tokens: [Network.Model.Token] = [] {
|
|
didSet {
|
|
youGiveTokenSelectorView.tokens = tokens.filter(\.isCertificate)
|
|
if let index = youGiveTokenSelectorView.tokens.enumerated()
|
|
.first(where: { $0.element.symbol == self.selectSymbol })?.offset,
|
|
!selectSymbol.isEmpty {
|
|
selectSymbol = ""
|
|
youGiveTokenSelectorView.index = index
|
|
}
|
|
|
|
certificateGiveView.action = .cards(
|
|
icon: Asset.commonLock.image.withTintColor(Asset.pebble.color),
|
|
tokens: youGiveTokenSelectorView.tokens,
|
|
selected: youGiveTokenSelectorView.tokens
|
|
.first(where: { $0.symbol == bill?.gtoken_out.quantity.symbol }),
|
|
empty: .menu(
|
|
image: Asset.commonToken.image.tinted(with: Asset.deepWater.color),
|
|
title: L10n.Cccp.IssueBackTokens.youGiveTokenTitle
|
|
),
|
|
title: L10n.Cccp.IssueBackTokens.youGiveTokenTitle, { [weak self] _ in
|
|
})
|
|
certificateGiveView.isUserInteractionEnabled = false
|
|
|
|
tokeGiveView.action = .cards(
|
|
icon: Asset.commonLock.image.withTintColor(Asset.pebble.color),
|
|
tokens: youGiveTokenSelectorView.tokens,
|
|
selected: youGiveTokenSelectorView.selectedToken,
|
|
empty: .menu(
|
|
image: Asset.commonToken.image.tinted(with: Asset.deepWater.color),
|
|
title: L10n.Cccp.IssueBackTokens.youGiveTokenTitle
|
|
),
|
|
title: L10n.Cccp.IssueBackTokens.youGiveTokenTitle, { [weak self] in
|
|
self?.tokeGiveView.selectedCashBill = nil
|
|
self?.tokeGiveView.update(animated: true)
|
|
self?.youGiveTokenSelectorView.index = self?.youGiveTokenSelectorView.tokens.index(of: $0.uuid) ?? -1
|
|
})
|
|
}
|
|
}
|
|
|
|
var selectedTokens: (Network.Model.Token, Network.Model.Token, String)? {
|
|
guard let certificateGive = youGiveTokenSelectorView.tokens
|
|
.first(where: { $0.symbol == tokeGiveView.selectedCashBill?.gtoken_out.quantity.symbol })
|
|
?? youGiveTokenSelectorView.selectedToken,
|
|
let cashGive = Wallet.Service.Tokens.shared.certificateToCash(certificateGive),
|
|
let tokenGet = Wallet.Service.Tokens.shared.certificateToList(certificateGive)
|
|
else {
|
|
return nil
|
|
}
|
|
return (certificateGive, cashGive, tokenGet.symbol)
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
navigationItem.title = L10n.Cccp.IssueBackTokens.title
|
|
navigationItem.leftBarButtonItem = .pop(self)
|
|
|
|
tokeGiveView.isUserInteractionEnabled = false
|
|
tokeGiveView.root = true
|
|
tokeGiveView.cashBillsService = cashBillsService
|
|
self.tokeGiveView.selectCashBillAction = { [weak self] in
|
|
print($0?.id)
|
|
self?.tokeGiveView.selectedCashBill = $0
|
|
self?.tokeGiveView.update(animated: true)
|
|
self?.stateChanged()
|
|
Popup.hide()
|
|
}
|
|
youGiveTokenSelectorView.count = 1
|
|
if let bill = bill {
|
|
tokeGiveView.selectedCashBill = bill
|
|
tokeGiveView.update(animated: true)
|
|
stateChanged()
|
|
}
|
|
|
|
tokeGiveView.action = .cards(
|
|
tokens: [],
|
|
selected: nil,
|
|
empty: .menu(
|
|
image: Asset.commonToken.image.tinted(with: Asset.deepWater.color),
|
|
title: L10n.Cccp.IssueBackTokens.youGiveTokenTitle
|
|
),
|
|
title: L10n.Cccp.IssueBackTokens.youGiveTokenTitle
|
|
)
|
|
amountTextField.keyboardType = .numberPad
|
|
amountTextField.delegate = self
|
|
|
|
youGiveTokenSelectorView.titleLabel.text = L10n.Cccp.DestroyTokens.youGiveTitle
|
|
youGiveTokenSelectorView.secondTitleLabel.isHidden = true
|
|
youGiveTokenSelectorView.notesTitleLabel.text = L10n.Cccp.DestroyTokens.youGiveYouGiveTitle
|
|
youGiveTokenSelectorView.balanceStackView.isHidden = false
|
|
youGiveTokenSelectorView.parentViewController = self
|
|
|
|
youGetTokenSelectorView.secondTitleLabel.isHidden = true
|
|
youGetTokenSelectorView.countSectionStackView.isHidden = true
|
|
youGetTokenSelectorView.currencyPickerSectionStackView.isHidden = true
|
|
youGetTokenSelectorView.currencySectionImageView.isHidden = true
|
|
youGetTokenSelectorView.notesTitleLabel.text = L10n.Cccp.DestroyTokens.youGetYouGetTitle
|
|
youGetTokenSelectorView.parentViewController = self
|
|
|
|
observers.append(contentsOf: [
|
|
Notification.subscribe(name: .didChangeAccount) { _ in Loader.show() },
|
|
Notification.subscribe(name: .didUpdateBalances) { [weak self] _ in self?.setupView() }
|
|
])
|
|
setupView()
|
|
// NotificationCenter.default.addObserver(self, selector: #selector(onBalancesChange(_:)),
|
|
// name: .didUpdateBalances, object: nil)
|
|
// onBalancesChange(Notification(name: .didUpdateBalances))
|
|
}
|
|
|
|
var observers: [AnyObject] = []
|
|
deinit {
|
|
observers.forEach({ Notification.unsubscribe(observer: $0) })
|
|
// NotificationCenter.default.removeObserver(self, name: .didUpdateBalances, object: nil)
|
|
}
|
|
|
|
func setupView() { //(_ notification: Notification)
|
|
CCCP.Service.Swaps.shared.fetch { [weak self] in
|
|
self?.tokensIncome = $0
|
|
self?.tokens = Wallet.Service.Tokens.shared.balances.collection
|
|
Loader.hide()
|
|
}
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
Accounts().isLocked = true
|
|
}
|
|
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
super.viewWillDisappear(animated)
|
|
Accounts().isLocked = false
|
|
}
|
|
|
|
@IBAction func destroyTokensPressed(_ sender: Any) {
|
|
guard let user = Accounts().current,
|
|
let (certificateTokenGive, cashTokenGive, tokenGet) = selectedTokens,
|
|
youGiveTokenSelectorView.count > 0 else { return }
|
|
|
|
let actions = prepareBlockchainActions(
|
|
user: user,
|
|
certificateTokenGive: certificateTokenGive,
|
|
tokenGet: tokenGet
|
|
)
|
|
|
|
Popup.show(title: navigationItem.title, views: [labelsStackView], submit: L10n.Common.Button.confirm, in: self, { [unowned self] ctrl in
|
|
AccountViewAuthorize.showGetPrivateKey(in: self) {
|
|
Loader.show(in: ctrl)
|
|
Network.Service.Blockchain.execute(actions: actions, privateKeys: [$0]) { result in
|
|
Loader.hide(in: ctrl)
|
|
ctrl.dismiss(animated: true)
|
|
switch result {
|
|
case .success(let transactionId):
|
|
delayed(0.5) { //needed because labelsStackView will free inly after previous popup hde
|
|
Popup.show(title: L10n.Cccp.IssueBackTokens.completeTitle,
|
|
views: [labelsStackView],
|
|
submit: L10n.Common.Button.checkOnBloksIO,
|
|
submitStyle: .outline,
|
|
cancel: L10n.Common.Button.done, in: self, { _ in
|
|
guard let checkTransactionUrl = URL(transactionId: transactionId) else { return }
|
|
UIApplication.shared.open(checkTransactionUrl, options: [:], completionHandler: nil)
|
|
},
|
|
{
|
|
if let secondViewController = navigationController?.viewControllers.dropFirst().first {
|
|
navigationController?.popToViewController(secondViewController, animated: true)
|
|
}
|
|
})
|
|
}
|
|
case let .failure(error):
|
|
Alert.notify(error, pop: self)
|
|
}
|
|
}
|
|
}
|
|
}, { [weak self] in
|
|
guard let self = self else { return }
|
|
self.mainStackView.addArrangedSubview(self.labelsStackView)
|
|
})
|
|
}
|
|
|
|
private func prepareBlockchainActions(
|
|
user: Account.Model,
|
|
certificateTokenGive: Network.Model.Token,
|
|
tokenGet: String) -> [(Contract, BlockchainAction, Codable)] {
|
|
|
|
var actions = [(Contract, BlockchainAction, Codable)]()
|
|
|
|
//Create Token balances if not present
|
|
if !tokens.map({ $0.symbol }).contains(tokenGet) {
|
|
let openBalanceData = Network.Model.Blockchain.OpenBalance(
|
|
owner: user.username,
|
|
symbol: "8,\(tokenGet)",
|
|
ram_payer: user.username
|
|
)
|
|
actions.append((.list, .open, openBalanceData))
|
|
}
|
|
|
|
//Destroy Tokens action
|
|
if let bill = tokeGiveView.selectedCashBill {
|
|
let swapBackData = Network.Model.Blockchain.BillSwapback(
|
|
owner: user.username, receiver: user.username,
|
|
bill_id: "\(bill.id)"
|
|
)
|
|
actions.append((.cash, .cashBillSwapback, swapBackData))
|
|
} else {
|
|
let swapBackData = Network.Model.Blockchain.Swapback(
|
|
owner: user.username, receiver: user.username,
|
|
certificate: "\(youGiveTokenSelectorView.count) \(certificateTokenGive.symbol)"
|
|
)
|
|
actions.append((.cash, .cashSwapback, swapBackData))
|
|
}
|
|
|
|
return actions
|
|
}
|
|
}
|
|
|
|
extension CCCPControllerDestroyTokens: CCCPViewTokenSelectorDelegate {
|
|
|
|
func stateChanged() {
|
|
//Reset appearance
|
|
youGiveTokenSelectorView.notesSectionSubStackView.arrangedSubviews
|
|
.forEach({ $0.removeFromSuperview() })
|
|
youGetTokenSelectorView.notesSectionSubStackView.arrangedSubviews
|
|
.forEach({ $0.removeFromSuperview() })
|
|
// destroyTokensButton.setTitle(L10n.Cccp.DestroyTokens.buttonDestroyTokens(""), for: .normal)
|
|
destroyTokensButton.isEnabled = false
|
|
|
|
guard let (certGive, cashTokenGive, tokenGet) = selectedTokens else { return }
|
|
// amountTextField.isHidden = false
|
|
labelsStackView.isHidden = false
|
|
|
|
labelsStackView.arrangedSubviews.forEach({ $0.removeFromSuperview() })
|
|
|
|
let cashInfo1 = CommonViewInfoLabel()
|
|
cashInfo1.lzTitle = L10n.Cash.DestroyTokens.tokenReturn
|
|
cashInfo1.addText(cashTokenGive.symbol)
|
|
labelsStackView.addArrangedSubview(cashInfo1)
|
|
|
|
//Cash token select section view appearance
|
|
let cashTokensCount = Decimal(youGiveTokenSelectorView.count) * cashTokenGive.certCoef
|
|
let labelCashTokens = CCCPLabelAddMoneyColored(sign: "-", amount: cashTokensCount, symbol: cashTokenGive.symbol)
|
|
youGiveTokenSelectorView.notesSectionSubStackView.addArrangedSubview(labelCashTokens)
|
|
|
|
let labelListTokens = CCCPLabelAddMoneyColored(
|
|
amount: Decimal(youGiveTokenSelectorView.count) * (tokensIncomeCoef ?? 0.0), symbol: tokenGet)
|
|
youGetTokenSelectorView.notesSectionSubStackView.addArrangedSubview(labelListTokens)
|
|
|
|
// youGiveInfoLbl.clearAll()
|
|
// youGiveInfoLbl.addText("\(youGiveTokenSelectorView.count) \(certGive.symbol)")
|
|
// youGiveInfoLbl.addText("\(cashTokensCount.toString(precision: 5)) \(cashTokenGive.symbol)")
|
|
|
|
let returnAmount = (tokeGiveView.selectedCashBill?.token_out.quantity ?? "\(cashTokensCount.toString(max: 5, group: false)) \(cashTokenGive.symbol)").amount.toDecimal()
|
|
let returnCommission = returnAmount * 0.03
|
|
let cashInfo2 = CommonViewInfoLabel()
|
|
cashInfo2.lzTitle = L10n.Cash.DestroyTokens.amountReturn
|
|
cashInfo2.addText((returnAmount + returnCommission).toString(max: 5))
|
|
labelsStackView.addArrangedSubview(cashInfo2)
|
|
|
|
let cashInfo3 = CommonViewInfoLabel()
|
|
cashInfo3.lzTitle = L10n.Cash.DestroyTokens.commissionReturn
|
|
cashInfo3.addText(returnCommission.toString(max: 5))
|
|
labelsStackView.addArrangedSubview(cashInfo3)
|
|
|
|
let cashInfo4 = CommonViewInfoLabel()
|
|
cashInfo4.lzTitle = L10n.Cash.DestroyTokens.tokenGet
|
|
cashInfo4.addText(tokenGet)
|
|
labelsStackView.addArrangedSubview(cashInfo4)
|
|
|
|
let cashInfo5 = CommonViewInfoLabel()
|
|
cashInfo5.lzTitle = L10n.Cash.DestroyTokens.amountGet
|
|
cashInfo5.addText("100")
|
|
labelsStackView.addArrangedSubview(cashInfo5)
|
|
|
|
// youGetInfoLbl.updateText("\((Double(youGiveTokenSelectorView.count) * (tokensIncomeCoef ?? 0.0)).toString(precision: 8)) \(tokenGet)")
|
|
|
|
// destroyTokensButton.setTitle(L10n.Cccp.DestroyTokens.buttonDestroyTokens(tokenGet), for: .normal)
|
|
|
|
if let amountHave = tokens.first(where: { $0.symbol == cashTokenGive.symbol })?.amount {
|
|
if amountHave >= (returnAmount + returnCommission) && certGive.amount > 0 {
|
|
destroyTokensButton.isEnabled = true
|
|
} else if certGive.amount > 0 {
|
|
cashInfo2.addError(L10n.Cccp.IssueBackTokens.youGiveAmountError(cashTokenGive.symbol))
|
|
}
|
|
}
|
|
|
|
// amountTextField.error = youGiveTokenSelectorView.count > 0
|
|
// && youGiveTokenSelectorView.count > youGiveTokenSelectorView.maxTokens
|
|
// ? L10n.Cccp.IssueBackTokens.youGiveAmountError(certGive.symbol) : nil
|
|
//
|
|
// if youGiveTokenSelectorView.count > 0 && youGiveTokenSelectorView.count <= youGiveTokenSelectorView.maxTokens {
|
|
// if let amountHave = tokens.first(where: { $0.symbol == cashTokenGive.symbol })?.amount {
|
|
// if amountHave >= Double(youGiveTokenSelectorView.count) * cashTokenGive.certCoef {
|
|
// destroyTokensButton.isEnabled = true
|
|
// } else {
|
|
// let infoLabel = UILabel()
|
|
// infoLabel.attributedText = L10n.Cccp.DestroyTokens.noEnoughtBalance.attributed
|
|
// .applying(attribute: .foregroundColor, value: Asset.liSTRedEnd.color)
|
|
// .applying(attribute: .font, value: FontFamily.GolosUI.medium.font(size: 14)!)
|
|
// youGiveTokenSelectorView.notesSectionSubStackView.addArrangedSubview(infoLabel)
|
|
// youGiveInfoLbl.addError(L10n.Cccp.IssueBackTokens.youGiveAmountError(cashTokenGive.symbol))
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
extension CCCPControllerDestroyTokens: CommonTextFieldDelegate {
|
|
func textFieldDidChange(_ textField: CommonTextField) {
|
|
youGiveTokenSelectorView.count = Int(textField.value) ?? 0
|
|
}
|
|
}
|