// // ResourcesControllerSetupRAM.swift // Wallet // // Created by Igor Danich on 14.08.2020. // Copyright © 2020 List. All rights reserved. // import UIKit class ResourcesControllerSetupRAM: UIViewController { @IBOutlet private weak var tokenView: CommonViewCard! @IBOutlet private weak var ramInfoView: ResourceInfoItemView! @IBOutlet private weak var otherSwitch: UISwitch! @IBOutlet private weak var otherLbl: UILabel! @IBOutlet private weak var otherAccountTxtFld: CommonTextField! @IBOutlet private weak var ramTxtFld: CommonTextField! @IBOutlet private weak var submitBtn: CommonButtonAction! @IBOutlet weak var tokenContainerView: UIView! @IBOutlet weak var stackViewHeightConstraint: NSLayoutConstraint! @IBOutlet weak var amountLabelStackContainer: UIStackView! @IBOutlet weak var amountRamLabel: UILabel! @IBOutlet weak var textfieldsStackView: UIStackView! @IBOutlet weak var textField1: CommonTextField! @IBOutlet weak var textfield2: CommonTextField! private var account: String? { Accounts().current?.name } private enum Locals { static let minimumRamAmount: Decimal = 0.02 } var action: Resources.Service.Setup.RAM.Action! var performance: Resources.Service.Popup.Statistics! var service: Resources.Service.Setup.RAM! { didSet { service.didUpdate = { [weak self] in self?.update(animated: true) } service.didReload = { [weak self] in if let self = self { Loader.hide(in: self) } } service.action = action service.clear(force: false) } } private func preload() { ramTxtFld.value = "" otherSwitch.isOn = false service.fetch { error in if case .dataError = error { Alert.error(text: L10n.Main.NoInternet.text) } } service.clear(force: false) performance.fetch() if let token = Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.symbol.contains(words: "EOS")}) { service.token = token } else { service.token = Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.symbol.contains(words: "USDCASH")}) } Loader.show(in: self) } override func viewDidLoad() { super.viewDidLoad() service = .init(account: account ?? "") preload() title = action == .buy ? L10n.Resources.Setup.Buy.ram : L10n.Resources.Setup.Sell.ram textField1.keyboardType = .decimalPad textfield2.keyboardType = .decimalPad textField1.delegate = self textfield2.delegate = self ramTxtFld.keyboardType = .decimalPad otherAccountTxtFld.action = .autocomplete( icon: Asset.commonArrowDown.image, title: L10n.Resources.Setup.Account.select, service: Account.Service.Contacts() ) { [weak self] menu in self?.view.endEditing(true) self?.service.otherAccount = menu.uuid } service.fetch { error in if case .dataError = error { Alert.error(text: L10n.Main.NoInternet.text) } } } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) Accounts().isLocked = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) Accounts().isLocked = false } private func update(animated: Bool) { setupRamView() tokenView.action = .cards(tokens: service.balances.filter({ token in service.ramPrices.contains(where: { $0.code == token.contract && $0.token == token.symbol && token.amount >= 0 }) }), selected: service.token) { [weak self] menu in self?.view.endEditing(true) self?.service.token = self?.service.balances.object(menu: menu) self?.textField1.precision = self?.service.balances.object(menu: menu)?.precision self?.textfield2.precision = 2 } if action == .sell { otherSwitch.superview?.isHidden = true tokenContainerView.isHidden = true amountLabelStackContainer.isHidden = true textfieldsStackView.isHidden = true stackViewHeightConstraint.constant = -110 stackViewHeightConstraint.isActive = true } else { textField1.lzTitle = service.token?.symbol ?? "" textfield2.lzTitle = "Kb" if !textField1.isFirstResponder { textField1.value = service.amountSend } if !textfield2.isFirstResponder { textfield2.value = service.amountRecieve } self.ramTxtFld.isHidden = true } ramTxtFld.precision = service.ramPrecision ramTxtFld.lzPlaceholder = action == .buy && service.buy == .eos ? L10n.Resources.Setup.Placeholder.eos : L10n.Resources.Setup.Placeholder.kb if action == .sell { ramTxtFld.lzText = performance.performance[.ram].availableKbString ramTxtFld.lzTitle = L10n.Resources.Setup.Ram.title } submitBtn.isEnabled = service.isValid submitBtn.lzTitle = service.submitText otherAccountTxtFld.superview?.isHidden = !otherSwitch.isOn if !otherAccountTxtFld.isFirstResponder, service.otherAccount.isEmpty { otherAccountTxtFld.action?.selected = nil otherAccountTxtFld.value = service.otherAccount } self.ramTxtFld.error = nil if !self.ramTxtFld.value.isEmpty, !self.service.isValid { self.ramTxtFld.error = self.ramTxtFld.value.toDecimal() < Locals.minimumRamAmount ? L10n.Resources.Performance.Balance.incorrectMinimum : L10n.Resources.Performance.Balance.error } self.textField1.error = (service.isValidAmount || self.textField1.value.isEmpty || self.textField1.value.toDecimal().isZero) ? nil : L10n.Resources.Performance.Balance.error animated ? UIView.animate(withDuration: Animation.slow) { self.view.layoutIfNeeded() } : view.layoutIfNeeded() } private func setupRamView() { let p = performance.performance[.ram] ramInfoView.update(progress: CGFloat(p.availableProgress), title: p.kind.title, leftSubtitle: p.availableStr, rightSubtitle: p.maxStr) ramInfoView.makeShadow() } @IBAction private func onBuy(_ : AnyObject?) { view.endEditing(true) ramTxtFld.set(value: service.ramAmount, animated: true) update(animated: true) } @IBAction private func onOther(_ : AnyObject?) { view.endEditing(true) service.isOtherEnabled = otherSwitch.isOn ramTxtFld.set(value: service.ramAmount, animated: true) update(animated: true) } @IBAction private func onSubmit(_ : AnyObject?) { view.endEditing(true) if service.action == .buy { self.submitPopup(ramPrice: Decimal(string: self.textField1.value) ?? 0) } else { Task { Loader.show() let ramPrice = await service.getPricePerKilobyte(kbs: service.ramAmount.toDecimal()) Loader.hide() self.submitPopup(ramPrice: ramPrice ?? 0) } } } private func submitPopup(ramPrice: Decimal) { let kbVal = service.ramAmount.toDecimal().toString(max: 2, symbol: L10n.Resources.Performance.Unit.kb) let popupTitle: String let field11: String let field12: String let field21: String let field22: String if service.action == .buy { popupTitle = service.isOtherEnabled ? L10n.Resources.Setup.Confirm.Buy.ramOther(service.otherAccount) : L10n.Resources.Setup.Confirm.Buy.ram field11 = L10n.Wallet.Send.Amount.send field12 = "\(service.amountSend) \(service.token?.symbol ?? "")" field21 = L10n.Wallet.Send.Amount.get field22 = "\(service.amountRecieve) \(L10n.Resources.Performance.Unit.kb)" // switch service.buy { // case .eos: // field12 = service.ramAmount.toDecimal().toString(max: 4, symbol: service.token?.symbol ?? "") // field22 = (service.ramAmount.toDecimal()/ramPrice).toString(max: 2, symbol: L10n.Resources.Performance.Unit.kb) // case .kb: // field12 = ramPrice.toString(max: 4, symbol: service.token?.symbol ?? "") // field22 = kbVal // } } else { popupTitle = L10n.Resources.Setup.Confirm.Sell.ram field11 = L10n.Swap.Investment.RemoveConfirmation.give field12 = kbVal field21 = L10n.Swap.Investment.RemoveConfirmation.get field22 = (service.ramAmount.toDecimal() * ramPrice * 1024).toString(max: 4, symbol: "EOS") } var views: [UIView] = [ .label( text: popupTitle .attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ) ] views.append(contentsOf: [.field(title: field11, text: field12), .field(title: field21, text: field22)] ) 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 } Loader.show() AccountViewAuthorize.showGetPrivateKey(in: self) { self.service.submit(privateKey: $0) { (error) in Loader.hide() if error == nil { Wallet.Service.Tokens.shared.balances.fetch() self.dismiss(animated: true) { Loader.show() } delayed(4) { self.preload() Wallet.Service.Tokens.shared.balances.fetch { result in Loader.hide() guard case .success = result else { return } self.update(animated: true) Alert.success() } } } else { Popup.hide() guard !(error is BlockchainError) else { return } self.showError() } } } } } private func showError() { let errorVC = PopupNotificationController(title: L10n.Resources.Setup.Buy.errorTitle, description: L10n.Resources.Setup.Buy.errorTryAgain, buttonText: L10n.Resources.Setup.Buy.errorComplete, icon: Asset.commonErrorAlert.image) self.present(errorVC, animated: true) } } extension ResourcesControllerSetupRAM: CommonTextFieldDelegate { func textFieldDidChange(_ textField: CommonTextField) { if service.action == .sell { service.ramAmount = textField.value } switch textField { case textField1: service.update(send: textField.value) case textfield2: service.update(receive: textField.value) default: break } } } extension UIView { func makeShadow() { self.layer.masksToBounds = false self.layer.cornerRadius = 16 self.layer.shadowColor = UIColor.black.cgColor self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath self.layer.shadowOpacity = 0.10 self.layer.shadowRadius = 4.0 self.layer.shadowOffset = CGSize(width: 0, height: 0) } }