Tunnels list: Show a busy indicator before the tunnels are loaded

This commit is contained in:
Roopesh Chander 2018-11-03 08:50:27 +05:30
parent c6df88c893
commit 4bb45397f1
1 changed files with 55 additions and 29 deletions

View File

@ -4,40 +4,66 @@
import UIKit import UIKit
import MobileCoreServices import MobileCoreServices
class TunnelsListTableViewController: UITableViewController { class TunnelsListTableViewController: UIViewController {
var tunnelsManager: TunnelsManager? = nil var tunnelsManager: TunnelsManager? = nil
var onTunnelsManagerReady: ((TunnelsManager) -> Void)? = nil var onTunnelsManagerReady: ((TunnelsManager) -> Void)? = nil
init() { var busyIndicator: UIActivityIndicatorView? = nil
super.init(style: .plain) var tableView: UITableView? = nil
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
view.backgroundColor = UIColor.white
// Set up the navigation bar
self.title = "WireGuard" self.title = "WireGuard"
let addButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addButtonTapped(sender:))) let addButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addButtonTapped(sender:)))
self.navigationItem.rightBarButtonItem = addButtonItem self.navigationItem.rightBarButtonItem = addButtonItem
let settingsButtonItem = UIBarButtonItem(title: "Settings", style: .plain, target: self, action: #selector(settingsButtonTapped(sender:))) let settingsButtonItem = UIBarButtonItem(title: "Settings", style: .plain, target: self, action: #selector(settingsButtonTapped(sender:)))
self.navigationItem.leftBarButtonItem = settingsButtonItem self.navigationItem.leftBarButtonItem = settingsButtonItem
self.tableView.rowHeight = 60 // Set up the busy indicator
let busyIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
busyIndicator.hidesWhenStopped = true
self.tableView.register(TunnelsListTableViewCell.self, forCellReuseIdentifier: TunnelsListTableViewCell.id) // Add the busyIndicator, centered
view.addSubview(busyIndicator)
busyIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
busyIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
busyIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
busyIndicator.startAnimating()
self.busyIndicator = busyIndicator
// Create the tunnels manager, and when it's ready, create the tableView
TunnelsManager.create { [weak self] tunnelsManager in TunnelsManager.create { [weak self] tunnelsManager in
guard let tunnelsManager = tunnelsManager else { return } guard let tunnelsManager = tunnelsManager else { return }
if let s = self { guard let s = self else { return }
tunnelsManager.delegate = s
s.tunnelsManager = tunnelsManager let tableView = UITableView(frame: CGRect.zero, style: .plain)
s.onTunnelsManagerReady?(tunnelsManager) tableView.rowHeight = 60
s.onTunnelsManagerReady = nil tableView.register(TunnelsListTableViewCell.self, forCellReuseIdentifier: TunnelsListTableViewCell.id)
s.tableView.reloadData()
} s.view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.leftAnchor.constraint(equalTo: s.view.leftAnchor),
tableView.rightAnchor.constraint(equalTo: s.view.rightAnchor),
tableView.topAnchor.constraint(equalTo: s.view.topAnchor),
tableView.bottomAnchor.constraint(equalTo: s.view.bottomAnchor)
])
tableView.dataSource = s
tableView.delegate = s
s.tableView = tableView
busyIndicator.stopAnimating()
tunnelsManager.delegate = s
s.tunnelsManager = tunnelsManager
s.onTunnelsManagerReady?(tunnelsManager)
s.onTunnelsManagerReady = nil
} }
} }
@ -238,16 +264,16 @@ extension TunnelsListTableViewController: QRScanViewControllerDelegate {
// MARK: UITableViewDataSource // MARK: UITableViewDataSource
extension TunnelsListTableViewController { extension TunnelsListTableViewController: UITableViewDataSource {
override func numberOfSections(in tableView: UITableView) -> Int { func numberOfSections(in tableView: UITableView) -> Int {
return 1 return 1
} }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (tunnelsManager?.numberOfTunnels() ?? 0) return (tunnelsManager?.numberOfTunnels() ?? 0)
} }
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelsListTableViewCell.id, for: indexPath) as! TunnelsListTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: TunnelsListTableViewCell.id, for: indexPath) as! TunnelsListTableViewCell
if let tunnelsManager = tunnelsManager { if let tunnelsManager = tunnelsManager {
let tunnel = tunnelsManager.tunnel(at: indexPath.row) let tunnel = tunnelsManager.tunnel(at: indexPath.row)
@ -276,8 +302,8 @@ extension TunnelsListTableViewController {
// MARK: UITableViewDelegate // MARK: UITableViewDelegate
extension TunnelsListTableViewController { extension TunnelsListTableViewController: UITableViewDelegate {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let tunnelsManager = tunnelsManager else { return } guard let tunnelsManager = tunnelsManager else { return }
let tunnel = tunnelsManager.tunnel(at: indexPath.row) let tunnel = tunnelsManager.tunnel(at: indexPath.row)
let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager,
@ -286,7 +312,7 @@ extension TunnelsListTableViewController {
showDetailViewController(tunnelDetailNC, sender: self) // Shall get propagated up to the split-vc showDetailViewController(tunnelDetailNC, sender: self) // Shall get propagated up to the split-vc
} }
override func tableView(_ tableView: UITableView, func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete", handler: { [weak self] (_, _, completionHandler) in let deleteAction = UIContextualAction(style: .destructive, title: "Delete", handler: { [weak self] (_, _, completionHandler) in
guard let tunnelsManager = self?.tunnelsManager else { return } guard let tunnelsManager = self?.tunnelsManager else { return }
@ -308,19 +334,19 @@ extension TunnelsListTableViewController {
extension TunnelsListTableViewController: TunnelsManagerDelegate { extension TunnelsListTableViewController: TunnelsManagerDelegate {
func tunnelAdded(at index: Int) { func tunnelAdded(at index: Int) {
tableView.insertRows(at: [IndexPath(row: index, section: 0)], with: .automatic) tableView?.insertRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
} }
func tunnelModified(at index: Int) { func tunnelModified(at index: Int) {
tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic) tableView?.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
} }
func tunnelMoved(at oldIndex: Int, to newIndex: Int) { func tunnelMoved(at oldIndex: Int, to newIndex: Int) {
tableView.moveRow(at: IndexPath(row: oldIndex, section: 0), to: IndexPath(row: newIndex, section: 0)) tableView?.moveRow(at: IndexPath(row: oldIndex, section: 0), to: IndexPath(row: newIndex, section: 0))
} }
func tunnelRemoved(at index: Int) { func tunnelRemoved(at index: Int) {
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic) tableView?.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
} }
} }