Files
raspberry/iOS/Wallet/Sources/Main/Controller/MainController.swift
T
2022-12-06 23:00:21 +03:00

766 lines
36 KiB
Swift

//
// MainControllerRoot.swift
// List
//
// Created by Saveliy Stavitsky on 7/14/20.
// Copyright © 2020 Igor Danich. All rights reserved.
//
import UIKit
// import MaterialComponents.MaterialBottomSheet
import Branch
import struct Resolver.Injected
import Alamofire
import class RealmSwift.NotificationToken
import WebKit
import WalletKit
import WalletFoundation
import Combine
extension UserDefaults {
@objc dynamic var chatsReadCount: [String: Int] {
return (dictionary(forKey: "chatsReadCount") as? [String: Int]) ?? [:]
}
}
extension UIViewController {
// swiftlint:disable force_cast
var mainController: MainController { UIApplication.shared.windows.first?.rootViewController as! MainController }
}
final class MainController: UIViewController {
@IBOutlet var headerView: UIView!
@IBOutlet var accountButton: UIButton!
@IBOutlet var accountBarButton: UIBarButtonItem!
@IBOutlet var backButton: UIButton!
@IBOutlet var barNav: UINavigationBar!
@IBOutlet var headerSeperatorView: UIView!
@IBOutlet weak var resourcesSwitch: CommonSwitch!
@IBOutlet private weak var resourcesBtn: UIBarButtonItem!
@IBOutlet weak var settingsGearButton: UIBarButtonItem!
@IBOutlet private weak var offset: NSLayoutConstraint!
@IBOutlet var inviteView: MainViewInvite!
private let service = Main.Service()
private var notificationTokens = [NotificationToken]()
private var cancellables = Set<AnyCancellable>()
private var hasTitle: Bool {
guard let barNavItems = self.barNav.items else { return false }
let titlesOfItems = barNavItems.compactMap { $0.title }
return !titlesOfItems.isEmpty
}
var content: MainControllerContent { child()! }
let timerFreeTx = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { timer in
timer.tolerance = 0.5
Accounts().fetchQuota()
}
let timerBalances = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in
timer.tolerance = 0.2
if Wallet.Service.Tokens.shared.balances.collection.count == 0 {
Wallet.Service.Tokens.shared.balances.fetch()
} else {
timer.invalidate()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.accountBarButton.customView = self.accountButton
self.headerView.layer.shadowColor = Asset.lightGray.color.cgColor
self.configureAccountButton()
self.configureQRButton()
self.inviteView.changeVisibility(Accounts().hasActiveAccounts)
self.updateMsgCount()
// if !UserDefaults.standard.bool(forKey: "isFreeTransactionsOn") {
// changeFreeSwitchState()
// }
// Network.shared.onReabilityChange = { }
Loader.show()
Account.Service.History.shared.current?.fetch()
NotificationCenter.default.addObserver(
self,
selector: #selector(self.onAccountChange),
name: .didChangeAccount,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(self.onAccountChange),
name: .didUpdateLock,
object: nil
)
Notification.subscribe(bag: bag, name: .didUpdateAuthorization) { [unowned self]_ in
self.setupSubscriptions()
guard let link = deepLink else { return }
self.process(deepLink: link)
self.deepLink = nil
}
Notification.subscribe(bag: bag, name: .didUpdateAccountQuota) { [unowned self]_ in
self.resourcesSwitch.isActive = Accounts().hasActiveAccounts
self.resourcesSwitch.lzTextFrontSelected = Accounts().hasActiveAccounts ? "\(Accounts().quota.count)" : ""
self.resourcesSwitch.set(isSelected: Accounts().quota.isEnabled, animated: true)
}
Notification.subscribe(bag: bag, name: .didUpdateReachability) { _ in
guard !Network.Service().isReachable else { return }
Alert.error(text: L10n.Main.NoInternet.text)
}
self.inviteView.didLockedFunds = { [weak self] in
self?.content.push(P2PLockedFundsController(), animated: true)
}
// Notification.subscribe(name: .didChangeAccount) { [weak self] _ in
// P2PMainLockedFundsService.shared.fetch {
//// if P2P.Service.balances.collection.
// if P2PMyDealsService.shared.deals.count > 0 || P2PMyOrdersService.shared.orders.count > 0 {
// self?.inviteView.lockedFundsView.isHidden = false
// let msg = P2PMyOrdersService.shared.orders
// .reduce("", { $0 + "Order: \($1.id):\($1.volume_balance)" })
// + P2PMyDealsService.shared.deals
// .reduce("", { $0 + "Deal: \($1.id):\($1.volume)" })
// self?.inviteView.lockedFundsLabel.attributedText = msg.attributed
// .applying(attribute: .font, value: FontFamily.GolosUI.medium.font(size: 20))
// .applying(attribute: .foregroundColor, value: Asset.textSnow.color)
// self?.inviteView.lockedFundsLabel.speed = .rate(20.0)
// } else {
// self?.inviteView.lockedFundsView.isHidden = true
// }
// }
// }
Notification.subscribe(name: .didChangeAccount) { [weak self] _ in
// self?.inviteView.lockedFundsView.isHidden = true
self?.notificationTokens.removeAll()
self?.notificationTokens.append(contentsOf: [
self?.service.p2pBalancesService.balances.observe(on: .main) { _ in
Wallet.Service.Tokens.shared.balances.fetch()
if (self?.service.p2pBalancesService.balances.filter("amount > 0 || blockedAmount > 0").count ?? 0) > 0 {
self?.inviteView.lockedFundsView.isHidden = false
let msg = L10n.P2p.Main.LockedFunds.headerTitle +
(self?.service.p2pBalancesService.balances.filter("amount > 0 || blockedAmount > 0")
.reduce("", { $0 + " \(($1.amount.decimalValue + $1.blockedAmount.decimalValue).toString(max: 5)) \($1.symbol) " }) ?? "")
+ " "
self?.inviteView.lockedFundsLabel.attributedText = msg.attributed
.applying(attribute: .font, value: FontFamily.GolosUI.medium.font(size: 20))
.applying(attribute: .foregroundColor, value: Asset.textSnow.color)
self?.inviteView.lockedFundsLabel.speed = .rate(20.0)
} else {
self?.inviteView.lockedFundsView.isHidden = true
}
}
].compactMap { $0 })
}
self.resourcesBtn.customView = self.resourcesSwitch
self.resourcesSwitch.isSelected = Accounts().quota.isEnabled
Accounts().fetchQuota()
Accounts().bank
.activePublisher
.sink { [weak self] _ in
self?.onAccountChange()
}
.store(in: &self.cancellables)
// TODO: - Here we need handle update notifications
// Notification.subscribe(name: .socketDidUpdateValue) { [weak self] in
// print($0)
// print("\(Date()) - socket update")
// }
Notification.subscribe(name: .didUpdateHistory, { [unowned self] in
guard let username = Accounts().current?.name,
username == $0.userInfo?["username"] as? String else { return }
Wallet.Service.Tokens.shared.balances.fetch()
self.updateMsgCount()
})
self.observer = UserDefaults.standard.observe(\.chatsReadCount, options: [.initial, .new], changeHandler: { (defaults, change) in
guard let username = Accounts().current?.name else {
self.setChatsBadge(count: 0)
return
}
self.setChatsBadge(count: self.chatsMsgsCount(username: username) - self.chatsRead(by: username))
})
self.inviteView.didClose = { [ unowned self] in self.inviteView.isHidden = true }
Task.detached {
struct Income: Codable {
let income: Network.Model.TokenSmall
}
Network.table.fetch(
code: ApplicationEnvironment.shared().current.contract(.p2p),
table: "swap",
scope: ApplicationEnvironment.shared().current.contract(.p2p),
type: Income.self) { rows in
p2pTokenscollection = rows.map({ $0.income })
}
}
}
func chatsRead(by username: String) -> Int {
var chatsRead = 0
AccountViewAuthorize.showGetPrivateKey(in: self) {
guard
let msgsHistoryService = try? CryptoChat.Service.MsgsHistory(
username: username,
encryptionKey: $0
)
else { return }
msgsHistoryService.fetchFromLocalHistory()
chatsRead = msgsHistoryService.readCount
}
return chatsRead
}
private func chatsMsgsCount(username: String) -> Int {
Account.Service.History.shared.current?.actions
.filter("account = '\(ApplicationEnvironment.shared().current.contract(.chat))'")
.filter("name = '\(Network.Model.Blockchain.Action.chatSendDm.rawValue)'")
.filter("receiver = '\(username)'").count ?? 0
}
var observer: NSKeyValueObservation?
func setChatsBadge(count: Int) {
DispatchQueue.main.async { [weak self] in
self?.content.viewControllers?
.compactMap({ $0 as? UINavigationController })
.compactMap({ $0.viewControllers.first })
.first(where: { $0 is CryptoChatControllerChats })?
.navigationController?.tabBarItem.badgeValue = count > 0 ? "\(count)" : nil
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Task {
if ApplicationEnvironment.shared().current.hyperions.count == 0 {
await self.service.loadNodes()
if let versionError = await self.service.loadVersion() {
let action = UIAlertAction(title: L10n.Main.WrongVersion.updateButton, style: .default) { _ in
let url = URL(string: "itms-apps://apple.com/app/id\(Bundle.main.appId)")!
UIApplication.shared.open(url)
}
Alert.system(text: versionError, actions: [action])
}
Settings.shared.isSwapFunctionalActive = await self.service.appSettings.isSwapActive
self.service.loadHyperions()
self.content.setupTabBarOrder()
}
}
StoreReviewHelper.checkAndAskForReview()
_ = Account.Service.History.shared
let current = Accounts().current
if !current.isExist,
Account.Service.isAccountMigrated,
!(Account.Service.Authorize.shared.password ?? "").isEmpty {
self.showWalletBoarding()
}
// else if !UserDefaults.standard.bool(forKey: "onboardingOverviewPassed") {
// present(StoryboardScene.AccountOnboarding.accountOnboardingControllerInterfaceType.instantiate(), animated: true)
// }
else if Accounts().isAuthorized {
Loader.hide()
// Show news
/*Task {
if let urlString = await service.loadNews().first?.url,
let url = URL(string: urlString),
!(AccountOnboarding.Service.Common().newsShowed ?? []).contains(urlString) {
let webview = WKWebView()
webview.load(URLRequest(url: url))
webview.addHeightConstraint(height: UIScreen.main.bounds.height * 0.8 - 100)
Popup.show(
views: [webview],
submit: L10n.Common.Button.close,
in: self
)
AccountOnboarding.Service.Common().newsShowed = (AccountOnboarding.Service.Common().newsShowed ?? []) + [urlString]
}
}*/
}
}
func showWalletBoarding() {
let ctrl = WalletBoardingViewController()
ctrl.modalPresentationStyle = .fullScreen
self.present(ctrl, animated: true)
}
func updateMsgCount() {
guard let username = Accounts().current?.name else {
self.setChatsBadge(count: 0)
return
}
if UserDefaults.standard.object(forKey: "chatsReadCount") == nil {
UserDefaults.standard.setValue([username: self.chatsMsgsCount(username: username)], forKey: "chatsReadCount")
} else if !(UserDefaults.standard.dictionary(forKey: "chatsReadCount")?.keys.contains(username) ?? false) {
var readDict = (UserDefaults.standard.dictionary(forKey: "chatsReadCount") as? [String: Int]) ?? [:]
readDict[username] = self.chatsMsgsCount(username: username)
UserDefaults.standard.setValue(readDict, forKey: "chatsReadCount")
}
self.setChatsBadge(count: self.chatsMsgsCount(username: username) - self.chatsRead(by: username))
}
@objc func onAccountChange() {
DispatchQueue.main.async { Loader.hide() }
self.configureAccountButton()
self.configureQRButton()
self.setupSubscriptions()
self.inviteView.changeVisibility(Accounts().hasActiveAccounts)
self.updateMsgCount()
}
func setupSubscriptions() {
if let username = Accounts().current?.name,
!Network.webSockets.contains(id: "\(username)-sockets2.0") {
Network.webSockets.remove(idSuffix: "-sockets2.0")
let timeText = Date().toISODateString
let signature = Network.Service.Blockchain.signWithK1(privateKey: AccountViewAuthorize.getPrivateKey(),
data: timeText.data(using: .utf8) ?? Data())
let signaturesString = #"""
{ \\\"username\\\": \\\"$username\\\", \\\"text\\\": \\\"$timeText\\\", \\\"signature\\\": \\\"$signature\\\" }
"""#
.replacingOccurrences(of: "$username", with: username)
.replacingOccurrences(of: "$timeText", with: timeText)
.replacingOccurrences(of: "$signature", with: signature)
let subscription =
#"""
{"id":"2","type":"start","payload":{"query":"subscription { notifications(lang: $lang, signature: \"$signature\"){ notificationType state payload previousUid currentUid }}","variables":null}}
"""#
.replacingOccurrences(of: "$signature", with: signaturesString)
.replacingOccurrences(of: "$lang", with: Common.Model.Language.current.rawValue)
Network.webSockets.open(subscription: subscription, id: "\(username)-sockets2.0")
service.reloadP2PData(username: Accounts().current?.name ?? "")
}
}
private func configureAccountButton() {
let accountButtonTitle = Accounts().hasActiveAccounts ? (Accounts().current?.name ?? L10n.Account.Button.empty)
: L10n.Account.Button.addAccounts
self.accountButton.setAttributedTitle(accountButtonTitle.attributed(style: .bold,
size: 16,
color: Asset.textSnow.color),
for: .normal
)
self.accountButton.isEnabled = Accounts().hasActiveAccounts
self.accountButton.backgroundColor = Accounts().hasActiveAccounts ? Asset.deepWater.color : Asset.disabled.color
self.accountButton.isUserInteractionEnabled = Accounts().hasActiveAccounts && !Accounts().isLocked
self.accountButton.setImage(Accounts().isLocked ? Asset.accountLock.image : Asset.commonEos.image, for: .normal)
}
private func configureQRButton() {
self.settingsGearButton.isEnabled = Accounts().hasActiveAccounts
self.settingsGearButton.image = Accounts().hasActiveAccounts ? Asset.commonButtonQr.image : Asset.qrDisabled.image
}
@IBAction func accountPressed(_ sender: Any) {
// let ctrl = AccountsSelectionViewController()
let ctrl = AccountsListController()
mainController.content.push(ctrl, animated: true)
}
@IBAction func onResources(_: AnyObject?) {
let ctrl = StoryboardScene.Resources.setup.instantiate()
ctrl.shouldHideBackButton = self.hasTitle
content.push(ctrl, animated: true)
}
@IBAction func qrPressed(_ sender: Any) {
guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else {
let ctrl = ScannerViewController()
ctrl.navigationItem.leftBarButtonItem = .close { [unowned self] in dismiss(animated: true) }
ctrl.didCapture = { [unowned self]string in
dismiss(animated: true)
readQrData(string: string)
}
let navCtrl = UINavigationController(rootViewController: ctrl)
navCtrl.modalPresentationStyle = .fullScreen
present(navCtrl, animated: true)
return
}
Alert.system(
actions: [
.init(title: L10n.Wallet.Send.qrCamera, style: .default) { [unowned self] _ in
let ctrl = ScannerViewController()
ctrl.navigationItem.leftBarButtonItem = .close(self)
ctrl.didCapture = { [unowned self]string in
dismiss(animated: true)
readQrData(string: string)
}
let navCtrl = UINavigationController(rootViewController: ctrl)
navCtrl.modalPresentationStyle = .fullScreen
UIViewController.topController().present(navCtrl, animated: true)
},
.init(title: L10n.Wallet.Send.qrLibrary, style: .default) { [unowned self] _ in
let ctrl = UIImagePickerController()
ctrl.delegate = self
ctrl.sourceType = .photoLibrary
UIViewController.topController().present(ctrl, animated: true)
},
.init(title: L10n.Main.Qr.showMy, style: .default) { [unowned self] _ in
let ctrl = StoryboardScene.Wallet.receive.instantiate()
ctrl.isQuickLook = true
mainController.content.push(ctrl, animated: true)
},
.init(title: L10n.Common.Button.cancel, style: .cancel)
],
style: .actionSheet,
in: self
)
}
private func openTransfer(with dictionary: [String: Any]) {
let viewController = StoryboardScene.Wallet.transfer.instantiate()
viewController.dictionary = dictionary
let navigationController = content.selectedViewController as? UINavigationController
navigationController?.popToRootViewController(animated: true)
navigationController?.pushViewController(viewController, animated: true)
}
private func readQrData(string: String) {
if let link = URL(string: string) {
Branch.getInstance().handleDeepLink(link)
} else {
openTransfer(with: convertStringToDictionary(text: string) ?? [:])
}
}
private var deepLink: DeepLink?
// swiftlint:disable cyclomatic_complexity function_body_length
func process(deepLink: DeepLink) {
guard Accounts().isAuthorized else {
self.deepLink = deepLink
return
}
let navigationController = self.content.selectedViewController as? UINavigationController
switch deepLink.action {
case .walletAuth:
let dictionary = deepLink.dictionary()
if let callbackUrl = dictionary["callback_url"] as? String,
let verificationCode = dictionary["verification_code"] as? String,
let account = Accounts().current?.name {
let siteName = ((dictionary["site_name"] as? String) ?? "").isEmpty
? " " : "\((dictionary["site_name"] as? String) ?? " ")"
Popup.show(
title: ((dictionary["site_name"] as? String) ?? "").isEmpty
? L10n.Main.ListLogin.title : L10n.Main.ListLogin.titleOn(siteName),
views: [
.label(
text: L10n.Main.ListLogin.description(siteName)
.attributed(style: .regular, size: 16, color: Asset.textCoal.color),
numberOfLines: 0
)
],
submit: L10n.Common.Button.confirm,
in: navigationController ?? self
) { ctrl in
Loader.show(in: ctrl)
AccountViewAuthorize.showGetPrivateKey(in: navigationController ?? self) {
let data = "{\"account\":\"\(account)\",\"verification_code\":\"\(verificationCode)\"}"
let signature = Network.Service.Blockchain.signWithK1(privateKey: $0, data: data.data(using: .utf8) ?? Data())
AF.request(
callbackUrl,
method: .post,
parameters: ["signature": signature, "data": data],
encoding: JSONEncoding.default
).responseString {
Loader.hide(in: ctrl)
Popup.hide()
guard let statusCode = $0.response?.statusCode else { return }
let errorTitle: String?
if statusCode == 200 {
// Open URL if it exists
deepLink.url >>- { UIApplication.shared.open($0) }
return
} else if let error = ($0.error as NSError?) {
Alert.notify(error.localizedDescription, dismiss: ctrl)
return
} else if statusCode >= 400, statusCode < 500 {
errorTitle = L10n.tr("Localizable", "main.listLogin.expired")
} else {
errorTitle = L10n.tr("Localizable", "main.listLogin.unexpected")
}
errorTitle >>- { Alert.notify($0, dismiss: ctrl) }
}
}
}
}
case .transfer, .competitivePrice:
let viewController = StoryboardScene.Wallet.transfer.instantiate()
viewController.dictionary = deepLink.dictionary()
navigationController?.popToRootViewController(animated: true)
navigationController?.pushViewController(viewController, animated: true)
case .connect:
if let model = deepLink.get(AccountModelConnect.self),
let account = Accounts().collection.filter({ $0.name == model.from }).first {
Accounts().current = account
let ctrl = StoryboardScene.Account.connect.instantiate()
ctrl.service.model = model
(self.content.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
(self.content.selectedViewController as? UINavigationController)?.pushViewController(ctrl, animated: true)
}
case .chat:
// guard UIApplication.shared.applicationState == .inactive else { return }
if let model = deepLink.get(CryptoChat.Model.DeepLink.self) {
AccountViewAuthorize.showGetPrivateKey(in: self) {
guard
let user = Accounts().current,
let msgsHistoryService = try? CryptoChat.Service.MsgsHistory(
username: user.name,
encryptionKey: $0
)
else { return }
let ctrl = CryptoChatControllerChat()
ctrl.username = model.account
ctrl.msgsHistoryService = msgsHistoryService
ctrl.unreadCount = 0
(self.content.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
self.content.selectChatViewController()
guard let selectedNavigation = (self.content.selectedViewController as? UINavigationController),
!(selectedNavigation.viewControllers.last is CryptoChatControllerChat) else { return }
selectedNavigation.pushViewController(ctrl, animated: true)
selectedNavigation.setNavigationBarHidden(false, animated: true)
}
}
case .chatMessage:
// guard UIApplication.shared.applicationState == .inactive else { return }
guard let info = deepLink.info,
let receiver = info["receiver"] as? String,
let sender = info["sender"] as? String,
let account = Accounts().collection.filter({ $0.name == receiver }).first
else { return }
Accounts().current = account
AccountViewAuthorize.showGetPrivateKey(in: self) {
guard
let user = Accounts().current,
let msgsHistoryService = try? CryptoChat.Service.MsgsHistory(
username: user.name,
encryptionKey: $0
)
else { return }
let ctrl = CryptoChatControllerChat()
ctrl.username = sender
ctrl.msgsHistoryService = msgsHistoryService
ctrl.unreadCount = 0
(self.content.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
self.content.selectChatViewController()
guard let selectedNavigation = (self.content.selectedViewController as? UINavigationController),
!(selectedNavigation.viewControllers.last is CryptoChatControllerChat) else { return }
selectedNavigation.pushViewController(ctrl, animated: true)
selectedNavigation.setNavigationBarHidden(false, animated: true)
}
case .tokenization:
if let model = deepLink.get(Apartments.Model.Tokenization.self),
let account = Accounts().collection.filter({
$0.name == model.permission
}).first {
Accounts().current = account
let ctrl = StoryboardScene.Apartments.request.instantiate()
ctrl.title = L10n.Apartments.Tokenization.title
ctrl.popupDescription = L10n.Apartments.Tokenization.popup
let service = Apartments.Service.Tokenization()
service.image = Asset.apartmentsTokenization.image
service.warning = L10n.Apartments.Tokenization.warning
service.submit = L10n.Apartments.Tokenization.submit
service.title = L10n.Apartments.Tokenization.description
service.actionTitle = L10n.Apartments.Tokenization.Emission.title
service.contract = model.contract
service.action = model.action
service.symbol = model.symbol
service.fetchApartment(id: model.apt_id, contract: model.contract, symbol: model.symbol) { (success) in
guard success else { return }
service.receiver = nil
ctrl.service = service
(self.content.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
(self.content.selectedViewController as? UINavigationController)?.pushViewController(ctrl, animated: true)
}
}
case .approveBuy:
if let model = deepLink.get(Apartments.Model.ApproveBuy.self),
let account = Accounts().collection.filter({
$0.name == model.permission
}).first {
Accounts().current = account
let ctrl = StoryboardScene.Apartments.request.instantiate()
ctrl.title = L10n.Apartments.Approve.title
ctrl.popupDescription = L10n.Apartments.Approve.popup
let service = Apartments.Service.Approve()
service.warning = L10n.Apartments.Approve.warning
service.submit = L10n.Apartments.Approve.submit
service.title = L10n.Apartments.Approve.description
service.actionTitle = L10n.Apartments.Approve.Emission.title
service.contract = model.contract
service.action = model.action
service.symbol = model.token
service.fetchApartment(id: model.apt_id, contract: model.contract, symbol: model.token) { (success) in
guard success else { return }
service.receiver = nil
ctrl.service = service
(self.content.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
(self.content.selectedViewController as? UINavigationController)?.pushViewController(ctrl, animated: true)
}
}
case .emission:
if let model = deepLink.get(Apartments.Model.Emission.self),
let account = Accounts().collection.filter({
$0.name == model.permission
}).first {
Accounts().current = account
let ctrl = StoryboardScene.Apartments.request.instantiate()
ctrl.title = L10n.Apartments.Emission.title
ctrl.popupDescription = L10n.Apartments.Emission.popup
let service = Apartments.Service.Emission()
service.image = Asset.apartmentsEmission.image
service.warning = L10n.Apartments.Emission.warning
service.title = L10n.Apartments.Emission.description
service.actionTitle = L10n.Apartments.Tokenization.Emission.title
service.submit = L10n.Apartments.Emission.submit
service.contract = model.contract
service.action = model.action
service.to = model.to
service.amount = model.amount
service.symbol = model.symbol
service.memo = model.memo
service.fetchApartment(id: model.apt_id, contract: model.contract, symbol: model.symbol) { (success) in
guard success else { return }
ctrl.service = service
(self.content.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
(self.content.selectedViewController as? UINavigationController)?.pushViewController(ctrl, animated: true)
}
}
case .transactionTransfer, .transactionEmission, .transactionInheritance/*, .cashDealComplete*/:
if let info = deepLink.info,
let username = info["receiver"] as? String,
let symbol = info["currency"] as? String,
let account = Accounts().collection.filter({ $0.name == username }).first {
Accounts().current = account
if let index = content.viewControllers?.lastIndex(where: { ($0 as? UINavigationController)?.viewControllers.first is WalletController }) {
content.selectedIndex = index
let walletController = ((content.viewControllers?[index] as? UINavigationController)?.viewControllers.first as? WalletController)
walletController?.selectedSymbol = symbol
((content.viewControllers?[index] as? UINavigationController)?.viewControllers.first as? WalletController)?.selectedSymbol = symbol
(content.viewControllers?[index] as? UINavigationController)?.popToRootViewController(animated: true)
}
Wallet.Service.Tokens.shared.balances.fetch()
}
case .p2pDealNew, .p2pDealComplete, .p2pDealCancel, .p2pDealDispute:
guard UIApplication.shared.applicationState == .inactive else { return }
if let info = deepLink.info,
let username = info["receiver"] as? String,
let symbol = info["currency"] as? String,
let account = Accounts().collection.filter({ $0.name == username }).first {
Accounts().current = account
if let index = content.viewControllers?.lastIndex(where: { ($0 as? UINavigationController)?.viewControllers.first is P2PControllerDashboard }) {
content.selectedIndex = index
(content.viewControllers?[index] as? UINavigationController)?.popToRootViewController(animated: true)
// P2P.Service.Dashboard.shared.symbol = symbol
Wallet.Service.Tokens.shared.balances.fetch()
}
}
/*case .cashDealNew, .cashDealConfirm, .cashDealCancel:
if let info = deepLink.info,
let username = info["receiver"] as? String,
let account = Accounts().collection.filter({ $0.username == username }).first {
Accounts().current = account
if let index = content.viewControllers?.lastIndex(where: { ($0 as? UINavigationController)?.viewControllers.first is CCCPMainViewController }) {
content.selectedIndex = index
(content.viewControllers?[index] as? UINavigationController)?.popToRootViewController(animated: true)
if deepLink.action == .cashDealNew || deepLink.action == .cashDealCancel {
let ctrl = CCCPControllerExchangeRequests()
ctrl.type = .incomingRequests
(content.viewControllers?[index] as? UINavigationController)?.pushViewController(ctrl, animated: true)
}
}
}*/
case .news:
if let info = deepLink.info,
let aps = info["aps"] as? [String: Any],
let alert = aps["alert"] as? [String: String] {
Popup.show(title: alert["title"], description: alert["body"] ?? "", submit: L10n.Common.Button.ok)
}
}
}
}
extension MainController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
picker.dismiss(animated: true)
guard
let selectedImage = info[.originalImage] as? UIImage,
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh]),
let ciImage = CIImage(image: selectedImage)
else { return }
var qrCodeLink = ""
for feature in (detector.features(in: ciImage) as? [CIQRCodeFeature]) ?? [] {
qrCodeLink += feature.messageString ?? ""
}
print(qrCodeLink) // Your result from QR Code
if !qrCodeLink.isEmpty {
readQrData(string: qrCodeLink)
} else {
Alert.error(L10n.Main.Qr.notValidError)
}
}
}