diff --git a/Kukai Mobile/Controls/EnterAddressComponent/EnterAddressComponent.swift b/Kukai Mobile/Controls/EnterAddressComponent/EnterAddressComponent.swift
index da908ed4..63b49010 100644
--- a/Kukai Mobile/Controls/EnterAddressComponent/EnterAddressComponent.swift
+++ b/Kukai Mobile/Controls/EnterAddressComponent/EnterAddressComponent.swift
@@ -42,6 +42,13 @@ public class EnterAddressComponent: UIView {
private var currentSelectedType: AddressType = .tezosAddress
public weak var delegate: EnterAddressComponentDelegate? = nil
+ public var allowEmpty: Bool = false {
+ didSet {
+ if (self.textField.text == nil || self.textField.text == "") && allowEmpty {
+ self.sendButton.isEnabled = true
+ }
+ }
+ }
required init?(coder aDecoder: NSCoder) {
@@ -71,7 +78,7 @@ public class EnterAddressComponent: UIView {
textField.validatorTextFieldDelegate = self
self.hideError(animate: false)
- self.sendButton.isEnabled = false
+ self.sendButton.isEnabled = allowEmpty
}
public func updateAvilableAddressTypes(_ types: [AddressType]) {
@@ -275,7 +282,7 @@ extension EnterAddressComponent: ValidatorTextFieldDelegate {
self.sendButton.isEnabled = true
} else if text == "" {
- self.sendButton.isEnabled = false
+ self.sendButton.isEnabled = allowEmpty
} else {
self.sendButton.isEnabled = false
diff --git a/Kukai Mobile/Extensions/UIViewController+extensions.swift b/Kukai Mobile/Extensions/UIViewController+extensions.swift
index a73dacb2..5db27bba 100644
--- a/Kukai Mobile/Extensions/UIViewController+extensions.swift
+++ b/Kukai Mobile/Extensions/UIViewController+extensions.swift
@@ -42,7 +42,7 @@ extension UIViewController {
activityViewStatusLabel.font = UIFont.custom(ofType: .medium, andSize: 16)
activityViewStatusLabel.textColor = UIColor.white
activityViewStatusLabel.textAlignment = .center
- activityViewStatusLabel.frame = CGRect(x: view.center.x, y: view.center.y, width: view.frame.width - 64, height: 50)
+ activityViewStatusLabel.frame = CGRect(x: view.center.x, y: view.center.y, width: view.frame.width - 64, height: 200)
UIViewController.activityViewActivityIndicator.color = UIColor.white
diff --git a/Kukai Mobile/Modules/Account/TokenDetailsViewModel.swift b/Kukai Mobile/Modules/Account/TokenDetailsViewModel.swift
index 12c418ff..95cc5dfe 100644
--- a/Kukai Mobile/Modules/Account/TokenDetailsViewModel.swift
+++ b/Kukai Mobile/Modules/Account/TokenDetailsViewModel.swift
@@ -7,6 +7,7 @@
import UIKit
import KukaiCoreSwift
+import Combine
import OSLog
struct AllChartData: Hashable {
@@ -122,6 +123,7 @@ public class TokenDetailsViewModel: ViewModel, TokenDetailsChartCellDelegate {
private let chartDateFormatter = DateFormatter(withFormat: "MMM dd HH:mm a")
private var initialChartLoad = true
private var onlineXTZFetchGroup = DispatchGroup()
+ private var bag = [AnyCancellable]()
// Set by VC
weak var delegate: (TokenDetailsViewModelDelegate & TokenDetailsBakerDelegate & TokenDetailsStakeBalanceDelegate)? = nil
@@ -155,6 +157,22 @@ public class TokenDetailsViewModel: ViewModel, TokenDetailsChartCellDelegate {
var finaliseableAmount: TokenAmount = .zero()
+ override init() {
+ super.init()
+
+ DependencyManager.shared.$addressRefreshed
+ .dropFirst()
+ .sink { [weak self] address in
+ let selectedAddress = DependencyManager.shared.selectedWalletAddress ?? ""
+ if self?.dataSource != nil && selectedAddress == address {
+ self?.refresh(animate: true)
+ }
+ }.store(in: &bag)
+ }
+
+ deinit {
+ bag.forEach({ $0.cancel() })
+ }
diff --git a/Kukai Mobile/Modules/Login/LoginViewController.swift b/Kukai Mobile/Modules/Login/LoginViewController.swift
index f50ed1a6..75bef38c 100644
--- a/Kukai Mobile/Modules/Login/LoginViewController.swift
+++ b/Kukai Mobile/Modules/Login/LoginViewController.swift
@@ -63,7 +63,7 @@ class LoginViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
- /* // TODO: uncomment
+
// Hide biometric button if its not enabled, or we are in the middle of the edit passcode flow
if isEditPasscodeMode() || CurrentDevice.biometricTypeAuthorized() == .none || StorageService.isBiometricEnabled() == false {
useBiometricsButton.isHidden = true
@@ -83,9 +83,6 @@ class LoginViewController: UIViewController {
// Edit passcode popup
self.hiddenTextfield.becomeFirstResponder()
}
- */
-
- self.next()
}
override func viewDidDisappear(_ animated: Bool) {
diff --git a/Kukai Mobile/Modules/Send/SendAbstractConfirmViewController.swift b/Kukai Mobile/Modules/Send/SendAbstractConfirmViewController.swift
index f00ae6a6..84919a1a 100644
--- a/Kukai Mobile/Modules/Send/SendAbstractConfirmViewController.swift
+++ b/Kukai Mobile/Modules/Send/SendAbstractConfirmViewController.swift
@@ -114,6 +114,7 @@ class SendAbstractConfirmViewController: UIViewController {
if collapseOnly == false {
if isDuringStakeOnboardingFlow {
topMostNavigationController?.dismiss(animated: true)
+
} else {
(self?.presentingViewController as? UINavigationController)?.popToHome()
}
diff --git a/Kukai Mobile/Modules/Stake/ChooseBakerConfirmViewController.swift b/Kukai Mobile/Modules/Stake/ChooseBakerConfirmViewController.swift
index 392a6a6a..d11a502b 100644
--- a/Kukai Mobile/Modules/Stake/ChooseBakerConfirmViewController.swift
+++ b/Kukai Mobile/Modules/Stake/ChooseBakerConfirmViewController.swift
@@ -181,10 +181,7 @@ class ChooseBakerConfirmViewController: SendAbstractConfirmViewController, Slide
func didCompleteSlide() {
self.blockInteraction(exceptFor: [closeButton])
-
- // TODO: swap back
- //self.performAuth()
- self.handleApproval(opHash: "", slideButton: self.slideButton)
+ self.performAuth()
}
override func authSuccessful() {
diff --git a/Kukai Mobile/Modules/Stake/ChooseBakerViewController.swift b/Kukai Mobile/Modules/Stake/ChooseBakerViewController.swift
index 18eb48c1..a667d15a 100644
--- a/Kukai Mobile/Modules/Stake/ChooseBakerViewController.swift
+++ b/Kukai Mobile/Modules/Stake/ChooseBakerViewController.swift
@@ -13,7 +13,7 @@ class ChooseBakerViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
- private let viewModel = ChooseBakerViewModel()
+ private var viewModel = ChooseBakerViewModel()
private var cancellable: AnyCancellable?
private let footerView = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 2))
private let blankView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.1))
@@ -49,7 +49,10 @@ class ChooseBakerViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
- viewModel.refresh(animate: false)
+
+ if viewModel.bakers.count == 0 {
+ viewModel.refresh(animate: false)
+ }
}
public func enteredCustomBaker(address: String) {
@@ -58,9 +61,10 @@ class ChooseBakerViewController: UIViewController {
if address == "" {
let currentDelegate = DependencyManager.shared.balanceService.account.delegate
let name = currentDelegate?.alias ?? currentDelegate?.address.truncateTezosAddress() ?? ""
- let baker = TzKTBaker(address: "", name: name)
+ let baker = TzKTBaker(address: currentDelegate?.address ?? "", name: name)
TransactionService.shared.delegateData.chosenBaker = baker
+ TransactionService.shared.stakeData.chosenBaker = baker
TransactionService.shared.delegateData.isAdd = false
} else {
@@ -68,11 +72,13 @@ class ChooseBakerViewController: UIViewController {
if let foundBaker = viewModel.bakerFor(address: address) {
TransactionService.shared.delegateData.chosenBaker = foundBaker
+ TransactionService.shared.stakeData.chosenBaker = foundBaker
TransactionService.shared.delegateData.isAdd = true
} else {
let baker = TzKTBaker(address: address, name: address.truncateTezosAddress())
TransactionService.shared.delegateData.chosenBaker = baker
+ TransactionService.shared.stakeData.chosenBaker = baker
TransactionService.shared.delegateData.isAdd = true
}
}
@@ -97,7 +103,13 @@ class ChooseBakerViewController: UIViewController {
return
}
- let operations = OperationFactory.delegateOperation(to: toAddress, from: selectedWallet.address)
+ var operations: [KukaiCoreSwift.Operation] = []
+ if TransactionService.shared.delegateData.isAdd == true {
+ operations = OperationFactory.delegateOperation(to: toAddress, from: selectedWallet.address)
+ } else {
+ operations = OperationFactory.undelegateOperation(address: selectedWallet.address)
+ }
+
DependencyManager.shared.tezosNodeClient.estimate(operations: operations, walletAddress: selectedWallet.address, base58EncodedPublicKey: selectedWallet.publicKeyBase58encoded()) { [weak self] estimationResult in
self?.hideLoadingView()
@@ -132,6 +144,7 @@ extension ChooseBakerViewController: UITableViewDelegate {
if let baker = viewModel.bakerFor(indexPath: indexPath) {
TransactionService.shared.delegateData.chosenBaker = baker
+ TransactionService.shared.stakeData.chosenBaker = baker
TransactionService.shared.delegateData.isAdd = true
self.performSegue(withIdentifier: "details", sender: nil)
diff --git a/Kukai Mobile/Modules/Stake/ChooseBakerViewModel.swift b/Kukai Mobile/Modules/Stake/ChooseBakerViewModel.swift
index 42a82d50..24e5d8a1 100644
--- a/Kukai Mobile/Modules/Stake/ChooseBakerViewModel.swift
+++ b/Kukai Mobile/Modules/Stake/ChooseBakerViewModel.swift
@@ -32,15 +32,6 @@ class ChooseBakerViewModel: ViewModel, UITableViewDiffableDataSourceHandler {
override init() {
super.init()
-
- DependencyManager.shared.$addressRefreshed
- .dropFirst()
- .sink { [weak self] address in
- let selectedAddress = DependencyManager.shared.selectedWalletAddress ?? ""
- if self?.dataSource != nil && selectedAddress == address {
- self?.refresh(animate: true)
- }
- }.store(in: &bag)
}
deinit {
diff --git a/Kukai Mobile/Modules/Stake/EnterCustomBakerViewController.swift b/Kukai Mobile/Modules/Stake/EnterCustomBakerViewController.swift
index 4b4122bf..ada6d567 100644
--- a/Kukai Mobile/Modules/Stake/EnterCustomBakerViewController.swift
+++ b/Kukai Mobile/Modules/Stake/EnterCustomBakerViewController.swift
@@ -18,6 +18,7 @@ class EnterCustomBakerViewController: UIViewController, EnterAddressComponentDel
enterAddressComponent.headerLabel.text = "Baker:"
enterAddressComponent.updateAvilableAddressTypes([.tezosAddress, .tezosDomain])
enterAddressComponent.delegate = self
+ enterAddressComponent.allowEmpty = true // undelegate by entering blank into field
}
func validatedInput(entered: String, validAddress: Bool, ofType: AddressType) {
diff --git a/Kukai Mobile/Modules/Stake/Stake.storyboard b/Kukai Mobile/Modules/Stake/Stake.storyboard
index 00971a25..fdc72c24 100644
--- a/Kukai Mobile/Modules/Stake/Stake.storyboard
+++ b/Kukai Mobile/Modules/Stake/Stake.storyboard
@@ -253,7 +253,7 @@
-
+
@@ -293,7 +293,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -434,6 +434,9 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
+
+
+
@@ -451,6 +454,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
+
@@ -471,7 +475,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -704,7 +708,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -745,7 +749,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -1090,6 +1094,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
+
@@ -1114,7 +1119,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -1703,7 +1708,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -1711,7 +1716,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -1719,7 +1724,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -2345,7 +2350,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -2353,7 +2358,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -2361,7 +2366,7 @@ Bakers validate and participate in Tezos governance. By delegating to a Baker, y
-
+
@@ -3050,11 +3055,219 @@ Bakers also vote on behalf of users to make changes to the network, during the G
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Kukai Mobile/Modules/Stake/StakeOnboardingContainerViewController.swift b/Kukai Mobile/Modules/Stake/StakeOnboardingContainerViewController.swift
index b20ee93f..cbd8a458 100644
--- a/Kukai Mobile/Modules/Stake/StakeOnboardingContainerViewController.swift
+++ b/Kukai Mobile/Modules/Stake/StakeOnboardingContainerViewController.swift
@@ -6,6 +6,8 @@
//
import UIKit
+import KukaiCoreSwift
+import Combine
class StakeOnboardingContainerViewController: UIViewController {
@@ -23,55 +25,41 @@ class StakeOnboardingContainerViewController: UIViewController {
@IBOutlet weak var navigationContainerView: UIView!
private var childNavigationController: UINavigationController? = nil
private var currentChildViewController: UIViewController? = nil
+ private var bag = [AnyCancellable]()
+ private var currentStep: String = ""
override func viewDidLoad() {
super.viewDidLoad()
GradientView.add(toView: self.view, withType: .fullScreenBackground)
actionButton.customButtonType = .primary
- self.pageIndicator1.setInprogress(pageNumber: 1)
- //NotificationCenter.default.addObserver(self, selector: #selector(bakerConfirmation), name: ChooseBakerViewController.notificationNameBakerChosen, object: nil)
- }
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
-
- /*
- DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
- self?.pageIndicator1.setComplete()
- self?.setProgressSegmentComplete(self?.progressSegment1)
- self?.pageIndicator2.setInprogress(pageNumber: 2)
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 6) { [weak self] in
- self?.pageIndicator2.setComplete()
- self?.setProgressSegmentComplete(self?.progressSegment2)
- self?.pageIndicator3.setInprogress(pageNumber: 3)
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 9) { [weak self] in
- self?.pageIndicator3.setComplete()
- self?.setProgressSegmentComplete(self?.progressSegment3)
- self?.pageIndicator4.setInprogress(pageNumber: 4)
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 12) { [weak self] in
- self?.pageIndicator4.setComplete()
- self?.setProgressSegmentComplete(self?.progressSegment4)
- self?.pageIndicator5.setInprogress(pageNumber: 5)
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + 15) { [weak self] in
- self?.pageIndicator5.setComplete()
- }
- */
+ DependencyManager.shared.activityService.$addressesWithPendingOperation
+ .dropFirst()
+ .sink { [weak self] addresses in
+ guard let address = DependencyManager.shared.selectedWalletAddress else {
+ return
+ }
+
+ DispatchQueue.main.async { [weak self] in
+ if addresses.contains([address]) {
+ self?.showLoadingView()
+ self?.updateLoadingViewStatusLabel(message: "Waiting for transaction to complete \n\nThis should only take a few seconds")
+
+ } else {
+ self?.hideLoadingView()
+ self?.handleOperationComplete()
+ }
+ }
+ }.store(in: &bag)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
-
- //NotificationCenter.default.removeObserver(self, name: ChooseBakerViewController.notificationNameBakerChosen, object: nil)
+ }
+
+ @IBAction func closeTapped(_ sender: Any) {
+ self.navigationController?.popToDetails()
}
func setProgressSegmentComplete(_ view: UIProgressView?) {
@@ -83,7 +71,6 @@ class StakeOnboardingContainerViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "embed", let dest = segue.destination as? UINavigationController {
childNavigationController = dest
-
}
}
@@ -94,24 +81,65 @@ class StakeOnboardingContainerViewController: UIViewController {
}
currentChildViewController = currentChildVc
+ currentStep = currentChildVc.title ?? ""
+
switch currentChildVc.title {
case "step1":
currentChildVc.performSegue(withIdentifier: "next", sender: nil)
- self.pageIndicator1.setComplete()
- self.setProgressSegmentComplete(self.progressSegment1)
- self.pageIndicator2.setInprogress(pageNumber: 2)
+ self.pageIndicator1.setInprogress(pageNumber: 1)
case "step2":
if handlePageControllerNext(vc: currentChildVc) == true {
actionButton.setTitle("Choose Baker", for: .normal)
- self.pageIndicator2.setComplete()
- self.setProgressSegmentComplete(self.progressSegment2)
- self.pageIndicator3.setInprogress(pageNumber: 3)
+ self.pageIndicator1.setComplete()
+ self.setProgressSegmentComplete(self.progressSegment1)
+ self.pageIndicator2.setInprogress(pageNumber: 2)
}
case "step3":
self.performSegue(withIdentifier: "chooseBaker", sender: nil)
+ case "step4":
+ currentChildVc.performSegue(withIdentifier: "next", sender: nil)
+
+ case "step5":
+ if handlePageControllerNext(vc: currentChildVc) == true {
+ actionButton.setTitle("Stake", for: .normal)
+ self.pageIndicator3.setComplete()
+ self.setProgressSegmentComplete(self.progressSegment3)
+ self.pageIndicator4.setInprogress(pageNumber: 4)
+ }
+
+ case "step6":
+ TransactionService.shared.currentTransactionType = .stake
+ TransactionService.shared.stakeData.chosenToken = Token.xtz(withAmount: DependencyManager.shared.balanceService.account.xtzBalance)
+ // chosenBaker will be set inside the the delegation flow
+ self.performSegue(withIdentifier: "stake", sender: nil)
+
+ case "step7":
+ self.navigationController?.popToDetails()
+
+ default:
+ self.windowError(withTitle: "error".localized(), description: "Unknown error")
+ }
+ }
+
+ private func handleOperationComplete() {
+ switch currentStep {
+ case "step3":
+ self.pageIndicator2.setComplete()
+ self.setProgressSegmentComplete(self.progressSegment2)
+ self.pageIndicator3.setInprogress(pageNumber: 3)
+ self.currentChildViewController?.performSegue(withIdentifier: "next", sender: nil)
+ self.actionButton.setTitle("Next", for: .normal)
+
+ case "step6":
+ self.pageIndicator4.setComplete()
+ self.setProgressSegmentComplete(self.progressSegment4)
+ self.pageIndicator5.setInprogress(pageNumber: 5)
+ self.currentChildViewController?.performSegue(withIdentifier: "next", sender: nil)
+ self.actionButton.setTitle("Done", for: .normal)
+
default:
self.windowError(withTitle: "error".localized(), description: "Unknown error")
}
@@ -131,13 +159,4 @@ class StakeOnboardingContainerViewController: UIViewController {
return false
}
}
-
- /*
- @objc private func bakerConfirmation() {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
- self?.hideLoadingView()
- self?.performSegue(withIdentifier: "confirmBaker", sender: nil)
- }
- }
- */
}