aboutsummaryrefslogtreecommitdiff
path: root/foray/ForayTableViewController.swift
blob: a16c3bbd27a08b9a5205dc61c93095f28a8d1cba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//
//  ForayTableViewController.swift
//  foray
//
//  Created by Nicholas Tay on 14/3/2022.
//

import UIKit

enum ItemType: String, Decodable {
    case item
    case quest
}

struct PenguinItem: Decodable {
    var type: ItemType
    var releaseDate: Date
    var id: String
    var name: String
}

struct YearSection {
    var year: Date
    var items: [PenguinItem]
}

private func parseDate(_ str : String) -> Date {
    let dateFormat = DateFormatter()
    dateFormat.dateFormat = "yyyy-MM-dd"
    return dateFormat.date(from: str)!
}

private func firstDayOfYear(date: Date) -> Date {
    let calendar = Calendar.current
    let components = calendar.dateComponents([.year], from: date)
    return calendar.date(from: components)!
}

class ForayTableViewController: UITableViewController {
    
    // MARK: - Static data TEMP
    
    var sections = [YearSection]()
    
    // MARK: - On load
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.rowHeight = UITableView.automaticDimension
        
        // Register our custom cell
        tableView.register(ForayNewTableViewCell.self, forCellReuseIdentifier: "ForayNewTableViewCell")
        
        // Not sure if this is the right way to go about this...
        let alert = UIAlertController(title: nil, message: "Grabbing data...", preferredStyle: .alert)
        let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
        loadingIndicator.hidesWhenStopped = true
        loadingIndicator.style = UIActivityIndicatorView.Style.medium
        loadingIndicator.startAnimating();
        alert.view.addSubview(loadingIndicator)
        present(alert, animated: true, completion: nil)
        
        reloadApiData()
        
        dismiss(animated: false, completion: nil)
        
        // Not 100% sure what this does (the for: bit)
        self.refreshControl?.addTarget(self, action: #selector(doRefresh), for: UIControl.Event.valueChanged)
    }
    
    @objc func doRefresh(sender: AnyObject) {
        reloadApiData()
    }
    
    func reloadApiData() {
        loadApiData(onComplete: { (apiItems) in
            var items = apiItems
            items.sort { (lhs, rhs) in lhs.releaseDate < rhs.releaseDate }
            
            let groups = Dictionary(grouping: apiItems) { (item) in
                return firstDayOfYear(date: item.releaseDate)
            }
            self.sections = groups.map { (key, values) in
                return YearSection(year: key, items: values)
            }
            // Sort the sections from oldest year to newest
            self.sections.sort { (lhs, rhs) in lhs.year < rhs.year }
            
            self.tableView.reloadData()
            self.refreshControl?.endRefreshing()
        })
    }
    
    func loadApiData(onComplete: @escaping ([PenguinItem]) -> ()) {
        var request = URLRequest(url: URL(string: "https://users.windblume.net/~nick/upload/dummy.json")!)
        request.cachePolicy = .reloadRevalidatingCacheData // Needed otherwise default caching policy seems not to check properly
        
        // Basic auth if required
        //let authData = ("ext:PASSWORD").data(using: .utf8)!.base64EncodedString()
        //request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization")

        URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
            print("finished getting data")
            print(response!)
            
            let jsonDecoder = JSONDecoder()
            jsonDecoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
                let container = try decoder.singleValueContainer()
                let dateStr = try container.decode(String.self)
                return parseDate(dateStr)
            })
            let items = try! jsonDecoder.decode([PenguinItem].self, from: data!)
            print("json decoded")
            
            // Passing back to UI, need to do it on the main thread (I think due to async?)
            DispatchQueue.main.async {
                onComplete(items)
            }
        }).resume()
    }
    
    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // Returns number of sections for table
        return self.sections.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Returns number of rows for table's section
        return self.sections[section].items.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = self.sections[indexPath.section].items[indexPath.row]
        
        let type: String
        let icon: UIImage
        switch item.type {
        case .item:
            type = "Item"
            icon = UIImage(named: item.id)!
        case .quest:
            type = "Quest"
            icon = UIImage(named: "spy")!
        }
        
        let cell: ForayNewTableViewCell = tableView.dequeueReusableCell(withIdentifier: "ForayNewTableViewCell", for: indexPath) as! ForayNewTableViewCell
        cell.setData(name: item.name, desc: type + "ID: " + item.id, img: icon)
        return cell
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let section = self.sections[section]
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy"
        return "Released in " + dateFormatter.string(from: section.year)
    }
    
    let detailViewController: ForayDetailViewController = ForayDetailViewController()
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let item = self.sections[indexPath.section].items[indexPath.row]
        detailViewController.selectedItem = item
        
        self.navigationController?.pushViewController(detailViewController, animated: true)
    }
}