385 lines
17 KiB
Swift
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)
|
|
}
|
|
}
|
|
}
|