// // CCCPMainViewController.swift // List // // Created by Saveliy Stavitsky on 7/13/20. // Copyright © 2020 Igor Danich. All rights reserved. // import UIKit import class Resolver.Resolver class CCCPMainViewController: UIViewController { @IBOutlet private var certificatesStackView: UIStackView! @IBOutlet var topViewStak: UIStackView! @IBOutlet private weak var offset: NSLayoutConstraint! @IBOutlet var segmentedControl: UISegmentedControl! @IBOutlet var segmentStackView: UIStackView! @IBOutlet private weak var requestsTableView: UITableView! @IBOutlet private weak var tableView: UITableView! let service = CCCP.Service.Priority() let cashBillsService = CashBillsService() var requestsService: CCCP.Service.ExchangeRequests { Resolver.resolve() } @IBOutlet var generateTokensButton: UIButton! @IBOutlet var destroyTokensButton: UIButton! @IBOutlet var generateTokensMainOptionView: MainOptionView! @IBOutlet var destroyTokensMainOptionView: MainOptionView! @IBOutlet var outgoingExchangeRequestsMainOptionView: MainOptionView! @IBOutlet var incomingExchangeRequestsMainOptionView: MainOptionView! @IBOutlet var soldExchangeRequestsMainOptionView: MainOptionView! private func last(income: Bool) -> AccountAction? { Account.Service.History.shared.current?.actions .filter("account = '\(Network.servers.current.contract(.cash))'") .filter("name = '\(income ? "getincome" : "getroyalties")'") .sorted(by: \.accountActionId, ascending: true) .last } // private func lastValues(trxId: String) -> [AccountAction] { // Account.Service.History.shared.current?.actions(in: trxId).filter("name = 'notify'").map({ $0 }) ?? [] // } private var lastIncome: AccountAction? { last(income: true) } private var lastIncomeDate: Date { lastIncome?.timestamp ?? Date(timeIntervalSince1970: 0) } // private var lastIncomeValues: [AccountAction] { lastValues(trxId: lastIncome?.trxId ?? "") } private var lastRoyalty: AccountAction? { last(income: false) } private var lastRoyaltyDate: Date { lastRoyalty?.timestamp ?? Date(timeIntervalSince1970: 0) } // private var lastRoyaltyValues: [AccountAction] { lastValues(trxId: lastRoyalty?.trxId ?? "") } @IBOutlet var myDividendsButton: CommonButtonAction! @IBOutlet var myRoyaltiesButton: CommonButtonAction! @IBOutlet var priorityButton: CommonButtonAction! @IBOutlet var rulesButton: CommonButtonAction! private lazy var noAccountsView: CommonViewEmpty = { CommonViewEmpty( // title: L10n.Cccp.Main.NoAccounts.title, title: L10n.Account.Empty.text, text: L10n.Cccp.Main.NoAccounts.info, image: Asset.accountEmpty.image, submit: L10n.Account.Empty.submit ) { [weak self] in guard let self = self else { return } AccountController.showPopup(in: self) } }() private lazy var certificatesEmptyView: CommonViewEmpty = { CommonViewEmpty( title: L10n.Cccp.Main.Certificates.Empty.title, text: L10n.Cccp.Main.Certificates.Empty.description, image: Asset.cccpMainCertificatesEmpty.image) }() private lazy var requestsEmptyView: CommonViewEmpty = { CommonViewEmpty( text: L10n.Cccp.Main.Requests.Empty.description, image: Asset.cccpRequestsEmpty1.image) }() private let refresh = UIRefreshControl() @IBAction func segmentChange(_ sender: Any) { requestsTableView.reloadData() self.requestsEmptyView.alpha = (self.requests.isEmpty ? 1 : 0) } override func viewDidLoad() { super.viewDidLoad() generateTokensButton.titleLabel?.textAlignment = .center generateTokensButton.setTitle(L10n.Cccp.Main.Header.Button.generateTokens, for: .normal) generateTokensButton.titleLabel?.font = Font.font(style: .medium, size: 14) generateTokensButton.setTitleColor(Asset.textDeepWater.color, for: .normal) destroyTokensButton.setTitle(L10n.Cccp.Main.Header.Button.destroyTokens, for: .normal) destroyTokensButton.titleLabel?.font = Font.font(style: .medium, size: 14) destroyTokensButton.setTitleColor(Asset.textDeepWater.color, for: .normal) destroyTokensButton.titleLabel?.textAlignment = .center generateTokensButton.alignTextBelow() destroyTokensButton.alignTextBelow() navigationItem.title = L10n.Cccp.Main.headerTitle navigationController?.interactivePopGestureRecognizer?.delegate = nil // navigationItem.rightBarButtonItem = .info { Alert.hint(text: L10n.Cccp.Main.popupDescription) } navigationItem.leftBarButtonItem = .pop(self) tableView.register(cell: CommonCellCard.self) tableView.allowsSelection = false Notification.subscribe(name: .didUpdateBalances) { [weak self] _ in guard let self = self else { return } Loader.hide(in: self.view) self.refresh.endRefreshing() self.tableView.reloadData() self.cashBillsService.fetchBills { self.tableView.reloadData() } } refresh.addTarget(self, action: #selector(refreshViewApearance), for: .valueChanged) tableView.addSubview(refresh) segmentedControl.setTitle(L10n.Cccp.Main.Segment.myOrders, forSegmentAt: 0) segmentedControl.setTitle(L10n.Cccp.Main.Segment.debt, forSegmentAt: 1) requestsTableView.allowsSelection = false requestsTableView.showsVerticalScrollIndicator = false requestsTableView.separatorStyle = .none requestsTableView.register(cell: CCCPCellExchangeRequest.self) generateTokensMainOptionView .addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(generateTokensPressed))) destroyTokensMainOptionView .addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(destroyTokensPressed))) outgoingExchangeRequestsMainOptionView .addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(outgoingExchangeRequestsPressed))) incomingExchangeRequestsMainOptionView .addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(incomingExchangeRequestsPressed))) soldExchangeRequestsMainOptionView .addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(soldExchangeRequestsPressed))) Notification.subscribe(name: .didUpdateCryptocashExchangeRequests) { [weak self] _ in DispatchQueue.main.async { self?.requestsTableView.reloadData() self?.requestsEmptyView.alpha = ((self?.requests.isEmpty ?? true) ? 1 : 0) } } NotificationCenter.default.addObserver(self, selector: #selector(onAccountChange(_:)), name: .didChangeAccount, object: nil) self.setupEmptyViews() cashBillsService.fetchBills { [weak self] in print(self?.cashBillsService.collection.count) print(self?.cashBillsService.collection) self?.tableView.reloadData() } } private func setupEmptyViews() { self.setupRequestsEmptyView() self.setupCertificatesEmptyView() } private func setupRequestsEmptyView() { requestsEmptyView.frame = CGRect(x: 0, y: 50, width: requestsTableView.frame.width, height: requestsTableView.frame.height - 50) requestsEmptyView.autoresizingMask = [.flexibleWidth, .flexibleHeight] requestsEmptyView.translatesAutoresizingMaskIntoConstraints = true requestsEmptyView.alpha = 0 requestsTableView.addSubview(requestsEmptyView) } private func setupCertificatesEmptyView() { certificatesEmptyView.frame = CGRect(x: 0, y: 50, width: tableView.frame.width, height: tableView.frame.height - 50) certificatesEmptyView.autoresizingMask = [.flexibleWidth, .flexibleHeight] certificatesEmptyView.translatesAutoresizingMaskIntoConstraints = true certificatesEmptyView.alpha = 1 tableView.addSubview(certificatesEmptyView) } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() noAccountsView.frame = .init( x: 0, y: 0, width: view.frameWidth, height: view.frameHeight - (navigationController?.tabBarController?.tabBar.frameHeight ?? 0) ) } @objc func onAccountChange(_ notification: Notification) { refreshViewApearance() } @objc func refreshViewApearance() { Accounts().exists ? noAccountsView.removeFromSuperview() : view.addSubview(noAccountsView) navigationController?.setNavigationBarHidden(!Accounts().exists, animated: false) getBalance() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if ((UIApplication.shared.windows.first!.rootViewController as? MainController)?.barNav.items?.count ?? 0) > 1 { (UIApplication.shared.windows.first!.rootViewController as? MainController)?.barNav.popItem(animated: true) } refreshViewApearance() } var isShareholder = false func getBalance() { service.fetch() // requestsService.fetch() CCCP.Service.Shareholders.shared.fetch { [weak self] in self?.myRoyaltiesButton.isHidden = !$0 } Wallet.Service.Tokens.shared.balances.fetch() } @objc func generateTokensPressed() { let generateTokensViewController = StoryboardScene.Cccp.cccpControllerGenerateTokens.instantiate() navigationController?.pushViewController(generateTokensViewController, animated: true) } @objc func destroyTokensPressed() { let destroyTokensViewController = StoryboardScene.Cccp.cccpControllerDestroyTokens.instantiate() destroyTokensViewController.cashBillsService = self.cashBillsService navigationController?.pushViewController(destroyTokensViewController, animated: true) } @objc func outgoingExchangeRequestsPressed() { let requestsViewController = CCCPControllerExchangeRequests() requestsViewController.type = .outgoingRequests navigationController?.pushViewController(requestsViewController, animated: true) } @objc func incomingExchangeRequestsPressed() { let requestsViewController = CCCPControllerExchangeRequests() requestsViewController.type = .incomingRequests navigationController?.pushViewController(requestsViewController, animated: true) } @objc func soldExchangeRequestsPressed() { let requestsViewController = CCCPControllerExchangeRequests() requestsViewController.type = .soldRequests navigationController?.pushViewController(requestsViewController, animated: true) } private func getDividendsPressed(isIncome: Bool) { guard let username = Accounts().current?.username else { return } AccountViewAuthorize.showGetPrivateKey(in: self) { [unowned self] privateKey in Loader.show() Network.Service.Blockchain.execute(contract: .cash, action: isIncome ? .cashGetdividends : .cashGetroyalties, data: ["owner": username, "ram_payer": username], privateKeys: [privateKey]) { [unowned self] result in switch result { case let .success(trxId): Account.Service.History.shared.current?.fetchUntil(trxId: trxId) { Loader.hide() let alertPopup = CCCPViewSuccessDividends() alertPopup.update(actions: $0.filter("name = 'notify'").map({ $0 }), id: trxId) // let viewController = CommonViewControllerPopUp(title: L10n.Cccp.Main.dividendsGot, view: alertPopup) // self.present(viewController, animated: true) } case let .failure(error): Loader.hide() Alert.error(error) } } } } private func lastTimeToString(time: Date) -> String { let dateFormater = DateFormatter() dateFormater.dateStyle = .medium dateFormater.timeStyle = .none let timeFormater = DateFormatter() timeFormater.dateStyle = .none timeFormater.timeStyle = .short if time.timeIntervalSince1970 > 0 { return L10n.Cccp.Main .dividendsLastTimeTitle(dateFormater.string(from: time), timeFormater.string(from: time)) } else { return "- -" } } private func showDividendsPopup(isIncome: Bool) { let title = UILabel() title.text = L10n.Cccp.Main.dividendsLastGetTitle title.font = FontFamily.GolosUI.medium.font(size: 14) title.textColor = Asset.dark.color let timeLabel = UILabel() timeLabel.text = lastTimeToString(time: isIncome ? lastIncomeDate : lastRoyaltyDate) timeLabel.font = FontFamily.GolosUI.regular.font(size: 14) timeLabel.textColor = Asset.dark.color let view = UIStackView(subviews: [title, timeLabel], axis: .vertical, distribution: .fill, alignment: .leading, spacing: 12) view.addWidthConstraint(width: UIScreen.main.bounds.width - 48) var calendar = Calendar.current calendar.timeZone = TimeZone(secondsFromGMT: 0)! // Popup.show( // title: isIncome ? L10n.Cccp.Main.dividendsPopupTitle : L10n.Cccp.Main.royaltiesPopupTitle, // image: Asset.cccpMainDividends.image, // description: isIncome ? L10n.Cccp.Main.dividendsPopupDesription : L10n.Cccp.Main.royaltiesPopupDesription, // submit: L10n.Common.Button.confirm, // submitEnabled: !calendar.isDateInToday(isIncome ? lastIncomeDate : lastRoyaltyDate), // in: self // ) { ctrl in // ctrl.dismiss(animated: true) // self.getDividendsPressed(isIncome: isIncome) // } } @IBAction func myDividendsPressed(_ sender: Any) { showDividendsPopup(isIncome: true) } @IBAction func myRoyaltiesPressed(_ sender: Any) { showDividendsPopup(isIncome: false) } @IBAction func priorityPressed(_ sender: Any) { let title = UILabel() title.text = L10n.Cccp.Main.priorityPopupDescription title.font = FontFamily.GolosUI.medium.font(size: 14) title.textColor = Asset.dark.color let priorityTokens = service.allPriority.filter({ $0.value }).map({ $0.key }) let tokensLabel = UILabel() tokensLabel.numberOfLines = 0 tokensLabel.textAlignment = .center tokensLabel.text = priorityTokens.count > 0 ? priorityTokens.joined(separator: ", ") : "- -" tokensLabel.font = FontFamily.GolosUI.regular.font(size: 14) tokensLabel.textColor = Asset.dark.color Popup.show( title: L10n.Cccp.Main.priorityPopupTitle, image: Asset.cccpMainPriorityFire.image, views: [title, tokensLabel], submit: L10n.Common.change, in: self ) { ctrl in ctrl.dismiss(animated: true) let viewController = StoryboardScene.Cccp.cccpControllerPriority.instantiate() viewController.service = self.service self.navigationController?.pushViewController(viewController, animated: true) } } @IBAction func rulesPressed(_ sender: Any) { UIApplication.shared.open(URL(string: "http://apple.com")!) } @IBAction func generatePressed(_ sender: Any) { generateTokensPressed() } @IBAction func destroyPressed(_ sender: Any) { destroyTokensPressed() } @IBAction func createExchangeRequestPressed(_ sender: Any) { let createRequestViewController = StoryboardScene.Cccp.cccpControllerCreateExchangeRequest.instantiate() navigationController?.pushViewController(createRequestViewController, animated: true) } } extension CCCPMainViewController: UITableViewDelegate, UITableViewDataSource { var requests: [CCCP.Model.ExchangeRequest] { segmentedControl.selectedSegmentIndex == 0 ? (requestsService.requests) : requestsService.debts } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let requestsTableViewCount = self.requests.count let certificatesTableViewCount = Wallet.Service.Tokens.shared.balances.collection .filter(\.isCertificate) .filter({ cert in (cashBillsService.collection.filter({ $0.gtoken_out.quantity.symbol == cert.symbol }) ?? []).count > 0 }).count print(cashBillsService.collection) self.certificatesEmptyView.alpha = (certificatesTableViewCount == 0) ? 1 : 0 self.requestsEmptyView.alpha = (requestsTableViewCount == 0) ? 1 : 0 return tableView.tag == 1 ? certificatesTableViewCount : requestsTableViewCount } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if tableView.tag == 1 { let cell = tableView.dequeueReusableCell(CommonCellCard.self, indexPath: indexPath) let token = Wallet.Service.Tokens.shared.balances.collection .filter(\.isCertificate) .filter({ cert in (cashBillsService.collection.filter({ $0.gtoken_out.quantity.symbol == cert.symbol }) ?? []).count > 0 })[indexPath.row] cell.cardView.cashBillsService = cashBillsService cell.cardView.rightAction = { tableView.beginUpdates() tableView.endUpdates() } cell.cardView.middleAction = { tableView.beginUpdates() cell.cardView.changeBillsState() tableView.endUpdates() } cell.cardView.selectCashBillAction = { [weak self] in let ctrl = CashBillDetailsViewController.loadFromNib() ctrl.bill = $0 ctrl.cashBillsService = self?.cashBillsService self?.navigationController?.pushViewController(ctrl, animated: true) } cell.cardView.action = .action(icon: Asset.commonArrowRight.image, empty: token.toMenu()) { [unowned self]_ in let ctrl = StoryboardScene.Wallet.history.instantiate() ctrl.service.token = Wallet.Service.Tokens.shared.balances.collection.filter(\.isCertificate)[indexPath.row] navigationController?.pushViewController(ctrl, animated: true) } return cell } else { let cell = tableView.dequeueReusableCell(CCCPCellExchangeRequest.self, indexPath: indexPath) cell.tokens = Wallet.Service.Tokens.shared.balances.collection cell.setup(request: requests[indexPath.row]) cell.parent = self return cell } } } extension CCCPMainViewController: UIScrollViewDelegate { var buttonsHeight: CGFloat { 94 } var topViewHeight: CGFloat { topViewStak.frame.height + 36 } func scrollViewDidScroll(_ scrollView: UIScrollView) { // guard service.deals.collection.count > 0 else { return } if scrollView == requestsTableView { let value = offset.constant - scrollView.contentOffset.y if value > buttonsHeight && value < topViewHeight { scrollView.contentOffset = .zero offset.constant = value // topView.alpha = 0 } else if value <= buttonsHeight { offset.constant = buttonsHeight // topView.alpha = 1 } else if value >= topViewHeight { offset.constant = topViewHeight // topView.alpha = 0 } view.layoutIfNeeded() } // else if scrollView == collectionView { // pageControl.currentPage = Int( // CGFloat(pageControl.numberOfPages)*(scrollView.contentOffset.x + scrollView.frameWidth/2)/scrollView.contentSize.width // ) // } } }