browser/metro/base/content/flyoutpanels/SyncFlyoutPanel.js

changeset 2
7e26c7da4463
equal deleted inserted replaced
-1:000000000000 0:46c38410cdf3
1 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
6
7 Components.utils.import("resource://gre/modules/Services.jsm");
8
9 let SyncFlyoutPanel = {
10 init: function() {
11 if (this._isInitialized) {
12 Cu.reportError("Attempted to initialize SyncFlyoutPanel more than once");
13 return;
14 }
15
16 this._isInitialized = true;
17 this._bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties");
18 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
19 let self = this;
20
21 this._elements = {};
22 [
23 ['outer', 'sync-flyoutpanel'],
24 ['preSetup', 'sync-presetup-container'],
25 ['easySetup', 'sync-setup-container'],
26 ['manualSetup', 'sync-manualsetup-container'],
27 ['setupSuccess', 'sync-setupsuccess-container'],
28 ['setupFailure', 'sync-setupfailure-container'],
29 ['connected', 'sync-connected-container'],
30 ['pairNewDevice', 'sync-pair-container'],
31 ['pairSuccess', 'sync-pair-success-container'],
32 ['setupCode1', 'sync-setup-code1'],
33 ['setupCode2', 'sync-setup-code2'],
34 ['setupCode3', 'sync-setup-code3'],
35 ['setupThrobber', 'sync-setup-throbber'],
36 ['account', 'sync-manualsetup-account'],
37 ['password', 'sync-manualsetup-password'],
38 ['syncKey', 'sync-manualsetup-syncKey'],
39 ['manualSetupConnect', 'sync-manualsetup-connect'],
40 ['manualSetupFailure', 'sync-manualsetup-failure'],
41 ['connectedAccount', 'sync-connected-account'],
42 ['deviceName', 'sync-connected-device'],
43 ['lastSync', 'sync-connected-lastSynced'],
44 ['connectedThrobber', 'sync-connected-throbber'],
45 ['disconnectLink', 'sync-disconnect-label'],
46 ['disconnectWarning', 'sync-disconnect-warning'],
47 ['pairCode1', 'sync-pair-entry1'],
48 ['pairCode2', 'sync-pair-entry2'],
49 ['pairCode3', 'sync-pair-entry3'],
50 ['pairButton', 'sync-pair-button'],
51 ['pairFailureMessage', 'sync-pair-failure'],
52 ].forEach(function (aContainer) {
53 let [name, id] = aContainer;
54 XPCOMUtils.defineLazyGetter(self._elements, name, function() {
55 return document.getElementById(id);
56 });
57 });
58
59 this._topmostElement = this._elements.outer;
60
61 let xps = Components.classes["@mozilla.org/weave/service;1"]
62 .getService(Components.interfaces.nsISupports)
63 .wrappedJSObject;
64
65 if (xps.ready) {
66 this._onServiceReady();
67 } else {
68 Services.obs.addObserver(this._onServiceReady.bind(this),
69 "weave:service:ready",
70 false);
71 xps.ensureLoaded();
72 }
73 },
74
75 _hide: function() {
76 this._elements.outer.hide();
77 this.showInitialScreen();
78 },
79
80 _hideVisibleContainer: function() {
81 if (this._currentlyVisibleContainer) {
82 this._currentlyVisibleContainer.collapsed = true;
83 delete this._currentlyVisibleContainer;
84 delete this._onBackButton;
85 }
86 },
87
88 _onServiceReady: function(aEvent) {
89 if (aEvent) {
90 Services.obs.removeObserver(this._onServiceReady, "weave:service:ready");
91 }
92
93 this.showInitialScreen();
94 Services.obs.addObserver(this._onSyncStart.bind(this), "weave:service:sync:start", false);
95 Services.obs.addObserver(this._onSyncEnd.bind(this), "weave:ui:sync:finish", false);
96 Services.obs.addObserver(this._onSyncEnd.bind(this), "weave:ui:sync:error", false);
97 Weave.Service.scheduler.scheduleNextSync(10*1000);
98 },
99
100 _onSyncStart: function() {
101 this._isSyncing = true;
102 this._updateConnectedPage();
103 },
104
105 _onSyncEnd: function() {
106 this._isSyncing = false;
107 this._updateConnectedPage();
108 },
109
110 showInitialScreen: function() {
111 if (Weave.Status.login == Weave.LOGIN_SUCCEEDED) {
112 this.showConnected();
113 } else {
114 this.showPreSetup();
115 }
116 },
117
118 abortEasySetup: function() {
119 if (this._setupJpake) {
120 this._setupJpake.abort();
121 }
122 this._cleanUpEasySetup();
123 },
124
125 _cleanUpEasySetup: function() {
126 this._elements.setupCode1.value = "";
127 this._elements.setupCode2.value = "";
128 this._elements.setupCode3.value = "";
129 delete this._setupJpake;
130 this._elements.setupThrobber.collapsed = true;
131 this._elements.setupThrobber.enabled = false;
132 },
133
134 _updateConnectedPage: function() {
135 // Show the day-of-week and time (HH:MM) of last sync
136 let lastSync = Weave.Svc.Prefs.get("lastSync");
137 let syncDate = '';
138 if (lastSync != null) {
139 syncDate = new Date(lastSync).toLocaleFormat("%A %I:%M %p");
140 }
141
142 let device = Weave.Service.clientsEngine.localName;
143 let account = Weave.Service.identity.account;
144 this._elements.deviceName.textContent =
145 this._bundle.formatStringFromName("sync.flyout.connected.device",
146 [device], 1);
147 this._elements.connectedAccount.textContent =
148 this._bundle.formatStringFromName("sync.flyout.connected.account",
149 [account], 1);
150 this._elements.lastSync.textContent =
151 this._bundle.formatStringFromName("sync.flyout.connected.lastSynced",
152 [syncDate], 1);
153
154 if (this._currentlyVisibleContainer == this._elements.connected
155 && this._isSyncing) {
156 this._elements.connectedThrobber.collapsed = false;
157 this._elements.connectedThrobber.enabled = true;
158 } else {
159 this._elements.connectedThrobber.collapsed = true;
160 this._elements.connectedThrobber.enabled = false;
161 }
162 },
163
164 showConnected: function() {
165 // Reset state of the connected screen
166 this._elements.disconnectWarning.collapsed = true;
167 this._elements.disconnectLink.collapsed = false;
168
169 this._updateConnectedPage();
170 this._showContainer(this._elements.connected);
171 },
172
173 startEasySetup: function() {
174 let self = this;
175
176 this._showContainer(this._elements.easySetup);
177
178 // Set up our back button to do the appropriate action
179 this._onBackButton = function() {
180 self.abortEasySetup();
181 self.showInitialScreen();
182 };
183
184 this._setupJpake = new Weave.JPAKEClient({
185 displayPIN: function displayPIN(aPin) {
186 self._elements.setupCode1.value = aPin.slice(0, 4);
187 self._elements.setupCode2.value = aPin.slice(4, 8);
188 self._elements.setupCode3.value = aPin.slice(8);
189 },
190
191 onPairingStart: function onPairingStart() {
192 self._elements.setupThrobber.collapsed = false;
193 self._elements.setupThrobber.enabled = true;
194 },
195
196 onComplete: function onComplete(aCredentials) {
197 Weave.Service.identity.account = aCredentials.account;
198 Weave.Service.identity.basicPassword = aCredentials.password;
199 Weave.Service.identity.syncKey = aCredentials.synckey;
200 Weave.Service.serverURL = aCredentials.serverURL;
201 Weave.Service.persistLogin();
202 Weave.Service.scheduler.scheduleNextSync(0);
203
204 if (self._currentlyVisibleContainer == self._elements.easySetup) {
205 self.showSetupSuccess();
206 }
207 self._cleanUpEasySetup();
208 },
209
210 onAbort: function onAbort(aError) {
211 if (aError == "jpake.error.userabort") {
212 Services.obs.notifyObservers(null, "browser:sync:setup:userabort", "");
213 self._cleanUpEasySetup();
214 return;
215 } else if (aError == "jpake.error.network") {
216 Services.obs.notifyObservers(null, "browser:sync:setup:networkerror", "");
217 }
218
219 if (self._currentlyVisibleContainer == self._elements.easySetup) {
220 self.showSetupFailure();
221 self._cleanUpEasySetup();
222 }
223 }
224 });
225
226 this._setupJpake.receiveNoPIN();
227 },
228
229 _showContainer: function(aContainer) {
230 this._hideVisibleContainer();
231 this._currentlyVisibleContainer = aContainer;
232 this._currentlyVisibleContainer.collapsed = false;
233 },
234
235 showSetupSuccess: function() {
236 this._showContainer(this._elements.setupSuccess);
237 this._onBackButton = this.showInitialScreen;
238 },
239
240 showSetupFailure: function() {
241 this._showContainer(this._elements.setupFailure);
242 this._onBackButton = this.showInitialScreen;
243 },
244
245 showPreSetup: function() {
246 this._showContainer(this._elements.preSetup);
247 delete this._onBackButton;
248 },
249
250 showManualSetup: function() {
251 this._showContainer(this._elements.manualSetup);
252 this._onBackButton = this.showInitialScreen;
253
254 this._elements.account.value = Weave.Service.identity.account;
255 this._elements.password.value = Weave.Service.identity.basicPassword;
256 this._elements.syncKey.value =
257 Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey);
258 this.updateManualSetupConnectButtonState();
259 },
260
261 updateManualSetupConnectButtonState: function() {
262 this._elements.manualSetupConnect.disabled = !this._elements.account.value
263 || !this._elements.password.value
264 || !this._elements.syncKey.value;
265 },
266
267 manualSetupConnect: function() {
268 delete this._onBackButton;
269 this._elements.manualSetupConnect.disabled = true;
270 Weave.Service.identity.account = this._elements.account.value;
271 Weave.Service.identity.basicPassword = this._elements.password.value;
272 Weave.Service.identity.syncKey = Weave.Utils.normalizePassphrase(this._elements.syncKey.value);
273 if (Weave.Service.login()) {
274 Weave.Service.persistLogin();
275 if (this._currentlyVisibleContainer == this._elements.manualSetup) {
276 this.showSetupSuccess();
277 }
278 Weave.Service.scheduler.scheduleNextSync(0);
279 } else {
280 this._elements.manualSetupFailure.textContent = Weave.Utils.getErrorString(Weave.Status.login);
281 this._elements.manualSetupFailure.collapsed = false;
282 this.updateManualSetupConnectButtonState();
283 }
284 },
285
286 onDisconnectLink: function() {
287 this._elements.disconnectWarning.collapsed = false;
288 this._elements.disconnectLink.collapsed = true;
289 },
290
291 onDisconnectCancel: function() {
292 this._elements.disconnectWarning.collapsed = true;
293 this._elements.disconnectLink.collapsed = false;
294 },
295
296 onDisconnectButton: function() {
297 Weave.Service.startOver();
298 this.showInitialScreen();
299 },
300
301 onPairDeviceLink: function() {
302 // Reset state
303 this._elements.pairCode1.value = "";
304 this._elements.pairCode2.value = "";
305 this._elements.pairCode3.value = "";
306 this.updatePairButtonState();
307 this._elements.pairFailureMessage.collapsed = true;
308 this._elements.pairNewDevice.collapsed = false;
309
310 this._showContainer(this._elements.pairNewDevice);
311 this._onBackButton = this.showInitialScreen;
312 },
313
314 updatePairButtonState: function () {
315 this._elements.pairButton.disabled = !this._elements.pairCode1.value
316 || !this._elements.pairCode2.value
317 || !this._elements.pairCode3.value;
318 },
319
320 onCancelButton: function() {
321 this.showInitialContainer();
322 },
323
324 onTryAgainButton: function() {
325 this.startEasySetup();
326 },
327
328 onPairButton: function() {
329 this._elements.pairButton.disabled = true;
330 this._elements.pairFailureMessage.collapsed = true;
331 let self = this;
332 this._pairJpake = new Weave.JPAKEClient({
333 onPaired: function() {
334 self._pairJpake.sendAndComplete({
335 account: Weave.Service.identity.account,
336 password: Weave.Service.identity.basicPassword,
337 synckey: Weave.Service.identity.syncKey,
338 serverURL: Weave.Service.serverURL
339 });
340 },
341
342 onComplete: function() {
343 delete self._pairJpake;
344 Weave.Service.persistLogin();
345 if (self._currentlyVisibleContainer == self._elements.pairNewDevice) {
346 self._showContainer(self._elements.pairSuccess);
347 }
348 Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval);
349 },
350
351 onAbort: function(error) {
352 delete self._pairJpake;
353 if (error == Weave.JPAKE_ERROR_USERABORT) {
354 return;
355 }
356
357 self._elements.pairFailureMessage.collapsed = false;
358 self.updatePairButtonState();
359 }
360 });
361
362 this._pairJpake.pairWithPIN(this._elements.pairCode1.value
363 + this._elements.pairCode2.value
364 + this._elements.pairCode3.value,
365 false);
366 },
367 };

mercurial