-
Notifications
You must be signed in to change notification settings - Fork 27
/
TabsPayload.swift
127 lines (103 loc) · 3.85 KB
/
TabsPayload.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
/* 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 Foundation
import Shared
import Storage
import XCGLogger
import SwiftyJSON
private let log = Logger.browserLogger
open class TabsPayload: CleartextPayloadJSON {
open class Tab {
let title: String
let urlHistory: [String]
let lastUsed: Timestamp
let icon: String?
fileprivate init(title: String, urlHistory: [String], lastUsed: Timestamp, icon: String?) {
self.title = title
self.urlHistory = urlHistory
self.lastUsed = lastUsed
self.icon = icon
}
func toRemoteTabForClient(_ guid: GUID) -> RemoteTab? {
let urls = optFilter(urlHistory.map({ $0.asURL }))
if urls.isEmpty {
log.debug("Bug 1201875 - Discarding tab as history has no conforming URLs.")
return nil
}
return RemoteTab(clientGUID: guid, URL: urls[0], title: self.title, history: urls, lastUsed: self.lastUsed, icon: self.icon?.asURL)
}
class func remoteTabFromJSON(_ json: JSON, clientGUID: GUID) -> RemoteTab? {
return fromJSON(json)?.toRemoteTabForClient(clientGUID)
}
class func fromJSON(_ json: JSON) -> Tab? {
func getLastUsed(_ json: JSON) -> Timestamp? {
// This might be a string or a number.
if let num = json["lastUsed"].int64 {
return Timestamp(num * 1000)
}
if let num = json["lastUsed"].string {
// Try parsing.
return decimalSecondsStringToTimestamp(num)
}
return nil
}
if let title = json["title"].string,
let urlHistory = jsonsToStrings(json["urlHistory"].array),
let lastUsed = getLastUsed(json) {
return Tab(title: title, urlHistory: urlHistory, lastUsed: lastUsed, icon: json["icon"].string)
}
return nil
}
}
override open func isValid() -> Bool {
if !super.isValid() {
return false
}
if self["deleted"].bool ?? false {
return true
}
return self["clientName"].type == Type.string &&
self["tabs"].type == Type.array
}
// Eventually it'd be nice to unify RemoteTab and Tab. We want to kill the GUID in RemoteTab,
// at which point the only distinction between the two is that RemoteTab is "simple" and
// lives in Storage, and Tab is more closely tied to TabsPayload.
var remoteTabs: [RemoteTab] {
if let clientGUID = self["id"].string {
let payloadTabs = self["tabs"].array!
let remoteTabs = optFilter(payloadTabs.map({ Tab.remoteTabFromJSON($0, clientGUID: clientGUID) }))
if payloadTabs.count != remoteTabs.count {
log.debug("Bug 1201875 - Missing remote tabs from sync")
}
return remoteTabs
}
log.debug("no client ID for remote tabs")
return []
}
var tabs: [Tab] {
return optFilter(self["tabs"].array!.map(Tab.fromJSON))
}
var clientName: String {
return self["clientName"].string!
}
override open func equalPayloads(_ obj: CleartextPayloadJSON) -> Bool {
if !(obj is TabsPayload) {
return false;
}
if !super.equalPayloads(obj) {
return false;
}
let p = obj as! TabsPayload
if p.clientName != self.clientName {
return false
}
// TODO: compare tabs.
/*
if p.tabs != self.tabs {
return false;
}
*/
return true
}
}