Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Adding Protocol picker and making changes to region picker
Browse files Browse the repository at this point in the history
  • Loading branch information
soner-yuksel committed Apr 26, 2023
1 parent d172915 commit 737993c
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 95 deletions.
115 changes: 115 additions & 0 deletions Sources/BraveVPN/BraveVPNPickerViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2020 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

import UIKit
import Shared
import BraveUI
import Lottie
import NetworkExtension
import GuardianConnect

class BraveVPNPickerViewController: UIViewController {

private var overlayView: UIView?
let tableView: UITableView = .init(frame: .zero, style: .insetGrouped)

deinit {
NotificationCenter.default.removeObserver(self)
}

var isLoading: Bool = false {
didSet {
overlayView?.removeFromSuperview()

navigationItem.hidesBackButton = isLoading

// Prevent dismissing the modal by swipe when the VPN is being configured
navigationController?.isModalInPresentation = isLoading

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)
}

view.addSubview(overlay)
overlay.snp.makeConstraints {
$0.edges.equalToSuperview()
}

overlayView = overlay
}
}

init() {
super.init(nibName: nil, bundle: nil)
}

@available(*, unavailable)
required init?(coder: NSCoder) { fatalError() }

override func viewDidLoad() {
tableView.register(VPNRegionCell.self)

NotificationCenter.default.addObserver(self, selector: #selector(vpnConfigChanged(notification:)),
name: .NEVPNStatusDidChange, object: nil)

view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}

@objc func vpnConfigChanged(notification: NSNotification) {
}

func showSuccessAlert() {
let animation = AnimationView(name: "vpncheckmark", bundle: .module).then {
$0.bounds = CGRect(x: 0, y: 0, width: 300, height: 200)
$0.contentMode = .scaleAspectFill
$0.play()
}

let popup = AlertPopupView(imageView: animation,
title: Strings.VPN.regionSwitchSuccessPopupText, message: "",
titleWeight: .semibold, titleSize: 18,
dismissHandler: { true })

popup.showWithType(showType: .flyUp, autoDismissTime: 1.5)
}

func showErrorAlert(title: String, message: String?) {
let alert = AlertController(title: Strings.VPN.regionPickerErrorTitle,
message: Strings.VPN.regionPickerErrorMessage,
preferredStyle: .alert)
let okAction = UIAlertAction(title: Strings.OKString, style: .default) { _ in
self.dismiss(animated: true)
}
alert.addAction(okAction)

present(alert, animated: true)
}
}

class VPNRegionCell: UITableViewCell, TableViewReusable {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}
@available(*, unavailable)
required init(coder: NSCoder) {
fatalError()
}
}
85 changes: 85 additions & 0 deletions Sources/BraveVPN/BraveVPNProtocolPickerViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

import UIKit
import Shared
import BraveUI
import Lottie
import NetworkExtension
import GuardianConnect

class BraveVPNProtocolPickerViewController: BraveVPNPickerViewController {

private let regionList: [GRDRegion]

/// This group monitors vpn connection status.
private var dispatchGroup: DispatchGroup?
private var vpnRegionChangeSuccess = false

override init() {
self.regionList = BraveVPN.regions
.sorted { $0.displayName < $1.displayName }

super.init()
}

@available(*, unavailable)
required init?(coder: NSCoder) { fatalError() }

override func viewDidLoad() {
title = "Transport Protocol"

tableView.delegate = self
tableView.dataSource = self

super.viewDidLoad()
}

override func vpnConfigChanged(notification: NSNotification) {
guard let connection = notification.object as? NEVPNConnection else { return }

if connection.status == .connected {
dispatchGroup?.leave()
self.vpnRegionChangeSuccess = true
dispatchGroup = nil
}
}
}

// MARK: - UITableView Data Source & Delegate

extension BraveVPNProtocolPickerViewController: UITableViewDelegate, UITableViewDataSource {

func numberOfSections(in tableView: UITableView) -> Int {
1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
regionList.count
}

func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "Please select your preferred transport protocol. Once switched your existing VPN credentials will be cleared and you will be reconnected if a VPN connection is currently established"
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(for: indexPath) as VPNRegionCell
cell.accessoryType = .none

guard let server = regionList[safe: indexPath.row] else { return cell }
cell.textLabel?.text = server.displayName

if server.displayName == BraveVPN.selectedRegion?.displayName {
cell.accessoryType = .checkmark
}

return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)

}
}
108 changes: 14 additions & 94 deletions Sources/BraveVPN/BraveVPNRegionPickerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,60 +10,23 @@ import Lottie
import NetworkExtension
import GuardianConnect

