Files
raspberry/iOS/Wallet/Sources/Resources/Controller/Setup/ResourcesControllerSetupRAM.swift
2023-01-17 15:10:50 +03:00

316 lines
12 KiB
Swift

//
// 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)
}
}