VPN initial
This commit is contained in:
138
main/TVCDomains.swift
Normal file
138
main/TVCDomains.swift
Normal file
@@ -0,0 +1,138 @@
|
||||
import UIKit
|
||||
import NetworkExtension
|
||||
|
||||
|
||||
class TVCDomains: UITableViewController {
|
||||
|
||||
private let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
||||
private var dataSource: [GroupedDomain] = []
|
||||
@IBOutlet private var welcomeMessage: UITextView!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.welcomeMessage.frame.size.height = 0
|
||||
// AppInfoType.initWorkingDir()
|
||||
|
||||
NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: OperationQueue.main) { [weak self] notification in
|
||||
self?.changeState((notification.object as? NETunnelProviderSession)?.status ?? .invalid)
|
||||
}
|
||||
NotificationCenter.default.addObserver(forName: .init("ChangedStateGlassVPN"), object: nil, queue: OperationQueue.main) { [weak self] notification in
|
||||
self?.changeState((notification.object as? NEVPNStatus) ?? .invalid)
|
||||
}
|
||||
|
||||
// pull-to-refresh
|
||||
tableView.refreshControl = UIRefreshControl()
|
||||
tableView.refreshControl?.addTarget(self, action: #selector(reloadDataSource(_:)), for: .valueChanged)
|
||||
performSelector(inBackground: #selector(reloadDataSource(_:)), with: nil)
|
||||
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: OperationQueue.main) { [weak self] _ in
|
||||
self?.reloadDataSource(nil)
|
||||
}
|
||||
// navigationItem.leftBarButtonItem?.title = "\u{2699}\u{0000FE0E}☰"
|
||||
// navigationItem.leftBarButtonItem?.setTitleTextAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 32)], for: .normal)
|
||||
}
|
||||
|
||||
@IBAction func clickToolbarLeft(_ sender: Any) {
|
||||
let alert = UIAlertController(title: "Clear results?",
|
||||
message: "You are about to delete all results that have been logged in the past. Continue?", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: { [weak self] _ in
|
||||
try? SQLiteDatabase.open(path: DB_PATH).destroyContent()
|
||||
self?.reloadDataSource(nil)
|
||||
}))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@IBAction func clickToolbarRight(_ sender: Any) {
|
||||
let active = (self.navigationItem.rightBarButtonItem?.tag == NEVPNStatus.connected.rawValue)
|
||||
let alert = UIAlertController(title: "\(active ? "Dis" : "En")able Proxy?",
|
||||
message: "The VPN proxy is currently \(active ? "en" : "dis")abled, do you want to proceed and \(active ? "dis" : "en")able logging?", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
alert.addAction(UIAlertAction(title: active ? "Disable" : "Enable", style: .default, handler: { [weak self] _ in
|
||||
self?.appDelegate.setProxyEnabled(!active)
|
||||
}))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func changeState(_ newState: NEVPNStatus) {
|
||||
let stateView = self.navigationItem.rightBarButtonItem
|
||||
if stateView?.tag == newState.rawValue {
|
||||
return // don't need to change, already correct state
|
||||
}
|
||||
stateView?.tag = newState.rawValue
|
||||
switch newState {
|
||||
case .connected:
|
||||
stateView?.title = "Active"
|
||||
stateView?.tintColor = .systemGreen
|
||||
case .connecting, .disconnecting, .reasserting:
|
||||
stateView?.title = "Updating"
|
||||
stateView?.tintColor = .systemYellow
|
||||
case .invalid, .disconnected:
|
||||
fallthrough
|
||||
@unknown default:
|
||||
stateView?.title = "Inactive"
|
||||
stateView?.tintColor = .systemRed
|
||||
}
|
||||
// let newButton = UIBarButtonItem(barButtonSystemItem: (active ? .pause : .play), target: self, action: #selector(clickToolbarRight(_:)))
|
||||
// newButton.tintColor = (active ? .systemRed : .systemGreen)
|
||||
// newButton.tag = (active ? 1 : 0)
|
||||
// self.navigationItem.setRightBarButton(newButton, animated: true)
|
||||
}
|
||||
|
||||
private func updateCellAt(_ index: Int) {
|
||||
DispatchQueue.main.async {
|
||||
guard index >= 0 else {
|
||||
self.welcomeMessage.frame.size.height = (self.dataSource.count == 0 ? self.view.frame.size.height : 0)
|
||||
self.tableView.reloadData()
|
||||
return
|
||||
}
|
||||
if let idx = self.tableView.indexPathsForVisibleRows?.first(where: { indexPath -> Bool in
|
||||
indexPath.row == index
|
||||
}) {
|
||||
self.tableView.reloadRows(at: [idx], with: .automatic)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
if let index = tableView.indexPathForSelectedRow?.row {
|
||||
let dom = dataSource[index].label
|
||||
segue.destination.navigationItem.prompt = dom
|
||||
(segue.destination as? TVCHosts)?.domain = dom
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Table View Delegate
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return dataSource.count
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "DomainCell")!
|
||||
let entry = dataSource[indexPath.row]
|
||||
let last = Date.init(timeIntervalSince1970: Double(entry.lastModified))
|
||||
|
||||
cell.textLabel?.text = entry.label
|
||||
cell.detailTextLabel?.text = "\(dateFormatter.string(from: last)) — \(entry.count)"
|
||||
return cell
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Data Source
|
||||
|
||||
@objc private func reloadDataSource(_ sender : Any?) {
|
||||
self.dataSource = self.sqliteAppList()
|
||||
if let refreshControl = sender as? UIRefreshControl {
|
||||
DispatchQueue.main.async { refreshControl.endRefreshing() }
|
||||
}
|
||||
self.updateCellAt(-1)
|
||||
}
|
||||
|
||||
private func sqliteAppList() -> [GroupedDomain] {
|
||||
guard let db = try? SQLiteDatabase.open(path: DB_PATH) else {
|
||||
return []
|
||||
}
|
||||
return db.domainList()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user