You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
9.8 KiB
253 lines
9.8 KiB
//
|
|
// InstancesTableViewController.swift
|
|
// elpha-ios
|
|
//
|
|
// Created by Dwayne Harris on 8/29/18.
|
|
// Copyright © 2018 Elpha. All rights reserved.
|
|
//
|
|
|
|
import CoreData
|
|
import UIKit
|
|
|
|
struct Instance {
|
|
var id: String?
|
|
var name: String?
|
|
var addedAt: String?
|
|
var updatedAt: String?
|
|
var checkedAt: String?
|
|
var uptime: Int?
|
|
var up: Bool?
|
|
var dead: Bool?
|
|
var version: String?
|
|
var ipv6: Bool?
|
|
var httpsScore: Int?
|
|
var httpsRank: String?
|
|
var users: String?
|
|
var statuses: String?
|
|
var connections: Int?
|
|
var openRegistrations: Bool?
|
|
var thumbnail: String?
|
|
var thumbnailProxy: String?
|
|
var activeUsers: Int?
|
|
var shortDescription: String?
|
|
var fullDescription: String?
|
|
var topic: String?
|
|
var languages: [String]?
|
|
var categories: [String]?
|
|
}
|
|
|
|
class InstancesTableViewController: UITableViewController, UIViewControllerPreviewingDelegate {
|
|
@IBOutlet var mainNavigationItem: UINavigationItem!
|
|
|
|
let instanceRequestCount = 20
|
|
var instances: [Instance] = []
|
|
var nextID: String? = nil
|
|
var finished: Bool = false
|
|
|
|
var loading: Bool = false {
|
|
didSet {
|
|
DispatchQueue.main.async {
|
|
if self.loading {
|
|
UIApplication.shared.isNetworkActivityIndicatorVisible = true
|
|
self.refreshControl?.beginRefreshing()
|
|
} else {
|
|
UIApplication.shared.isNetworkActivityIndicatorVisible = false
|
|
self.refreshControl?.endRefreshing()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
|
|
|
|
mainNavigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(done))
|
|
|
|
registerForPreviewing(with: self, sourceView: tableView)
|
|
refreshControl?.addTarget(self, action: #selector(self.reloadInstances), for: .valueChanged)
|
|
|
|
loadInstances()
|
|
}
|
|
|
|
@objc func done() {
|
|
dismiss(animated: true, completion: nil)
|
|
}
|
|
|
|
@objc func reloadInstances() {
|
|
self.nextID = nil
|
|
self.finished = false
|
|
|
|
loadInstances()
|
|
}
|
|
|
|
func loadInstances() {
|
|
loading = true
|
|
|
|
var params = [
|
|
"count=\(instanceRequestCount)",
|
|
"sort_by=users",
|
|
"sort_order=desc",
|
|
"include_closed=true",
|
|
"include_down=false",
|
|
]
|
|
|
|
if let nextID = nextID {
|
|
params.append("min_id=\(nextID)")
|
|
} else {
|
|
instances = []
|
|
|
|
DispatchQueue.main.async {
|
|
self.tableView.reloadData()
|
|
}
|
|
}
|
|
|
|
let requestURL = "\(Config.instancesServiceUrl)\(Config.instancesServiceEndpoint)?\(params.joined(separator: "&"))"
|
|
|
|
print("loading instances: requestURL: \(requestURL)")
|
|
|
|
var request = URLRequest(url: URL(string: requestURL)!)
|
|
request.addValue("Bearer \(Config.instancesServiceSecret)", forHTTPHeaderField: "Authorization")
|
|
|
|
let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
guard error == nil else {
|
|
return
|
|
}
|
|
|
|
defer {
|
|
self.loading = false
|
|
}
|
|
|
|
if let response = response as? HTTPURLResponse {
|
|
switch response.statusCode {
|
|
case 200..<300:
|
|
if let data = data {
|
|
do {
|
|
let instancesResult = try JSONSerialization.jsonObject(with: data) as! [String: Any]
|
|
|
|
if let pagination = instancesResult["pagination"] as? [String: Any] {
|
|
if let nextID = pagination["next_id"] as? String {
|
|
self.nextID = nextID
|
|
} else {
|
|
self.nextID = nil
|
|
self.finished = true
|
|
}
|
|
}
|
|
|
|
if let instances = instancesResult["instances"] as? [Any] {
|
|
for case let instance as [String: Any] in instances {
|
|
var i = Instance()
|
|
i.id = instance["id"] as? String
|
|
i.name = instance["name"] as? String
|
|
i.addedAt = instance["added_at"] as? String
|
|
i.updatedAt = instance["updated_at"] as? String
|
|
i.checkedAt = instance["checked_at"] as? String
|
|
i.uptime = instance["uptime"] as? Int
|
|
i.up = instance["up"] as? Bool
|
|
i.dead = instance["dead"] as? Bool
|
|
i.version = instance["version"] as? String
|
|
i.ipv6 = instance["ipv6"] as? Bool
|
|
i.httpsScore = instance["https_score"] as? Int
|
|
i.httpsRank = instance["https_rank"] as? String
|
|
i.users = instance["users"] as? String
|
|
i.statuses = instance["statuses"] as? String
|
|
i.connections = instance["connections"] as? Int
|
|
i.openRegistrations = instance["open_registrations"] as? Bool
|
|
i.thumbnail = instance["thumbnail"] as? String
|
|
i.thumbnailProxy = instance["thumbnail_proxy"] as? String
|
|
i.activeUsers = instance["active_users"] as? Int
|
|
|
|
let info = instance["info"] as? [String: Any]
|
|
if let info = info {
|
|
i.shortDescription = info["short_description"] as? String
|
|
i.fullDescription = info["full_description"] as? String
|
|
i.topic = info["topic"] as? String
|
|
i.languages = info["languages"] as? [String]
|
|
i.categories = info["categories"] as? [String]
|
|
}
|
|
|
|
self.instances.append(i)
|
|
}
|
|
|
|
DispatchQueue.main.async {
|
|
self.tableView.reloadData()
|
|
}
|
|
}
|
|
} catch let error {
|
|
print(error)
|
|
return
|
|
}
|
|
}
|
|
case 400:
|
|
print("instances.social: 400")
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
dataTask.resume()
|
|
}
|
|
|
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
return 1
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
return instances.count
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "InstancesTableViewCell", for: indexPath) as? InstancesTableViewCell else {
|
|
fatalError("Unable to find reusable cell")
|
|
}
|
|
|
|
let instance = instances[indexPath.row]
|
|
cell.instanceNameLabel.text = instance.name
|
|
|
|
if let statuses = instance.statuses {
|
|
cell.statusesLabel.text = NumberFormatter.localizedString(from: NSNumber(value: Int64(statuses)!), number: .decimal)
|
|
}
|
|
|
|
if let users = instance.users {
|
|
cell.usersLabel.text = NumberFormatter.localizedString(from: NSNumber(value: Int64(users)!), number: .decimal)
|
|
}
|
|
|
|
if let thumbnail = instance.thumbnail {
|
|
cell.thumbnailURL = thumbnail
|
|
}
|
|
|
|
if indexPath.row == instances.count - 1 && !loading && !finished {
|
|
loadInstances()
|
|
}
|
|
|
|
return cell
|
|
}
|
|
|
|
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
if segue.identifier == "InstanceDetailSegue", let cell = segue.destination as? InstanceViewController {
|
|
if let row = tableView.indexPathForSelectedRow?.row {
|
|
cell.instance = instances[row]
|
|
}
|
|
}
|
|
}
|
|
|
|
public func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
|
|
guard let indexPath = tableView.indexPathForRow(at: location) else {
|
|
return nil
|
|
}
|
|
|
|
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
|
if let detailViewController = storyboard.instantiateViewController(withIdentifier: "InstanceViewController") as? InstanceViewController {
|
|
detailViewController.instance = instances[indexPath.row]
|
|
return detailViewController
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
|
|
navigationController?.pushViewController(viewControllerToCommit, animated: true)
|
|
}
|
|
}
|