/
HistoryPanel.swift
155 lines (133 loc) · 5.97 KB
/
HistoryPanel.swift
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
/* 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 Storage
private func getDate(#dayOffset: Int) -> NSDate {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let nowComponents = calendar.components(NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay, fromDate: NSDate())
let today = calendar.dateFromComponents(nowComponents)!
return calendar.dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: dayOffset, toDate: today, options: nil)!
}
class HistoryPanel: SiteTableViewController, HomePanel {
weak var homePanelDelegate: HomePanelDelegate? = nil
private let NumSections = 4
private let Today = getDate(dayOffset: 0)
private let Yesterday = getDate(dayOffset: -1)
private let ThisWeek = getDate(dayOffset: -7)
private var sectionOffsets = [Int: Int]()
override func reloadData() {
let opts = QueryOptions()
opts.sort = .LastVisit
profile.history.get(opts).uponQueue(dispatch_get_main_queue()) { result in
if let data = result.successValue {
self.sectionOffsets = [Int: Int]()
self.data = data
self.tableView.reloadData()
}
// TODO: error handling.
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
let offset = sectionOffsets[indexPath.section]!
if let site = data[indexPath.row + offset] as? Site {
if let cell = cell as? TwoLineTableViewCell {
cell.setLines(site.title, detailText: site.url)
if let img = site.icon {
let imgURL = NSURL(string: img.url)
cell.imageView?.sd_setImageWithURL(imgURL, placeholderImage: self.profile.favicons.defaultIcon)
} else {
cell.imageView?.image = self.profile.favicons.defaultIcon
}
}
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let offset = sectionOffsets[indexPath.section]!
if let site = data[indexPath.row + offset] as? Site {
if let url = NSURL(string: site.url) {
homePanelDelegate?.homePanel(self, didSelectURL: url)
return
}
}
println("Could not click on history row")
}
// Functions that deal with showing header rows
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return NumSections
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
var title = String()
switch section {
case 0: title = NSLocalizedString("Today", comment: "History tableview section header")
case 1: title = NSLocalizedString("Yesterday", comment: "History tableview section header")
case 2: title = NSLocalizedString("Last week", comment: "History tableview section header")
case 3: title = NSLocalizedString("Last month", comment: "History tableview section header")
default:
assertionFailure("Invalid history section \(section)")
}
return title.uppercaseString
}
private func isInSection(date: MicrosecondTimestamp, section: Int) -> Bool {
let date = Double(date)
switch section {
case 0:
return date > (1000 * Today.timeIntervalSince1970)
case 1:
return date > (1000 * Yesterday.timeIntervalSince1970)
case 2:
return date > (1000 * ThisWeek.timeIntervalSince1970)
default:
return true
}
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if let current = sectionOffsets[section] {
if let next = sectionOffsets[section+1] {
if current == next {
// If this points to the same element as the next one, it's empty. Don't show it.
return 0
}
}
} else {
// This may not be filled in yet (for instance, if the number of rows in data is zero). If it is,
// just return zero.
return 0
}
// Return the default height for header rows
return super.tableView(tableView, heightForHeaderInSection: section)
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let size = sectionOffsets[section] {
if let nextSize = sectionOffsets[section+1] {
return nextSize - size
}
}
var searchingSection = 0
sectionOffsets[searchingSection] = 0
// Loop over all the data. Record the start of each "section" of our list.
for i in 0..<data.count {
if let site = data[i] as? Site {
if !isInSection(site.latestVisit!.date, section: searchingSection) {
searchingSection++
sectionOffsets[searchingSection] = i
}
if searchingSection == NumSections {
break
}
}
}
// Now fill in any sections that weren't found with data.count.
// Note, we actually fill in one past the end of the list to make finding the length
// of a section easier.
searchingSection++
for i in searchingSection...NumSections {
sectionOffsets[i] = data.count
}
// This function wants the size of a section, so return the distance between two adjacent ones
return sectionOffsets[section+1]! - sectionOffsets[section]!
}
}