diff --git a/Tokenary macOS/Agent.swift b/Tokenary macOS/Agent.swift
index 36655b69..dbe3e22d 100644
--- a/Tokenary macOS/Agent.swift
+++ b/Tokenary macOS/Agent.swift
@@ -54,7 +54,7 @@ class Agent: NSObject {
self?.hasPassword = true
self?.showInitialScreen(externalRequest: externalRequest)
}
- let windowController = Window.showNew()
+ let windowController = Window.showNew(closeOthers: true)
windowController.contentViewController = welcomeViewController
return
}
@@ -76,22 +76,22 @@ class Agent: NSObject {
if case let .safari(request) = request {
processSafariRequest(request)
} else {
- let windowController = Window.showNew()
let accountsList = instantiate(AccountsListViewController.self)
if case let .wcSession(session) = request {
accountsList.onSelectedWallet = onSelectedWallet(session: session)
}
+ let windowController = Window.showNew(closeOthers: accountsList.onSelectedWallet == nil)
windowController.contentViewController = accountsList
}
}
- func showApprove(transaction: Transaction, chain: EthereumChain, peerMeta: PeerMeta?, completion: @escaping (Transaction?) -> Void) {
- let windowController = Window.showNew()
- let approveViewController = ApproveTransactionViewController.with(transaction: transaction, chain: chain, peerMeta: peerMeta) { [weak self] transaction in
+ func showApprove(windowController: NSWindowController, transaction: Transaction, chain: EthereumChain, peerMeta: PeerMeta?, completion: @escaping (Transaction?) -> Void) {
+ let window = windowController.window
+ let approveViewController = ApproveTransactionViewController.with(transaction: transaction, chain: chain, peerMeta: peerMeta) { [weak self, weak window] transaction in
if transaction != nil {
- self?.askAuthentication(on: windowController.window, onStart: false, reason: .sendTransaction) { success in
+ self?.askAuthentication(on: window, onStart: false, reason: .sendTransaction) { success in
completion(success ? transaction : nil)
}
} else {
@@ -101,13 +101,13 @@ class Agent: NSObject {
windowController.contentViewController = approveViewController
}
- func showApprove(subject: ApprovalSubject, meta: String, peerMeta: PeerMeta?, completion: @escaping (Bool) -> Void) {
- let windowController = Window.showNew()
- let approveViewController = ApproveViewController.with(subject: subject, meta: meta, peerMeta: peerMeta) { [weak self] result in
+ func showApprove(windowController: NSWindowController, subject: ApprovalSubject, meta: String, peerMeta: PeerMeta?, completion: @escaping (Bool) -> Void) {
+ let window = windowController.window
+ let approveViewController = ApproveViewController.with(subject: subject, meta: meta, peerMeta: peerMeta) { [weak self, weak window] result in
if result {
- self?.askAuthentication(on: windowController.window, onStart: false, reason: subject.asAuthenticationReason) { success in
+ self?.askAuthentication(on: window, getBackTo: window?.contentViewController, onStart: false, reason: subject.asAuthenticationReason) { success in
completion(success)
- (windowController.contentViewController as? ApproveViewController)?.enableWaiting()
+ (window?.contentViewController as? ApproveViewController)?.enableWaiting()
}
} else {
completion(result)
@@ -116,11 +116,6 @@ class Agent: NSObject {
windowController.contentViewController = approveViewController
}
- func showErrorMessage(_ message: String) {
- let windowController = Window.showNew()
- windowController.contentViewController = ErrorViewController.withMessage(message)
- }
-
func getWalletSelectionCompletionIfShouldSelect() -> ((EthereumChain?, TokenaryWallet?, Account?) -> Void)? {
let session = getSessionFromPasteboard()
return onSelectedWallet(session: session)
@@ -221,7 +216,7 @@ class Agent: NSObject {
guard let session = session else { return nil }
return { [weak self] chain, wallet, account in
guard let chain = chain, let wallet = wallet, account?.coin == .ethereum else {
- Window.closeAllAndActivateBrowser(force: nil)
+ Window.closeAllAndActivateBrowser(specific: nil)
return
}
self?.connectWallet(session: session, chainId: chain.id, wallet: wallet)
@@ -257,12 +252,12 @@ class Agent: NSObject {
let canDoLocalAuthentication = context.canEvaluatePolicy(policy, error: &error)
func showPasswordScreen() {
- let window = on ?? Window.showNew().window
+ let window = on ?? Window.showNew(closeOthers: onStart).window
let passwordViewController = PasswordViewController.with(mode: .enter, reason: reason) { [weak window] success in
if let getBackTo = getBackTo {
window?.contentViewController = getBackTo
} else {
- Window.closeAll()
+ Window.closeWindowAndActivateNext(idToClose: window?.windowNumber, specificBrowser: nil)
}
completion(success)
}
@@ -287,36 +282,50 @@ class Agent: NSObject {
}
private func connectWallet(session: WCSession, chainId: Int, wallet: TokenaryWallet) {
- let windowController = Window.showNew()
+ let windowController = Window.showNew(closeOthers: true)
let window = windowController.window
windowController.contentViewController = WaitingViewController.withReason(Strings.connecting)
walletConnect.connect(session: session, chainId: chainId, walletId: wallet.id) { [weak window] _ in
if window?.isVisible == true {
- Window.closeAllAndActivateBrowser(force: nil)
+ Window.closeAllAndActivateBrowser(specific: nil)
}
}
}
-
+
private func processSafariRequest(_ safariRequest: SafariRequest) {
+ var windowNumber: Int?
let action = DappRequestProcessor.processSafariRequest(safariRequest) {
- Window.closeAllAndActivateBrowser(force: .safari)
+ Window.closeWindowAndActivateNext(idToClose: windowNumber, specificBrowser: .safari)
}
switch action {
case .none:
break
- case .selectAccount(let action), .switchAccount(let action):
- let windowController = Window.showNew()
+ case .selectAccount(let accountAction), .switchAccount(let accountAction):
+ let closeOtherWindows: Bool
+ if case .selectAccount = action {
+ closeOtherWindows = false
+ } else {
+ closeOtherWindows = true
+ }
+
+ let windowController = Window.showNew(closeOthers: closeOtherWindows)
+ windowNumber = windowController.window?.windowNumber
let accountsList = instantiate(AccountsListViewController.self)
- accountsList.onSelectedWallet = action.completion
+ accountsList.onSelectedWallet = accountAction.completion
windowController.contentViewController = accountsList
case .approveMessage(let action):
- showApprove(subject: action.subject, meta: action.meta, peerMeta: action.peerMeta, completion: action.completion)
+ let windowController = Window.showNew(closeOthers: false)
+ windowNumber = windowController.window?.windowNumber
+ showApprove(windowController: windowController, subject: action.subject, meta: action.meta, peerMeta: action.peerMeta, completion: action.completion)
case .approveTransaction(let action):
- showApprove(transaction: action.transaction, chain: action.chain, peerMeta: action.peerMeta, completion: action.completion)
+ let windowController = Window.showNew(closeOthers: false)
+ windowNumber = windowController.window?.windowNumber
+ showApprove(windowController: windowController, transaction: action.transaction, chain: action.chain, peerMeta: action.peerMeta, completion: action.completion)
case .justShowApp:
- let windowController = Window.showNew()
+ let windowController = Window.showNew(closeOthers: true)
+ windowNumber = windowController.window?.windowNumber
let accountsList = instantiate(AccountsListViewController.self)
windowController.contentViewController = accountsList
}
diff --git a/Tokenary macOS/Base.lproj/Main.storyboard b/Tokenary macOS/Base.lproj/Main.storyboard
index 14f5861b..267813ef 100644
--- a/Tokenary macOS/Base.lproj/Main.storyboard
+++ b/Tokenary macOS/Base.lproj/Main.storyboard
@@ -679,7 +679,7 @@
-
+
@@ -1218,75 +1218,6 @@ DQ
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1671,7 +1602,7 @@ DQ
-
+
diff --git a/Tokenary macOS/Screens/ErrorViewController.swift b/Tokenary macOS/Screens/ErrorViewController.swift
deleted file mode 100644
index 0dd7a33b..00000000
--- a/Tokenary macOS/Screens/ErrorViewController.swift
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright © 2021 Tokenary. All rights reserved.
-
-import Cocoa
-
-class ErrorViewController: NSViewController {
-
- static func withMessage(_ message: String) -> ErrorViewController {
- let new = instantiate(ErrorViewController.self)
- new.message = message
- return new
- }
-
- private var message = ""
-
- @IBOutlet weak var titleLabel: NSTextField!
- @IBOutlet weak var messageLabel: NSTextField!
-
- override func viewDidLoad() {
- super.viewDidLoad()
- messageLabel.stringValue = message
- }
-
- @IBAction func actionButtonTapped(_ sender: Any) {
- Window.closeAllAndActivateBrowser(force: nil)
- }
-
-}
diff --git a/Tokenary macOS/Screens/PasswordViewController.swift b/Tokenary macOS/Screens/PasswordViewController.swift
index 07a70938..aa83075b 100644
--- a/Tokenary macOS/Screens/PasswordViewController.swift
+++ b/Tokenary macOS/Screens/PasswordViewController.swift
@@ -21,6 +21,7 @@ class PasswordViewController: NSViewController {
private var reason: AuthenticationReason?
private var passwordToRepeat: String?
private var completion: ((Bool) -> Void)?
+ private var didCallCompletion = false
@IBOutlet weak var reasonLabel: NSTextField!
@IBOutlet weak var cancelButton: NSButton!
@@ -43,6 +44,11 @@ class PasswordViewController: NSViewController {
}
}
+ override func viewDidAppear() {
+ super.viewDidAppear()
+ view.window?.delegate = self
+ }
+
func switchToMode(_ mode: Mode) {
self.mode = mode
switch mode {
@@ -67,11 +73,11 @@ class PasswordViewController: NSViewController {
let repeated = passwordTextField.stringValue
if repeated == passwordToRepeat {
keychain.save(password: repeated)
- completion?(true)
+ callCompletion(result: true)
}
case .enter:
if keychain.password == passwordTextField.stringValue {
- completion?(true)
+ callCompletion(result: true)
}
}
}
@@ -83,7 +89,14 @@ class PasswordViewController: NSViewController {
case .repeatAfterCreate:
switchToMode(.create)
case .enter:
- completion?(false)
+ callCompletion(result: false)
+ }
+ }
+
+ private func callCompletion(result: Bool) {
+ if !didCallCompletion {
+ didCallCompletion = true
+ completion?(result)
}
}
@@ -96,3 +109,11 @@ extension PasswordViewController: NSTextFieldDelegate {
}
}
+
+extension PasswordViewController: NSWindowDelegate {
+
+ func windowWillClose(_ notification: Notification) {
+ callCompletion(result: false)
+ }
+
+}
diff --git a/Tokenary macOS/Screens/WaitingViewController.swift b/Tokenary macOS/Screens/WaitingViewController.swift
index 1508638b..b675d6b4 100644
--- a/Tokenary macOS/Screens/WaitingViewController.swift
+++ b/Tokenary macOS/Screens/WaitingViewController.swift
@@ -22,7 +22,7 @@ class WaitingViewController: NSViewController {
}
@IBAction func actionButtonTapped(_ sender: Any) {
- Window.closeAll()
+ Window.closeWindowAndActivateNext(idToClose: view.window?.windowNumber, specificBrowser: nil)
}
}
diff --git a/Tokenary macOS/WalletConnect.swift b/Tokenary macOS/WalletConnect.swift
index d389703c..1ff34800 100644
--- a/Tokenary macOS/WalletConnect.swift
+++ b/Tokenary macOS/WalletConnect.swift
@@ -133,12 +133,14 @@ class WalletConnect {
let peer = PeerMeta(wcPeerMeta: getPeerOfInteractor(interactor))
let transaction = Transaction(from: wct.from, to: to, nonce: wct.nonce, gasPrice: wct.gasPrice, gas: wct.gas, value: wct.value, data: wct.data)
- agent.showApprove(transaction: transaction, chain: chain, peerMeta: peer) { [weak self, weak interactor] transaction in
+ let windowController = Window.showNew(closeOthers: false)
+ let windowNumber = windowController.window?.windowNumber
+ agent.showApprove(windowController: windowController, transaction: transaction, chain: chain, peerMeta: peer) { [weak self, weak interactor] transaction in
if let transaction = transaction {
self?.sendTransaction(transaction, walletId: walletId, chainId: chainId, requestId: id, interactor: interactor)
- Window.closeAllAndActivateBrowser(force: nil)
+ Window.closeWindowAndActivateNext(idToClose: windowNumber, specificBrowser: nil)
} else {
- Window.closeAllAndActivateBrowser(force: nil)
+ Window.closeWindowAndActivateNext(idToClose: windowNumber, specificBrowser: nil)
self?.rejectRequest(id: id, interactor: interactor, message: Strings.canceled)
}
}
@@ -162,12 +164,14 @@ class WalletConnect {
}
let peer = PeerMeta(wcPeerMeta: getPeerOfInteractor(interactor))
- agent.showApprove(subject: approvalSubject, meta: message ?? "", peerMeta: peer) { [weak self, weak interactor] approved in
+ let windowController = Window.showNew(closeOthers: false)
+ let windowNumber = windowController.window?.windowNumber
+ agent.showApprove(windowController: windowController, subject: approvalSubject, meta: message ?? "", peerMeta: peer) { [weak self, weak interactor] approved in
if approved {
self?.sign(id: id, payload: payload, walletId: walletId, interactor: interactor)
- Window.closeAllAndActivateBrowser(force: nil)
+ Window.closeWindowAndActivateNext(idToClose: windowNumber, specificBrowser: nil)
} else {
- Window.closeAllAndActivateBrowser(force: nil)
+ Window.closeWindowAndActivateNext(idToClose: windowNumber, specificBrowser: nil)
self?.rejectRequest(id: id, interactor: interactor, message: Strings.canceled)
}
}
diff --git a/Tokenary macOS/Window.swift b/Tokenary macOS/Window.swift
index 5494fdbd..72eddaeb 100644
--- a/Tokenary macOS/Window.swift
+++ b/Tokenary macOS/Window.swift
@@ -4,8 +4,10 @@ import Cocoa
struct Window {
- static func showNew() -> NSWindowController {
- closeAll()
+ static func showNew(closeOthers: Bool) -> NSWindowController {
+ if closeOthers {
+ closeAll()
+ }
let windowController = new
activate(windowController)
return windowController
@@ -21,19 +23,31 @@ struct Window {
window?.makeKeyAndOrderFront(nil)
}
- static func closeAllAndActivateBrowser(force browser: Browser?) {
- closeAll()
- activateBrowser(force: browser)
- }
-
- static func closeAll(updateStatusBarItem: Bool = true) {
- NSApplication.shared.windows.forEach { $0.close() }
- if updateStatusBarItem {
- Agent.shared.setupStatusBarItem()
+ static func closeWindowAndActivateNext(idToClose: Int?, specificBrowser: Browser?) {
+ if let id = idToClose, let windowToClose = NSApplication.shared.windows.first(where: { $0.windowNumber == id }) {
+ windowToClose.close()
+ }
+
+ if let window = NSApplication.shared.windows.last(where: { $0.windowNumber != idToClose && $0.isOnActiveSpace && $0.contentViewController != nil }) {
+ activateWindow(window)
+ } else {
+ activateBrowser(specific: specificBrowser)
}
}
- static func activateBrowser(force browser: Browser?) {
+ static func closeAllAndActivateBrowser(specific browser: Browser?) {
+ closeAll()
+ activateBrowser(specific: browser)
+ }
+
+ // MARK: - Private
+
+ private static func closeAll() {
+ NSApplication.shared.windows.forEach { $0.close() }
+ Agent.shared.setupStatusBarItem()
+ }
+
+ private static func activateBrowser(specific browser: Browser?) {
if let browser = browser {
activateBrowser(browser)
return
@@ -64,11 +78,7 @@ struct Window {
NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == browser.rawValue })?.activate(options: .activateIgnoringOtherApps)
}
- static var current: NSWindowController? {
- return NSApplication.shared.windows.first?.windowController
- }
-
- static var new: NSWindowController {
+ private static var new: NSWindowController {
return NSStoryboard.main.instantiateController(withIdentifier: "initial") as! NSWindowController
}
diff --git a/Tokenary.xcodeproj/project.pbxproj b/Tokenary.xcodeproj/project.pbxproj
index 8330c6e1..b6787b7d 100644
--- a/Tokenary.xcodeproj/project.pbxproj
+++ b/Tokenary.xcodeproj/project.pbxproj
@@ -123,7 +123,6 @@
2C8A09D726751A0C00993638 /* WalletConnect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A09D626751A0C00993638 /* WalletConnect.swift */; };
2C8A09DF267579EA00993638 /* AccountsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A09DE267579EA00993638 /* AccountsListViewController.swift */; };
2C8A09E326757FC000993638 /* AccountCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A09E226757FC000993638 /* AccountCellView.swift */; };
- 2C8A09E82675960D00993638 /* ErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A09E72675960D00993638 /* ErrorViewController.swift */; };
2C8A09EB2675964700993638 /* ApproveViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A09EA2675964700993638 /* ApproveViewController.swift */; };
2C8A09EE2675965F00993638 /* WaitingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A09ED2675965F00993638 /* WaitingViewController.swift */; };
2C8E47A326A322E8007B8354 /* RightClickTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8E47A226A322E8007B8354 /* RightClickTableView.swift */; };
@@ -352,7 +351,6 @@
2C8A09D626751A0C00993638 /* WalletConnect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConnect.swift; sourceTree = ""; };
2C8A09DE267579EA00993638 /* AccountsListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsListViewController.swift; sourceTree = ""; };
2C8A09E226757FC000993638 /* AccountCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountCellView.swift; sourceTree = ""; };
- 2C8A09E72675960D00993638 /* ErrorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorViewController.swift; sourceTree = ""; };
2C8A09EA2675964700993638 /* ApproveViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApproveViewController.swift; sourceTree = ""; };
2C8A09ED2675965F00993638 /* WaitingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitingViewController.swift; sourceTree = ""; };
2C8E47A226A322E8007B8354 /* RightClickTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RightClickTableView.swift; sourceTree = ""; };
@@ -678,7 +676,6 @@
2C1995412674C4B900A8E370 /* ImportViewController.swift */,
2C797E7D267BB88800F2CE2D /* WelcomeViewController.swift */,
2CDAB3712675B3F0009F8B97 /* PasswordViewController.swift */,
- 2C8A09E72675960D00993638 /* ErrorViewController.swift */,
2C901C462689E6D400D0926A /* ApproveTransactionViewController.swift */,
2C8A09EA2675964700993638 /* ApproveViewController.swift */,
2C8A09ED2675965F00993638 /* WaitingViewController.swift */,
@@ -1380,7 +1377,6 @@
2C4768A9282598C5005E8D4D /* CoinDerivationCellView.swift in Sources */,
2CB4031D281D745D00BAEBEE /* NSTableView.swift in Sources */,
2CD0B3F726AC619900488D92 /* AddAccountOptionCellView.swift in Sources */,
- 2C8A09E82675960D00993638 /* ErrorViewController.swift in Sources */,
0D059AD226C2796200EE3023 /* ApprovalSubject.swift in Sources */,
2C264BCB27B2F2FF00234393 /* TezosSafariRequest.swift in Sources */,
2C1995422674C4B900A8E370 /* ImportViewController.swift in Sources */,