From c1b6be772c109b99aa6f89816a34a18644d2d371 Mon Sep 17 00:00:00 2001 From: Soner Yuksel Date: Fri, 26 May 2023 12:42:50 -0400 Subject: [PATCH 1/3] Infinite loading spinner guarantee status handling --- .../Toolbars/BottomToolbar/Menu/VPNMenuButton.swift | 7 ++++++- Sources/BraveVPN/BraveVPN.swift | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Sources/Brave/Frontend/Browser/Toolbars/BottomToolbar/Menu/VPNMenuButton.swift b/Sources/Brave/Frontend/Browser/Toolbars/BottomToolbar/Menu/VPNMenuButton.swift index ad972be50a1..828253c2d92 100644 --- a/Sources/Brave/Frontend/Browser/Toolbars/BottomToolbar/Menu/VPNMenuButton.swift +++ b/Sources/Brave/Frontend/Browser/Toolbars/BottomToolbar/Menu/VPNMenuButton.swift @@ -110,7 +110,12 @@ struct VPNMenuButton: View { } .onReceive(NotificationCenter.default.publisher(for: .NEVPNStatusDidChange)) { _ in isVPNEnabled = BraveVPN.isConnected - isVPNStatusChanging = BraveVPN.reconnectPending + + if BraveVPN.isConnected { + isVPNStatusChanging = false + } else { + isVPNStatusChanging = BraveVPN.reconnectPending + } } } } diff --git a/Sources/BraveVPN/BraveVPN.swift b/Sources/BraveVPN/BraveVPN.swift index 2df3307988e..29459283a59 100644 --- a/Sources/BraveVPN/BraveVPN.swift +++ b/Sources/BraveVPN/BraveVPN.swift @@ -279,9 +279,10 @@ public class BraveVPN { logAndStoreError("configureAndConnectVPN: \(error)") } + reconnectPending = false + // Re-connected user should update last used region - detail is pulled fetchLastUsedRegionDetail() { _, _ in - reconnectPending = false DispatchQueue.main.async { completion?(status == .success) } @@ -302,9 +303,10 @@ public class BraveVPN { helper.ikev2VPNManager.removeFromPreferences() } + reconnectPending = false + // First time user will connect automatic region - detail is pulled fetchLastUsedRegionDetail() { _, _ in - reconnectPending = false DispatchQueue.main.async { completion?(success) } From 264b0f617a6c0916f479054f26ea5d6a1096be5c Mon Sep 17 00:00:00 2001 From: Soner Yuksel Date: Fri, 26 May 2023 15:09:37 -0400 Subject: [PATCH 2/3] Adding proper loading to actions for install Adding retry to install --- Sources/BraveVPN/BuyVPNViewController.swift | 74 ++++++++++--------- .../BraveVPN/InstallVPNViewController.swift | 53 ++++++++----- 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/Sources/BraveVPN/BuyVPNViewController.swift b/Sources/BraveVPN/BuyVPNViewController.swift index d0e643c4290..32a979ae4c9 100644 --- a/Sources/BraveVPN/BuyVPNViewController.swift +++ b/Sources/BraveVPN/BuyVPNViewController.swift @@ -9,7 +9,7 @@ import Preferences import StoreKit import os.log -class BuyVPNViewController: UIViewController { +class BuyVPNViewController: VPNSetupLoadingController { let iapObserver: IAPObserver @@ -29,40 +29,6 @@ class BuyVPNViewController: UIViewController { view = View() } - /// View to show when the vpn purchase is pending. - private var overlayView: UIView? - - private var isLoading: Bool = false { - didSet { - overlayView?.removeFromSuperview() - - // Toggle 'restore' button. - navigationItem.rightBarButtonItem?.isEnabled = !isLoading - - // Prevent dismissing the modal by swipe when the VPN is being configured - navigationController?.isModalInPresentation = isLoading == true - - if !isLoading { return } - - let overlay = UIView().then { - $0.backgroundColor = UIColor.black.withAlphaComponent(0.5) - let activityIndicator = UIActivityIndicatorView().then { indicator in - indicator.startAnimating() - indicator.autoresizingMask = [.flexibleWidth, .flexibleHeight] - } - - $0.addSubview(activityIndicator) - } - - buyVPNView.addSubview(overlay) - overlay.snp.makeConstraints { - $0.edges.equalToSuperview() - } - - overlayView = overlay - } - } - override func viewDidLoad() { super.viewDidLoad() @@ -175,3 +141,41 @@ extension BuyVPNViewController: IAPObserverDelegate { } } } + +class VPNSetupLoadingController: UIViewController { + + private var overlayView: UIView? + + var isLoading: Bool = false { + didSet { + overlayView?.removeFromSuperview() + + // Disable Action bar button while loading + navigationItem.rightBarButtonItem?.isEnabled = !isLoading + + // Prevent dismissing the modal by swipe + navigationController?.isModalInPresentation = isLoading == true + + if !isLoading { return } + + let overlay = UIView().then { + $0.backgroundColor = UIColor.black.withAlphaComponent(0.5) + let activityIndicator = UIActivityIndicatorView().then { + $0.startAnimating() + $0.autoresizingMask = [.flexibleWidth, .flexibleHeight] + $0.style = .large + $0.color = .white + } + + $0.addSubview(activityIndicator) + } + + view.addSubview(overlay) + overlay.snp.makeConstraints { + $0.edges.equalToSuperview() + } + + overlayView = overlay + } + } +} diff --git a/Sources/BraveVPN/InstallVPNViewController.swift b/Sources/BraveVPN/InstallVPNViewController.swift index 5ec76baa08a..fadb9511b92 100644 --- a/Sources/BraveVPN/InstallVPNViewController.swift +++ b/Sources/BraveVPN/InstallVPNViewController.swift @@ -8,11 +8,13 @@ import Shared import Lottie import BraveUI -class InstallVPNViewController: UIViewController { +class InstallVPNViewController: VPNSetupLoadingController { private var installVPNView: View { return view as! View // swiftlint:disable:this force_cast } + + private var installVPNProfileRetryCount = 0 override func loadView() { view = View() @@ -48,33 +50,44 @@ class InstallVPNViewController: UIViewController { } @objc func installVPNAction() { - installVPNView.installVPNButton.isLoading = true + isLoading = true - BraveVPN.connectToVPN() { [weak self] status in - guard let self = self else { return } + installProfileAndConnectVPNFirstTime { [weak self] status in + guard let self else { return } - DispatchQueue.main.async { - self.installVPNView.installVPNButton.isLoading = false - } - if status { self.dismiss(animated: true) { self.showSuccessAlert() } - } else { - let okAction = UIAlertAction(title: Strings.OKString, style: .default) - - let message = Strings.VPN.vpnConfigGenericErrorBody - let alert = UIAlertController(title: Strings.VPN.vpnConfigGenericErrorTitle, - message: message, - preferredStyle: .alert) - alert.addAction(okAction) - - DispatchQueue.main.async { - self.present(alert, animated: true) - } + } else if self.installVPNProfileRetryCount < 2 { + // Retry installing profile if it fails first time + presentErrorVPNInstallProfile() } } + + func presentErrorVPNInstallProfile() { + let alert = UIAlertController(title: Strings.VPN.vpnConfigGenericErrorTitle, + message: Strings.VPN.vpnConfigGenericErrorBody, + preferredStyle: .alert) + + alert.addAction(UIAlertAction(title: Strings.OKString, style: .default)) + + DispatchQueue.main.async { + self.present(alert, animated: true) + } + } + } + + private func installProfileAndConnectVPNFirstTime(completion: @escaping (Bool) -> Void) { + installVPNProfileRetryCount += 1 + + BraveVPN.connectToVPN() { [weak self] status in + DispatchQueue.main.async { + self?.isLoading = true + } + + completion(status) + } } @objc private func contactSupportAction() { From 524aa07b7f699c3d01f4fe9fdb0443cf258e9eb7 Mon Sep 17 00:00:00 2001 From: Soner Yuksel Date: Fri, 26 May 2023 16:55:34 -0400 Subject: [PATCH 3/3] Fixing retry and loading cases --- Sources/BraveVPN/InstallVPNViewController.swift | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Sources/BraveVPN/InstallVPNViewController.swift b/Sources/BraveVPN/InstallVPNViewController.swift index fadb9511b92..29f1af33d8b 100644 --- a/Sources/BraveVPN/InstallVPNViewController.swift +++ b/Sources/BraveVPN/InstallVPNViewController.swift @@ -59,9 +59,14 @@ class InstallVPNViewController: VPNSetupLoadingController { self.dismiss(animated: true) { self.showSuccessAlert() } - } else if self.installVPNProfileRetryCount < 2 { - // Retry installing profile if it fails first time - presentErrorVPNInstallProfile() + } else { + // Retry installing profile twice if it fails + // Error generated is WireGuard capabilities are not yet enabled on this node + if self.installVPNProfileRetryCount < 2 { + installVPNAction() + } else { + presentErrorVPNInstallProfile() + } } } @@ -83,7 +88,7 @@ class InstallVPNViewController: VPNSetupLoadingController { BraveVPN.connectToVPN() { [weak self] status in DispatchQueue.main.async { - self?.isLoading = true + self?.isLoading = false } completion(status)