class BraveVPNRegionPickerViewController: UIViewController {

private var overlayView: UIView?
private let tableView: UITableView = .init(frame: .zero, style: .insetGrouped)
class BraveVPNRegionPickerViewController: BraveVPNPickerViewController {
private let regionList: [GRDRegion]

private enum Section: Int, CaseIterable {
case automatic = 0
case regionList
}

deinit {
NotificationCenter.default.removeObserver(self)
}

/// This group monitors vpn connection status.
private var dispatchGroup: DispatchGroup?
private var vpnRegionChangeSuccess = false

private var isLoading: Bool = false {
didSet {
overlayView?.removeFromSuperview()

navigationItem.hidesBackButton = isLoading

// Prevent dismissing the modal by swipe when the VPN is being configured
navigationController?.isModalInPresentation = isLoading

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)
}

view.addSubview(overlay)
overlay.snp.makeConstraints {
$0.edges.equalToSuperview()
}

overlayView = overlay
}
}

init() {
override init() {
self.regionList = BraveVPN.regions
.sorted { $0.displayName < $1.displayName }

super.init(nibName: nil, bundle: nil)
super.init()
}

@available(*, unavailable)
Expand All @@ -74,18 +37,11 @@ class BraveVPNRegionPickerViewController: UIViewController {

tableView.delegate = self
tableView.dataSource = self
tableView.register(VPNRegionCell.self)

NotificationCenter.default.addObserver(self, selector: #selector(vpnConfigChanged(notification:)),
name: .NEVPNStatusDidChange, object: nil)

view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
super.viewDidLoad()
}

@objc private func vpnConfigChanged(notification: NSNotification) {
override func vpnConfigChanged(notification: NSNotification) {
guard let connection = notification.object as? NEVPNConnection else { return }

if connection.status == .connected {
Expand All @@ -94,15 +50,12 @@ class BraveVPNRegionPickerViewController: UIViewController {
dispatchGroup = nil
}
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
}

// MARK: - UITableView Data Source & Delegate

extension BraveVPNRegionPickerViewController: UITableViewDelegate, UITableViewDataSource {

func numberOfSections(in tableView: UITableView) -> Int {
Section.allCases.count
}
Expand Down Expand Up @@ -167,24 +120,13 @@ extension BraveVPNRegionPickerViewController: UITableViewDelegate, UITableViewDa
BraveVPN.changeVPNRegion(to: newRegion) { [weak self] success in
guard let self = self else { return }

func _showError() {
if !success {
DispatchQueue.main.async {
let alert = AlertController(title: Strings.VPN.regionPickerErrorTitle,
message: Strings.VPN.regionPickerErrorMessage,
preferredStyle: .alert)
let okAction = UIAlertAction(title: Strings.OKString, style: .default) { _ in
self.dismiss(animated: true)
}
alert.addAction(okAction)

self.present(alert, animated: true)
self.showErrorAlert(title: Strings.VPN.regionPickerErrorTitle,
message: Strings.VPN.regionPickerErrorMessage)
}
}

if !success {
_showError()
}

// Changing vpn server settings takes lot of time,
// and nothing we can do about it as it relies on Apple apis.
// Here we observe vpn status and we show success alert if it connected,
Expand All @@ -205,34 +147,12 @@ extension BraveVPNRegionPickerViewController: UITableViewDelegate, UITableViewDa
self.showSuccessAlert()
}
} else {
_showError()
DispatchQueue.main.async {
self.showErrorAlert(title: Strings.VPN.regionPickerErrorTitle,
message: Strings.VPN.regionPickerErrorMessage)
}
}
}
}
}

private func showSuccessAlert() {
let animation = AnimationView(name: "vpncheckmark", bundle: .module).then {
$0.bounds = CGRect(x: 0, y: 0, width: 300, height: 200)
$0.contentMode = .scaleAspectFill
$0.play()
}

let popup = AlertPopupView(imageView: animation,
title: Strings.VPN.regionSwitchSuccessPopupText, message: "",
titleWeight: .semibold, titleSize: 18,
dismissHandler: { true })

popup.showWithType(showType: .flyUp, autoDismissTime: 1.5)
}
}

private class VPNRegionCell: UITableViewCell, TableViewReusable {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .value1, reuseIdentifier: reuseIdentifier)
}
@available(*, unavailable)
required init(coder: NSCoder) {
fatalError()
}
}
2 changes: 1 addition & 1 deletion Sources/BraveVPN/BraveVPNSettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public class BraveVPNSettingsViewController: TableViewController {
}

private func selectProtocolTapped() {
let vc = BraveVPNRegionPickerViewController()
let vc = BraveVPNProtocolPickerViewController()
navigationController?.pushViewController(vc, animated: true)
}

Expand Down

0 comments on commit 737993c

Please sign in to comment.