Files
2022-05-27 20:21:01 +03:00

385 lines
17 KiB
Swift

//
// CCCPCellExchangeRequest.swift
// PayCash
//
// Created by Saveliy Stavitsky on 8/5/20.
// Copyright © 2020 List. All rights reserved.
//
import UIKit
import class Resolver.Resolver
private typealias Contract = Network.Model.Contract
private typealias BlockchainAction = Network.Model.Blockchain.Action
extension TimeInterval {
func format(using units: NSCalendar.Unit) -> String? {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = units
formatter.unitsStyle = .abbreviated
formatter.zeroFormattingBehavior = .pad
return formatter.string(from: self)
}
}
class CCCPCellExchangeRequest: UITableViewCell {
@IBOutlet private var requestNumberLabel: UILabel!
@IBOutlet private var requestDateLabel: UILabel!
@IBOutlet private var yoouDescriptionLabel: UILabel!
@IBOutlet var aditionalInfoStackView: UIStackView!
@IBOutlet private var giveaditionalTitleLabel: UILabel!
@IBOutlet private var giveaditionalLabel: UILabel!
@IBOutlet private var getaditionalTitleLabel: UILabel!
@IBOutlet private var getaditionalLabel: UILabel!
@IBOutlet private var giveTitleLabel: UILabel!
@IBOutlet private var giveLabel: UILabel!
@IBOutlet private var getTitleLabel: UILabel!
@IBOutlet private var getLabel: UILabel!
@IBOutlet private var whoStackView: UIStackView!
@IBOutlet private var whoTitleLabel: UILabel!
@IBOutlet private var whoLabel: UILabel!
@IBOutlet private var refreshButton: UIButton!
@IBOutlet private var refreshTimerStackView: UIStackView!
@IBOutlet private var refreshTimerImageView: UIView!
@IBOutlet private var refreshTimerLabel: UILabel!
@IBOutlet private var refreshTimerDescriptionLabel: UILabel!
@IBOutlet private var descriptionLabel: UILabel!
@IBOutlet private var confirmButton: UIButton!
var parent: UIViewController?
private var request: CCCP.Model.ExchangeRequest!
func setup(request: CCCP.Model.ExchangeRequest) {
self.request = request
requestNumberLabel.lzText = "# \(request.id)"
let dateFormater = DateFormatter()
dateFormater.dateStyle = .medium
dateFormater.timeStyle = .medium
requestDateLabel.lzText = dateFormater.string(from: request.creationDate)
if let amountString = request.volume.split(separator: " ").first,
let amount = Double(amountString),
let symbol = request.volume.split(separator: " ").last?.replacingOccurrences(of: "CASH", with: "") {
refreshTimerStackView.isHidden = false
descriptionLabel.isHidden = false
whoStackView.isHidden = false
refreshButton.isHidden = false
refreshTimerImageView.backgroundColor = request.isExpired
? Asset.brick.color : Asset.forest.color
let currentTimestamp = Resolver.resolve(RuntimeConfiguration.self).currentTimestamp
var interval = request.expirationDate.timeIntervalSince1970 - currentTimestamp
if interval < 0 { interval = 0 }
refreshTimerLabel.lzText = interval.format(using: [.day, .hour, .minute])
aditionalInfoStackView.isHidden = true
if !request.isDebt && request.isOwner {
yoouDescriptionLabel.lzText = L10n.Cccp.ExchangeRequestCell.outgoingYouDescription
giveTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.outgoingGiveTitle
giveLabel.lzText = amount.toString(max: 5, symbol: "\(symbol)CASH")
getTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.outgoingGetTitle
getLabel.lzText = (amount * 0.97).toString(max: 2, symbol: symbol)
refreshTimerDescriptionLabel.lzText = L10n.Cccp.ExchangeRequestCell.outgoingTimerDescription
descriptionLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.outgoingNoTimeDescription
: L10n.Cccp.ExchangeRequestCell.outgoingTimeDescription
whoTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.outgoingWhoTitle
whoLabel.lzText = request.receiver
confirmButton.setTitle(L10n.Cccp.ExchangeRequestCell.Button.confirm, for: .normal)
refreshButton.setTitle(L10n.Cccp.ExchangeRequestCell.Button.reject, for: .normal)
} else if !request.isDebt && !request.isOwner {
yoouDescriptionLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingYouDescription
aditionalInfoStackView.isHidden = false
giveaditionalTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingAditionalGiveTitle
giveaditionalLabel.lzText = request.blockedCertificate?.symbol
getaditionalTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingAditionalGetTitle
getaditionalLabel.lzText = amount.toString(max: 5, symbol: "\(symbol)CASH")
giveTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingGiveTitle
giveLabel.lzText = amount.toString(max: 5, symbol: "\(symbol)CASH")
getTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingGetTitle
getLabel.lzText = (amount * 0.97).toString(max: 2, symbol: symbol)
refreshTimerDescriptionLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingTimerDescription
descriptionLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.incomingNoTimeDescription
: L10n.Cccp.ExchangeRequestCell.incomingTimeDescription
whoTitleLabel.lzText = L10n.Cccp.ExchangeRequestCell.incomingWhoTitle
whoLabel.lzText = request.ownedBy
confirmButton.setTitle(L10n.Cccp.ExchangeRequestCell.Button.confirm, for: .normal)
refreshButton.setTitle(L10n.Cccp.ExchangeRequestCell.Button.reject, for: .normal)
refreshButton.isHidden = !request.isExpired
} else {
yoouDescriptionLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.debtNoTimeYouDescription
: L10n.Cccp.ExchangeRequestCell.debtTimeYouDescription
giveTitleLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.debtNoTimeGiveTitle
: L10n.Cccp.ExchangeRequestCell.debtTimeGiveTitle
giveLabel.lzText = (Double(request.reward?.split(separator: " ").first ?? "") ?? 0)
.toString(max: 5, symbol: String(request.reward?.split(separator: " ").last ?? ""))
getTitleLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.debtNoTimeGetTitle
: L10n.Cccp.ExchangeRequestCell.debtTimeGetTitle
getLabel.lzText = ((Double(request.buyoutPrice?.split(separator: " ").first ?? "") ?? 0) * 1.03)
.toString(max: 8, symbol: String(request.buyoutPrice?.split(separator: " ").last ?? ""))
refreshTimerStackView.isHidden = request.isExpired
refreshTimerDescriptionLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.debtNoTimeTimerDescription
: L10n.Cccp.ExchangeRequestCell.debtTimeTimerDescription
descriptionLabel.isHidden = request.isExpired
descriptionLabel.lzText = request.isExpired
? L10n.Cccp.ExchangeRequestCell.debtNoTimeDescription
: L10n.Cccp.ExchangeRequestCell.debtTimeDescription
whoStackView.isHidden = true
confirmButton.setTitle(L10n.Cccp.ExchangeRequestCell.Button.buyDebt, for: .normal)
refreshButton.isHidden = true
}
}
}
@IBAction func refreshPressed(_ sender: Any) {
guard let parent = parent,
let id = request?.id,
let symbol = request?.volume.split(separator: " ").last.map(String.init) else { return }
let amount = Decimal(string: String(request?.volume.split(separator: " ").first ?? "0")) ?? 0
let description = request.isOwner
? L10n.Cccp.ExchangeRequestCell.Outgoing.Reject.description
: L10n.Cccp.ExchangeRequestCell.Incoming.Reject.description(amount.toString(max: 5), symbol)
var views: [UIView] = [
.label(text: description, style: .regular, size: 14, color: Asset.textCoal.color, numberOfLines: 0)
]
if request.isOwner {
views.append(.field(
title: L10n.Cccp.OutgoingExchangeRequest.returnTitle,
text: amount.receive(precision: 5).toString(max: 5, symbol: symbol)
))
views.append(.field(
title: L10n.Wallet.Send.Confirmation.fee,
text: amount.commission(precision: 5).toString(max: 5, symbol: symbol)
))
} else {
views.append(.criticalWarning(text: L10n.Cccp.ExchangeRequestCell.Incoming.Reject.alert))
}
Popup.show(
title: L10n.Common.Title.confirmation,
views: views,
submit: L10n.Common.Button.confirm,
in: parent
) { ctrl in
AccountViewAuthorize.showGetPrivateKey(in: parent) {
Loader.show(in: ctrl)
Network.Service.Blockchain.execute(
contract: .cash,
action: .cashClosereq,
data: ["id": "\(id)", "cash": symbol],
privateKeys: [$0]
) { result in
if case let .success(trxId) = result {
Account.Service.History.shared.current?.fetchUntil(trxId: trxId)
}
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true)
switch result {
case .success:
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
Wallet.Service.Tokens.shared.balances.fetch()
})
default: break
}
Alert.notify(NSError.error(result))
}
}
}
}
var tokens: [Network.Model.Token] = []
private func prepareBlockchainActions(
id: Int,
cash: String,
username: String,
certificateTokenGive: String) -> [(Contract, BlockchainAction, Codable)] {
var actions = [(Contract, BlockchainAction, Codable)]()
let cert = Network.Model.Token(symbol: certificateTokenGive, precision: 0, amount: 0, contract: Network.servers.current.contract(.cash))
//Create Token balances if not present
if let tokenGet = Wallet.Service.Tokens.shared.certificateToList(cert),
!tokens.contains(tokenGet) {
let openBalanceData = Network.Model.Blockchain.OpenBalance(
owner: username,
symbol: "8,\(tokenGet.symbol)",
ram_payer: username
)
actions.append((.list, .open, openBalanceData))
}
let buyBackData = ["id": "\(id)", "cash": cash, "buyer": username]
actions.append((.cash, .cashBuydebt, buyBackData))
return actions
}
func buyDebt(id: Int) {
guard let symbol = request?.buyoutPrice?.split(separator: " ").last.map(String.init),
let username = Accounts().current?.username else { return }
let actions = prepareBlockchainActions(
id: id,
cash: symbol,
username: username,
certificateTokenGive: (request?.volume ?? "")?.split(separator: " ").last.map(String.init) ?? ""
)
let amount = (Decimal(string: String(request?.buyoutPrice?.split(separator: " ").first ?? "0")) ?? 0) * 1.03
let garantSymbol = request?.volume ?? ""
let cert = Network.Model.Token(symbol: String(garantSymbol.split(separator: " ").last ?? ""), precision: 0, amount: 0, contract: Network.servers.current.contract(.cash))
let secondSymbol = Wallet.Service.Tokens.shared.certificateToList(cert)?.symbol ?? ""
Popup.show(
title: L10n.Common.Title.confirmation,
views: [
.label(text: L10n.Cccp.SoldExchangeRequests.description, style: .regular, size: 14, color: Asset.textCoal.color, numberOfLines: 0),
.field(
title: L10n.Cccp.SoldExchangeRequests.giveTitle,
text: amount.toString(max: 5, symbol: symbol)
),
.field(
title: L10n.Cccp.SoldExchangeRequests.getTitle,
text: "100 \(secondSymbol)"
)
],
submit: L10n.Common.Button.confirm
) { [unowned self] ctrl in
AccountViewAuthorize.showGetPrivateKey(in: ctrl) {
Loader.show(in: ctrl)
Network.Service.Blockchain.execute(actions: actions, privateKeys: [$0]) { result in
if case let .success(trxId) = result {
Account.Service.History.shared.current?.fetchUntil(trxId: trxId)
}
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true) {
self.parent?.dismiss(animated: false)
}
// DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
// self.parent?.service.fetch()
// })
switch result {
case .success:
self.confirmButton.isEnabled = false
self.confirmButton.tintColor = Asset.dark.color
self.confirmButton.layer.borderColor = Asset.lightGray.color.cgColor
default: break
}
Alert.notify(NSError.error(result))
}
}
}
}
@IBAction func confirmPressed(_ sender: Any) {
guard let id = request?.id else { return }
if request.isDebt {
buyDebt(id: id)
return ()
}
guard let symbol = request?.volume.split(separator: " ").last.map(String.init) else { return }
let amount = (Double(request?.volume.split(separator: " ").first ?? "0") ?? 0) * 0.97
let description = request.isOwner
? L10n.Cccp.ExchangeRequestCell.Outgoing.Confirm.description(amount.toString(max: 5), symbol.replacingOccurrences(of: "CASH", with: ""))
: L10n.Cccp.ExchangeRequestCell.Incoming.Confirm.description(amount.toString(max: 5), symbol.replacingOccurrences(of: "CASH", with: ""))
let warningText = request.isOwner
? L10n.Cccp.ExchangeRequestCell.Outgoing.Confirm.alert
: L10n.Cccp.ExchangeRequestCell.Incoming.Confirm.alert
Popup.show(
title: L10n.Common.Title.confirmation,
views: [
.label(text: description, style: .regular, size: 14, color: Asset.textCoal.color, numberOfLines: 0),
.criticalWarning(text: warningText)
],
submit: L10n.Common.Button.confirm
) { [unowned self] ctrl in
AccountViewAuthorize.showGetPrivateKey(in: ctrl) {
Loader.show(in: ctrl)
Network.Service.Blockchain.execute(contract: .cash, action: .cashCompletereq, data: ["id": "\(id)", "cash": symbol], privateKeys: [$0]) { result in
if case let .success(trxId) = result {
Account.Service.History.shared.current?.fetchUntil(trxId: trxId)
}
Loader.hide(in: ctrl)
ctrl.dismiss(animated: true) {
self.parent?.dismiss(animated: false)
}
// DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
// self.parent?.service.fetch()
// })
switch result {
case .success:
self.confirmButton.isEnabled = false
self.confirmButton.tintColor = Asset.dark.color
self.confirmButton.layer.borderColor = Asset.lightGray.color.cgColor
default: break
}
Alert.notify(NSError.error(result))
}
}
}
}
@IBAction func chatPressed(_ sender: Any) {
guard let parent = parent,
let user = Accounts().current,
let username = (!request.isDebt && request.isOwner) ? request?.receiver : request?.ownedBy,
username != Accounts().current?.username else { return }
AccountViewAuthorize.showGetPrivateKey(in: parent) {
guard let msgsHistoryService = try? CryptoChat.Service.MsgsHistory(username: user.username, encryptionKey: $0) else { return }
let chatViewController = CryptoChatControllerChat()
chatViewController.username = username
chatViewController.msgsHistoryService = msgsHistoryService
chatViewController.unreadCount = 0
parent.navigationController?.pushViewController(chatViewController, animated: true)
}
}
}