// // ResourcesControllerSetupPerformance.swift // Wallet // // Created by Igor Danich on 14.08.2020. // Copyright © 2020 List. All rights reserved. // import UIKit class ResourcesControllerSetupPerformance: UIViewController { @IBOutlet private weak var cpuResourcesView: ResourceInfoItemView! @IBOutlet private weak var cpuStackedLbl: UILabel! @IBOutlet private weak var cpuStackedMeLbl: UILabel! @IBOutlet private weak var cpuStackedOthersLbl: UILabel! @IBOutlet private weak var netResourcesView: ResourceInfoItemView! @IBOutlet private weak var netStackedLbl: UILabel! @IBOutlet private weak var netStackedMeLbl: UILabel! @IBOutlet private weak var netStackedOthersLbl: UILabel! @IBOutlet private weak var tokenView: CommonViewCard! @IBOutlet private weak var tokenTitleLabel: UILabel! @IBOutlet private weak var timerView: UIView! @IBOutlet private weak var refundTitleLbl: UILabel! @IBOutlet private weak var refundTimeLbl: UILabel! @IBOutlet private weak var refundBtn: UIButton! @IBOutlet private weak var otherLbl: UILabel! @IBOutlet private weak var otherSwitch: UISwitch! @IBOutlet private weak var otherAccountTxtFld: CommonTextField! @IBOutlet private weak var otherTransferView: CommonViewRadioGroup! @IBOutlet private weak var cpuTxtFld: CommonTextField! @IBOutlet private weak var netTxtFld: CommonTextField! @IBOutlet private weak var submitBtn: CommonButtonAction! @IBOutlet weak var refundView: UIView! @IBOutlet weak var refundHeightConstraint: NSLayoutConstraint! private var account: String? { Accounts().current?.name } var action: Resources.Service.Setup.Performance.Action! var service: Resources.Service.Setup.Performance! { didSet { service.didUpdate = { [weak self] in self?.update(animated: true) } service.didReload = { [weak self] in guard let self = self else { return } Loader.hide(in: self) self.reload(animated: true) } service.action = action service.clear(force: false) } } func preload() { cpuTxtFld.value = "" netTxtFld.value = "" service.clear(force: false) service.fetch() Loader.show(in: self) } override func viewDidLoad() { super.viewDidLoad() title = action == .stake ? L10n.Resources.Setup.Buy.cpuNet : L10n.Resources.Setup.Sell.cpuNet cpuTxtFld.keyboardType = .decimalPad cpuTxtFld.precision = 4 netTxtFld.keyboardType = .decimalPad netTxtFld.precision = 4 otherTransferView.collection = [L10n.Resources.Setup.Transfer.irrevocably, L10n.Resources.Setup.Transfer.return] service = .init(account: account ?? "") preload() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) Accounts().isLocked = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) Accounts().isLocked = false } func reload(animated: Bool) { let cpu = service.performance[.cpu] cpuResourcesView.update(progress: CGFloat(cpu.availableProgress), title: cpu.kind.title, leftSubtitle: cpu.availableStr, rightSubtitle: cpu.maxStr) cpuResourcesView.layer.cornerRadius = 16 let cpuTxt = L10n.Resources.Performance.staked(cpu.staked) cpuStackedLbl.attributedText = cpuTxt.attributed(style: .medium, size: 16, color: Asset.textCoal.color) let cpuMeTxt = L10n.Resources.Performance.stakedByMe(cpu.stakedByMe) cpuStackedMeLbl.attributedText = cpuMeTxt.attributed(style: .medium, size: 14, color: Asset.textPebble.color) let cpuOthersTxt = L10n.Resources.Performance.stakedByOthers(cpu.stakedByOthers) cpuStackedOthersLbl.attributedText = cpuOthersTxt.attributed(style: .medium, size: 14, color: Asset.textPebble.color) let net = service.performance[.net] netResourcesView.update(progress: CGFloat(net.availableProgress), title: net.kind.title, leftSubtitle: net.availableStr, rightSubtitle: net.maxStr) netResourcesView.layer.cornerRadius = 16 let netStackedTxt = L10n.Resources.Performance.staked(service.performance[.net].staked) netStackedLbl.attributedText = netStackedTxt.attributed(style: .medium, size: 16, color: Asset.textCoal.color) let netMeTxt = L10n.Resources.Performance.stakedByMe(service.performance[.net].stakedByMe) netStackedMeLbl.attributedText = netMeTxt.attributed(style: .medium, size: 14, color: Asset.textPebble.color) let netOthersTxt = L10n.Resources.Performance.stakedByOthers(service.performance[.net].stakedByOthers) netStackedOthersLbl.attributedText = netOthersTxt.attributed(style: .medium, size: 14, color: Asset.textPebble.color) timerView.layer.cornerRadius = 8 if let refund = service.performance.refund { refundHeightConstraint.constant = 62 refundView.isHidden = false refundTitleLbl.attributedText = L10n.Resources.Setup.Refund.title(refund).attributed(style: .medium, size: 16, color: Asset.textCoal.color) refundTimeLbl.attributedText = (service.performance.refundTime ?? L10n.Resources.Setup.Refund.timeEmpty) .attributed(style: .bold, size: 14, color: Asset.textSnow.color) refundBtn.isEnabled = service.performance.refundTime == nil } else { refundHeightConstraint.constant = 0 refundView.isHidden = true refundTitleLbl.attributedText = L10n.Resources.Setup.Refund.title("").attributed(style: .medium, size: 16, color: Asset.textCoal.color) refundTimeLbl.attributedText = L10n.Resources.Setup.Refund.timeEmpty.attributed(style: .bold, size: 14, color: Asset.textSnow.color) refundBtn.isEnabled = false } let et1 = Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.contract == ApplicationEnvironment.shared().current.contract(.eosioToken) && $0.symbol.uppercased() == "EOS" }) var et2 = Network.Model.Token.eosioToken let sumOtherStackedCpu = service.staked.map { $0.cpu_weight.toDecimal() }.reduce(0, +) let sumOtherStackedNet = service.staked.map { $0.net_weight.toDecimal() }.reduce(0, +) et2.amount = service.performance[.net].stakedByMe.toDecimal() + service.performance[.cpu].stakedByMe.toDecimal() + sumOtherStackedCpu + sumOtherStackedNet let eosToken = (service.action == .stake) ? et1 : et2 tokenView.action = .cards(collection: nil, tokens: [], selectedMenu: nil, selected: eosToken, empty: nil, title: nil, nil) tokenView.isUserInteractionEnabled = false tokenTitleLabel.lzText = (service.action == .stake) ? L10n.Resources.Setup.avaliableToBuy : L10n.Resources.Setup.avaliableToUnstake otherSwitch.isOn = service.isOtherEnabled otherSwitch.superview?.isHidden = false if service.action == .stake { otherAccountTxtFld.action = .autocomplete( icon: Asset.commonArrowDown.image, title: L10n.Resources.Setup.Account.select, service: Account.Service.Contacts() ) { [weak self] menu in guard let self else { return } self.view.endEditing(true) self.service.otherAccount = menu.uuid } if service.otherAccount.isEmpty { otherAccountTxtFld.action?.selected = nil } else { otherAccountTxtFld.action?.selected = .menu(uuid: service.otherAccount, image: .account(service.otherAccount), title: service.otherAccount) } cpuTxtFld.lzText = "" netTxtFld.lzText = "" } else if service.action == .unstake { otherAccountTxtFld.action = .select( icon: Asset.commonArrowDown.image, title: L10n.Resources.Setup.Account.select, collection: service.staked.map({ $0.toMenu() }) ) { [weak self] menu in guard let self else { return } self.view.endEditing(true) self.service.otherAccount = menu.uuid } if service.otherAccount.isEmpty { otherAccountTxtFld.action?.selected = nil } else { otherAccountTxtFld.action?.selected = .menu(uuid: service.otherAccount, image: .account(service.otherAccount), title: service.otherAccount) } } else { otherAccountTxtFld.action?.selected = nil otherAccountTxtFld.action = .action(icon: Asset.commonArrowDown.image) } otherAccountTxtFld.update(animated: false) otherAccountTxtFld.isEnabled = service.action != nil otherTransferView.selectedIndex = service.transfer ? 0 : 1 cpuTxtFld.superview?.isHidden = false cpuTxtFld.set(value: service.cpuAmount, animated: animated) netTxtFld.superview?.isHidden = false netTxtFld.set(value: service.netAmount, animated: animated) submitBtn.superview?.isHidden = false update(animated: animated) } private func setupLabelsLzText() { if service.action == .unstake { if service.isOtherEnabled { let otherAccount = service.otherAccount if (otherAccount.isEmpty) { let cpu = service.staked.map { $0.cpu_weight.toDecimal() }.reduce(0, +).toString(max: 4, symbol: "EOS") let net = service.staked.map { $0.net_weight.toDecimal() }.reduce(0, +).toString(max: 4, symbol: "EOS") cpuTxtFld.lzText = L10n.Resources.Setup.Action.text(cpu) netTxtFld.lzText = L10n.Resources.Setup.Action.text(net) } else { let cpu = service.staked.first(where: { $0.to == otherAccount })?.cpu_weight.toDecimal().toString(max: 4, symbol: "EOS") ?? "" let net = service.staked.first(where: { $0.to == otherAccount })?.net_weight.toDecimal().toString(max: 4, symbol: "EOS") ?? "" cpuTxtFld.lzText = L10n.Resources.Setup.Action.text(cpu) netTxtFld.lzText = L10n.Resources.Setup.Action.text(net) } } else { cpuTxtFld.lzText = L10n.Resources.Setup.Action.text(service.performance[.cpu].stakedByMe) netTxtFld.lzText = L10n.Resources.Setup.Action.text(service.performance[.net].stakedByMe) } } else { cpuTxtFld.lzText = "" netTxtFld.lzText = "" } } private func getStakeSum() -> String { let value = service.performance[.cpu].staked.amount.toDecimal() + service.performance[.net].staked.amount.toDecimal() return value.toString(max: 4, symbol: "EOS") } private func update(animated: Bool) { otherLbl.attributedText = service.action == nil ? nil : (service.action == .stake ? L10n.Resources.Setup.Other.stake : L10n.Resources.Setup.Other.unstake) .attributed(style: .medium, size: 14, color: Asset.textGranite.color) setupLabelsLzText() otherAccountTxtFld.superview?.isHidden = !otherSwitch.isOn otherTransferView.superview?.isHidden = (!otherSwitch.isOn || service.action != .stake) submitBtn.isEnabled = service.isValid submitBtn.lzTitle = service.submitText let isAvailable = service.action == .stake ? service.balance >= (service.cpuAmount.toDecimal() + service.netAmount.toDecimal()) : cpuTxtFld.isFirstResponder ? service.getAvailableUnstakeAmount(isCpu: true) >= cpuTxtFld.value.toDecimal() : service.getAvailableUnstakeAmount(isCpu: false) >= netTxtFld.value.toDecimal() switch isAvailable { case false where self.cpuTxtFld.isFirstResponder: self.cpuTxtFld.error = L10n.Resources.Performance.Balance.error case false where self.netTxtFld.isFirstResponder: self.netTxtFld.error = L10n.Resources.Performance.Balance.error default: break } animated ? UIView.animate(withDuration: Animation.slow) { self.view.layoutIfNeeded() } : view.layoutIfNeeded() } @IBAction private func onRefund(_ : AnyObject?) { view.endEditing(true) AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() self.service.refund(privateKey: $0) { (error) in Loader.hide() Alert.notify(error) if error == nil { self.preload() } } } } @IBAction private func onOther(_ : AnyObject?) { view.endEditing(true) service.isOtherEnabled = otherSwitch.isOn update(animated: true) } @IBAction private func onOtherTransfer(_ : AnyObject?) { view.endEditing(true) service.transfer = otherTransferView.selectedIndex == 0 } @IBAction private func onSubmit(_ : AnyObject?) { view.endEditing(true) submitPopup() } private func submitPopup() { let value = service.netAmount.toDecimal() + service.cpuAmount.toDecimal() let eosVal = value.toString(max: 8, symbol: "EOS") let popupTitle: String let field1: String let field2: String if service.action == .stake { popupTitle = L10n.Resources.Setup.Confirm.stake field1 = L10n.Wallet.Send.Amount.send field2 = eosVal } else { popupTitle = service.isOtherEnabled ? L10n.Resources.Setup.Confirm.unstakeOther(service.otherAccount) : L10n.Resources.Setup.Confirm.unstake field1 = L10n.Swap.Investment.RemoveConfirmation.give field2 = eosVal } var views: [UIView] = [ .label( text: popupTitle .attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ) ] views.append(contentsOf: [.field(title: field1, text: field2)] ) Popup.show(title: L10n.P2p.Order.Confirm.title, views: views, submit: L10n.P2p.Order.Confirm.submit, in: self) { [weak self] ctrl in guard let self = self else { return } AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() self.service.submit(privateKey: $0) { (error) in self.preload() Loader.hide() Alert.notify(error) if error == nil { delayed(2) { self.preload() Wallet.Service.Tokens.shared.balances.fetch { _ in self.update(animated: true) } } self.dismiss(animated: true) } } } } } } extension ResourcesControllerSetupPerformance: CommonTextFieldDelegate { func textFieldDidChange(_ textField: CommonTextField) { switch textField { case cpuTxtFld: service.cpuAmount = textField.value case netTxtFld: service.netAmount = textField.value default: break } } }