Files
raspberry/iOS/Wallet/Sources/OnBoarding/OnBoardingWalletController.swift

212 lines
8.1 KiB
Swift

//
// OnBoardingWalletController.swift
// Malinka
//
// Created by Juraldinio on 11/29/22.
// Copyright © 2022 NUT.Tech. All rights reserved.
//
import Foundation
import UIKit
import WalletKit
import WalletFoundation
final class OnBoardingWalletController: UIViewController {
typealias Completion = () -> Void
private let group = DispatchGroup()
private let loadingGroup = DispatchGroup()
private var causeVersion: String?
private var causeRequiredLinks: String?
private let service = OnBoardingService(environment: ApplicationEnvironment.shared())
private let loader = CommonViewLoading()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .systemBackground
self.group.notify(queue: DispatchQueue.main) {
self.loader.hide()
}
Task {
self.loadingGroup.enter()
if ApplicationEnvironment.shared().current.hyperions.count == 0 {
defer { self.loadingGroup.leave() }
do {
try await self.service.loadNodes()
try await self.service.loadVersion()
await self.service.loadAppSettings(nodes: ApplicationEnvironment.shared().current.nodes)
try await self.service.loadHyperions()
} catch let OnBoardingService.ServiceError.nodes(cause: cause) {
self.causeRequiredLinks = cause
} catch let OnBoardingService.ServiceError.version(cause: cause) {
self.causeVersion = cause
} catch let OnBoardingService.ServiceError.hyperions(cause: cause) {
self.causeRequiredLinks = cause
}
}
}
}
func showPin(completion: @escaping Completion) {
self.showEnvironmentAlert { [weak self] in
guard let self else { return }
let isPinPwdMode = UserDefaults.standard.bool(forKey: "isPinPwdMode")
if !Account.Service.isPasswordExists || !isPinPwdMode {
Account.Service.isAccountMigrated = true
self.showPinController(completion: completion)
} else if Account.Service.isPasswordExists,
isPinPwdMode {
if (Account.Service.Authorize.shared.password ?? "").isEmpty {
if self.presentedViewController != nil {
self.dismiss(animated: false, completion: {
AccountViewAuthorize.showGetPassword(in: self,
viewModel: self.createPinViewModel(completion: completion),
showPinBackButton: false, {
self.initVillage(with: $0)
// Accounts().migrateAccountIfNeeded(password: $0)
self.group.notify(queue: DispatchQueue.main) { completion() }
})
})
} else {
AccountViewAuthorize.showGetPassword(in: self,
viewModel: self.createPinViewModel(completion: completion),
showPinBackButton: false, {
self.initVillage(with: $0)
// Accounts().migrateAccountIfNeeded(password: $0)
self.group.notify(queue: DispatchQueue.main) { completion() }
})
}
} else {
AccountViewAuthorize.showGetPassword(in: self,
viewModel: self.createPinViewModel(completion: completion),
showPinBackButton: false, {
self.initVillage(with: $0)
// Accounts().migrateAccountIfNeeded(password: $0)
self.group.notify(queue: DispatchQueue.main) { completion() }
})
}
}
}
}
// MARK: - Private
private func showPinController(completion: @escaping Completion) {
let controller = WalletPinController.instantiate(viewModel: self.createPinViewModel(completion: completion))
controller.modalPresentationStyle = .fullScreen
controller.isModalInPresentation = true
self.present(controller, animated: false)
}
private func createPinViewModel(completion: @escaping Completion) -> OnBoardingWalletPinViewModel {
let viewModel = OnBoardingWalletPinViewModel()
viewModel.updatePasswordHandler = { [weak self] in self?.initVillage(with: $0) }
viewModel.dismissControllerHandler = { [weak self] controller, isPinCleared in
controller.dismiss(animated: true) {
if !isPinCleared {
self?.group.notify(queue: DispatchQueue.main) { completion() }
} else {
self?.showPinController(completion: completion)
}
}
}
return viewModel
}
private func initVillage(with password: String) {
self.loader.show(in: self.view)
self.group.enter()
Task {
let record = ApplicationEnvironment.shared().current
let village = try Village.get(with: record.networkEnvironment())
guard let device = try? await village.device() else { throw NSError() }
let bank = try village.getBank(with: password, on: device)
Account.Service.shared = Account.Service(using: bank)
self.loadingGroup.notify(queue: DispatchQueue.main) {
if let cause = self.causeRequiredLinks {
Alert.error(text: cause, delay: 1.0)
} else if let cause = self.causeVersion {
let action = UIAlertAction(title: L10n.Main.WrongVersion.updateButton, style: .default) { _ in
URL(string: "itms-apps://apple.com/app/id\(Bundle.main.appId)") >>- {
UIApplication.shared.open($0)
}
}
self.loader.hide()
Alert.system(text: cause, actions: [action])
}
Wallet.Service.Tokens.shared.balances.fetch { _ in
P2P.Service.fetch { [weak self] in
self?.loader.hide()
self?.group.leave()
}
}
}
}
}
private func showEnvironmentAlert(_ completion: @escaping () -> Void) {
let current = ApplicationEnvironment.shared().current
if !current.isProduction {
let version = "\(Bundle.main.major).\(Bundle.main.minor).\(Bundle.main.patch) (\(Bundle.main.buildNumber))"
let alert = UIAlertController(title: "Environment \(version)",
message: "Usernames: \(current.usernames.name)\nBackend: \(current.backend.name)\nOther: \(current.other.name)\nSmarts: \(current.smarts.name)",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok",
style: .destructive,
handler: {(_: UIAlertAction!) in
alert.dismiss(animated: true)
completion()
}))
self.present(alert, animated: true)
} else {
completion()
}
}
}