summaryrefslogtreecommitdiffstats
path: root/application/basilisk/base/content/browser-syncui.js
diff options
context:
space:
mode:
authorAscrod <32915892+Ascrod@users.noreply.github.com>2019-04-18 20:35:10 -0400
committerAscrod <32915892+Ascrod@users.noreply.github.com>2019-04-18 20:35:10 -0400
commitaf7e140d4ed8f5bc9a69da2f0338ad3cb1319dec (patch)
tree4aac6c4383fb9e279fccb13c65a4e44595fd4cf6 /application/basilisk/base/content/browser-syncui.js
parent40fc72376411587e7bf9985fb9545eca1c9aaa8e (diff)
parent51722cd4fecb5c8c79a302f2771cad71535df5ea (diff)
downloadUXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar
UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar.gz
UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar.lz
UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.tar.xz
UXP-af7e140d4ed8f5bc9a69da2f0338ad3cb1319dec.zip
Merge branch 'master' into default-pref
Diffstat (limited to 'application/basilisk/base/content/browser-syncui.js')
-rw-r--r--application/basilisk/base/content/browser-syncui.js586
1 files changed, 242 insertions, 344 deletions
diff --git a/application/basilisk/base/content/browser-syncui.js b/application/basilisk/base/content/browser-syncui.js
index 7a80be87e..d0f46247a 100644
--- a/application/basilisk/base/content/browser-syncui.js
+++ b/application/basilisk/base/content/browser-syncui.js
@@ -1,63 +1,37 @@
-/* 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/. */
+# 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/.
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-#ifdef MOZ_SERVICES_CLOUDSYNC
-XPCOMUtils.defineLazyModuleGetter(this, "CloudSync",
- "resource://gre/modules/CloudSync.jsm");
-#endif
-
-XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
- "resource://gre/modules/FxAccounts.jsm");
-
-const MIN_STATUS_ANIMATION_DURATION = 1600;
-
-// gSyncUI handles updating the tools menu and displaying notifications.
+// gSyncUI handles updating the tools menu
var gSyncUI = {
_obs: ["weave:service:sync:start",
- "weave:service:sync:finish",
- "weave:service:sync:error",
+ "weave:service:sync:delayed",
"weave:service:quota:remaining",
"weave:service:setup-complete",
"weave:service:login:start",
"weave:service:login:finish",
- "weave:service:login:error",
"weave:service:logout:finish",
"weave:service:start-over",
- "weave:service:start-over:finish",
"weave:ui:login:error",
"weave:ui:sync:error",
"weave:ui:sync:finish",
"weave:ui:clear-error",
- "weave:engine:sync:finish"
],
_unloaded: false,
- // The last sync start time. Used to calculate the leftover animation time
- // once syncing completes (bug 1239042).
- _syncStartTime: 0,
- _syncAnimationTimer: 0,
-
- init: function () {
- Cu.import("resource://services-common/stringbundle.js");
+ init: function SUI_init() {
// Proceed to set up the UI if Sync has already started up.
// Otherwise we'll do it when Sync is firing up.
- if (this.weaveService.ready) {
+ let xps = Components.classes["@mozilla.org/weave/service;1"]
+ .getService(Components.interfaces.nsISupports)
+ .wrappedJSObject;
+ if (xps.ready) {
this.initUI();
return;
}
- // Sync isn't ready yet, but we can still update the UI with an initial
- // state - we haven't called initUI() yet, but that's OK - that's more
- // about observers for state changes, and will be called once Sync is
- // ready to start sending notifications.
- this.updateUI();
-
Services.obs.addObserver(this, "weave:service:ready", true);
- Services.obs.addObserver(this, "quit-application", true);
// Remove the observer if the window is closed before the observer
// was triggered.
@@ -65,7 +39,6 @@ var gSyncUI = {
gSyncUI._unloaded = true;
window.removeEventListener("unload", onUnload, false);
Services.obs.removeObserver(gSyncUI, "weave:service:ready");
- Services.obs.removeObserver(gSyncUI, "quit-application");
if (Weave.Status.ready) {
gSyncUI._obs.forEach(function(topic) {
@@ -85,158 +58,127 @@ var gSyncUI = {
Services.obs.addObserver(this, topic, true);
}, this);
- // initial label for the sync buttons.
- let broadcaster = document.getElementById("sync-status");
- broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
-
- this.maybeMoveSyncedTabsButton();
-
+ if (gBrowser && Weave.Notifications.notifications.length) {
+ this.initNotifications();
+ }
this.updateUI();
},
+ initNotifications: function SUI_initNotifications() {
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ let notificationbox = document.createElementNS(XULNS, "notificationbox");
+ notificationbox.id = "sync-notifications";
+ notificationbox.setAttribute("flex", "1");
- // Returns a promise that resolves with true if Sync needs to be configured,
- // false otherwise.
- _needsSetup() {
- // If Sync is configured for FxAccounts then we do that promise-dance.
- if (this.weaveService.fxAccountsEnabled) {
- return fxAccounts.getSignedInUser().then(user => {
- // We want to treat "account needs verification" as "needs setup".
- return !(user && user.verified);
- });
- }
- // We are using legacy sync - check that.
- let firstSync = Services.prefs.getCharPref("services.sync.firstSync", "");
+ let bottombox = document.getElementById("browser-bottombox");
+ bottombox.insertBefore(notificationbox, bottombox.firstChild);
- return Promise.resolve(Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
- firstSync == "notReady");
+ // Force a style flush to ensure that our binding is attached.
+ notificationbox.clientTop;
+
+ // notificationbox will listen to observers from now on.
+ Services.obs.removeObserver(this, "weave:notification:added");
},
- // Returns a promise that resolves with true if the user currently signed in
- // to Sync needs to be verified, false otherwise.
- _needsVerification() {
- // For callers who care about the distinction between "needs setup" and
- // "needs verification"
- if (this.weaveService.fxAccountsEnabled) {
- return fxAccounts.getSignedInUser().then(user => {
- // If there is no user, they can't be in a "needs verification" state.
- if (!user) {
- return false;
- }
- return !user.verified;
- });
- }
+ _wasDelayed: false,
- // Otherwise we are configured for legacy Sync, which has no verification
- // concept.
- return Promise.resolve(false);
+ _needsSetup: function SUI__needsSetup() {
+ let firstSync = Services.prefs.getCharPref("services.sync.firstSync", "");
+ return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
+ firstSync == "notReady";
},
- // Note that we don't show login errors in a notification bar here, but do
- // still need to track a login-failed state so the "Tools" menu updates
- // with the correct state.
- _loginFailed: function () {
- // If Sync isn't already ready, we don't want to force it to initialize
- // by referencing Weave.Status - and it isn't going to be accurate before
- // Sync is ready anyway.
- if (!this.weaveService.ready) {
- this.log.debug("_loginFailed has sync not ready, so returning false");
- return false;
- }
- this.log.debug("_loginFailed has sync state=${sync}",
- { sync: Weave.Status.login});
- return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
- },
+ updateUI: function SUI_updateUI() {
+ let needsSetup = this._needsSetup();
+ document.getElementById("sync-setup-state").hidden = !needsSetup;
+ document.getElementById("sync-syncnow-state").hidden = needsSetup;
- // Kick off an update of the UI - does *not* return a promise.
- updateUI() {
- this._promiseUpdateUI().catch(err => {
- this.log.error("updateUI failed", err);
- })
- },
+ if (!gBrowser)
+ return;
- // Updates the UI - returns a promise.
- _promiseUpdateUI() {
- return this._needsSetup().then(needsSetup => {
- if (!gBrowser)
- return Promise.resolve();
-
- let loginFailed = this._loginFailed();
-
- // Start off with a clean slate
- document.getElementById("sync-reauth-state").hidden = true;
- document.getElementById("sync-setup-state").hidden = true;
- document.getElementById("sync-syncnow-state").hidden = true;
-
-#ifdef MOZ_SERVICES_CLOUDSYNC
- if (CloudSync && CloudSync.ready && CloudSync().adapters.count) {
- document.getElementById("sync-syncnow-state").hidden = false;
- } else if (loginFailed) {
-#else
- if (loginFailed) {
-#endif
- // unhiding this element makes the menubar show the login failure state.
- document.getElementById("sync-reauth-state").hidden = false;
- } else if (needsSetup) {
- document.getElementById("sync-setup-state").hidden = false;
- } else {
- document.getElementById("sync-syncnow-state").hidden = false;
- }
+ let button = document.getElementById("sync-button");
+ if (!button)
+ return;
- return this._updateSyncButtonsTooltip();
- });
+ button.removeAttribute("status");
+ this._updateLastSyncTime();
+ if (needsSetup)
+ button.removeAttribute("tooltiptext");
},
+
// Functions called by observers
- onActivityStart() {
+ onActivityStart: function SUI_onActivityStart() {
if (!gBrowser)
return;
- this.log.debug("onActivityStart");
+ let button = document.getElementById("sync-button");
+ if (!button)
+ return;
- clearTimeout(this._syncAnimationTimer);
- this._syncStartTime = Date.now();
+ button.setAttribute("status", "active");
+ },
- let broadcaster = document.getElementById("sync-status");
- broadcaster.setAttribute("syncstatus", "active");
- broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label"));
- broadcaster.setAttribute("disabled", "true");
+ onSyncDelay: function SUI_onSyncDelay() {
+ // basically, we want to just inform users that stuff is going to take a while
+ let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
+ let description = this._stringBundle.GetStringFromName("error.sync.no_node_found");
+ let buttons = [new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
+ function() { gSyncUI.openServerStatus(); return true; }
+ )];
+ let notification = new Weave.Notification(
+ title, description, null, Weave.Notifications.PRIORITY_INFO, buttons);
+ Weave.Notifications.replaceTitle(notification);
+ this._wasDelayed = true;
+ },
- this.updateUI();
+ onLoginFinish: function SUI_onLoginFinish() {
+ // Clear out any login failure notifications
+ let title = this._stringBundle.GetStringFromName("error.login.title");
+ this.clearError(title);
},
- _updateSyncStatus() {
- if (!gBrowser)
- return;
- let broadcaster = document.getElementById("sync-status");
- broadcaster.removeAttribute("syncstatus");
- broadcaster.removeAttribute("disabled");
- broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
- this.updateUI();
+ onSetupComplete: function SUI_onSetupComplete() {
+ this.onLoginFinish();
},
- onActivityStop() {
- if (!gBrowser)
+ onLoginError: function SUI_onLoginError() {
+ // if login fails, any other notifications are essentially moot
+ Weave.Notifications.removeAll();
+
+ // if we haven't set up the client, don't show errors
+ if (this._needsSetup()) {
+ this.updateUI();
return;
- this.log.debug("onActivityStop");
+ }
- let now = Date.now();
- let syncDuration = now - this._syncStartTime;
+ let title = this._stringBundle.GetStringFromName("error.login.title");
- if (syncDuration < MIN_STATUS_ANIMATION_DURATION) {
- let animationTime = MIN_STATUS_ANIMATION_DURATION - syncDuration;
- clearTimeout(this._syncAnimationTimer);
- this._syncAnimationTimer = setTimeout(() => this._updateSyncStatus(), animationTime);
+ let description;
+ if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
+ // Convert to days
+ let lastSync =
+ Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
+ description =
+ this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
} else {
- this._updateSyncStatus();
+ let reason = Weave.Utils.getErrorString(Weave.Status.login);
+ description =
+ this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
}
- },
- onLoginError: function SUI_onLoginError() {
- this.log.debug("onLoginError: login=${login}, sync=${sync}", Weave.Status);
+ let buttons = [];
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.login.prefs.label"),
+ this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
+ function() { gSyncUI.openPrefs(); return true; }
+ ));
- // We don't show any login errors here; browser-fxaccounts shows them in
- // the hamburger menu.
+ let notification = new Weave.Notification(title, description, null,
+ Weave.Notifications.PRIORITY_WARNING, buttons);
+ Weave.Notifications.replaceTitle(notification);
this.updateUI();
},
@@ -244,6 +186,10 @@ var gSyncUI = {
this.updateUI();
},
+ onStartOver: function SUI_onStartOver() {
+ this.clearError();
+ },
+
onQuotaNotice: function onQuotaNotice(subject, data) {
let title = this._stringBundle.GetStringFromName("warning.sync.quota.label");
let description = this._stringBundle.GetStringFromName("warning.sync.quota.description");
@@ -259,40 +205,26 @@ var gSyncUI = {
Weave.Notifications.replaceTitle(notification);
},
- _getAppName: function () {
- let brand = new StringBundle("chrome://branding/locale/brand.properties");
- return brand.get("brandShortName");
+ openServerStatus: function () {
+ let statusURL = Services.prefs.getCharPref("services.sync.statusURL");
+ window.openUILinkIn(statusURL, "tab");
},
// Commands
- // doSync forces a sync - it *does not* return a promise as it is called
- // via the various UI components.
- doSync() {
- this._needsSetup().then(needsSetup => {
- if (!needsSetup) {
- setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0);
- }
- Services.obs.notifyObservers(null, "cloudsync:user-sync", null);
- }).catch(err => {
- this.log.error("Failed to force a sync", err);
- });
+ doSync: function SUI_doSync() {
+ setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0);
},
- // Handle clicking the toolbar button - which either opens the Sync setup
- // pages or forces a sync now. Does *not* return a promise as it is called
- // via the UI.
- handleToolbarButton() {
- this._needsSetup().then(needsSetup => {
- if (needsSetup || this._loginFailed()) {
- this.openSetup();
- } else {
- this.doSync();
- }
- }).catch(err => {
- this.log.error("Failed to handle toolbar button command", err);
- });
+ handleToolbarButton: function SUI_handleStatusbarButton() {
+ if (this._needsSetup())
+ this.openSetup();
+ else
+ this.doSync();
},
+ //XXXzpao should be part of syncCommon.js - which we might want to make a module...
+ // To be fixed in a followup (bug 583366)
+
/**
* Invoke the Sync setup wizard.
*
@@ -301,11 +233,9 @@ var gSyncUI = {
* null -- regular set up wizard
* "pair" -- pair a device first
* "reset" -- reset sync
- * @param entryPoint
- * Indicates the entrypoint from where this method was called.
*/
- openSetup: function SUI_openSetup(wizardType, entryPoint = "syncbutton") {
+ openSetup: function SUI_openSetup(wizardType) {
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
@@ -316,7 +246,6 @@ var gSyncUI = {
}
},
- // Open the legacy-sync device pairing UI. Note used for FxA Sync.
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked())
return;
@@ -329,199 +258,185 @@ var gSyncUI = {
"syncAddDevice", "centerscreen,chrome,resizable=no");
},
- openPrefs: function (entryPoint) {
- openPreferences("paneSync", { urlParams: { entrypoint: entryPoint } });
+ openQuotaDialog: function SUI_openQuotaDialog() {
+ let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
+ if (win)
+ win.focus();
+ else
+ Services.ww.activeWindow.openDialog(
+ "chrome://browser/content/sync/quota.xul", "",
+ "centerscreen,chrome,dialog,modal");
},
- openSignInAgainPage: function (entryPoint = "syncbutton") {
- gFxAccounts.openSignInAgainPage(entryPoint);
+ openPrefs: function SUI_openPrefs() {
+ openPreferences("paneSync");
},
- /* After Sync is initialized we perform a once-only check for the sync
- button being in "customize purgatory" and if so, move it to the panel.
- This is done primarily for profiles created before SyncedTabs landed,
- where the button defaulted to being in that purgatory.
- We use a preference to ensure we only do it once, so people can still
- customize it away and have it stick.
- */
- maybeMoveSyncedTabsButton() {
- const prefName = "browser.migrated-sync-button";
- let migrated = Services.prefs.getBoolPref(prefName, false);
- if (migrated) {
+ // Helpers
+ _updateLastSyncTime: function SUI__updateLastSyncTime() {
+ if (!gBrowser)
return;
- }
- if (!CustomizableUI.getPlacementOfWidget("sync-button")) {
- CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
- }
- Services.prefs.setBoolPref(prefName, true);
- },
- /* Update the tooltip for the sync-status broadcaster (which will update the
- Sync Toolbar button and the Sync spinner in the FxA hamburger area.)
- If Sync is configured, the tooltip is when the last sync occurred,
- otherwise the tooltip reflects the fact that Sync needs to be
- (re-)configured.
- */
- _updateSyncButtonsTooltip: Task.async(function* () {
- if (!gBrowser)
+ let syncButton = document.getElementById("sync-button");
+ if (!syncButton)
return;
- let email;
+ let lastSync;
try {
- email = Services.prefs.getCharPref("services.sync.username");
- } catch (ex) {}
-
- let needsSetup = yield this._needsSetup();
- let needsVerification = yield this._needsVerification();
- let loginFailed = this._loginFailed();
- // This is a little messy as the Sync buttons are 1/2 Sync related and
- // 1/2 FxA related - so for some strings we use Sync strings, but for
- // others we reach into gFxAccounts for strings.
- let tooltiptext;
- if (needsVerification) {
- // "needs verification"
- tooltiptext = gFxAccounts.strings.formatStringFromName("verifyDescription", [email], 1);
- } else if (needsSetup) {
- // "needs setup".
- tooltiptext = this._stringBundle.GetStringFromName("signInToSync.description");
- } else if (loginFailed) {
- // "need to reconnect/re-enter your password"
- tooltiptext = gFxAccounts.strings.formatStringFromName("reconnectDescription", [email], 1);
- } else {
- // Sync appears configured - format the "last synced at" time.
- try {
- let lastSync = new Date(Services.prefs.getCharPref("services.sync.lastSync"));
- tooltiptext = this.formatLastSyncDate(lastSync);
- }
- catch (e) {
- // pref doesn't exist (which will be the case until we've seen the
- // first successful sync) or is invalid (which should be impossible!)
- // Just leave tooltiptext as the empty string in these cases, which
- // will cause the tooltip to be removed below.
- }
+ lastSync = Services.prefs.getCharPref("services.sync.lastSync");
}
-
- // We've done all our promise-y work and ready to update the UI - make
- // sure it hasn't been torn down since we started.
- if (!gBrowser)
+ catch (e) { };
+ if (!lastSync || this._needsSetup()) {
+ syncButton.removeAttribute("tooltiptext");
return;
-
- let broadcaster = document.getElementById("sync-status");
- if (broadcaster) {
- if (tooltiptext) {
- broadcaster.setAttribute("tooltiptext", tooltiptext);
- } else {
- broadcaster.removeAttribute("tooltiptext");
- }
- }
- }),
-
- formatLastSyncDate: function(date) {
- let dateFormat;
- let sixDaysAgo = (() => {
- let date = new Date();
- date.setDate(date.getDate() - 6);
- date.setHours(0, 0, 0, 0);
- return date;
- })();
- // It may be confusing for the user to see "Last Sync: Monday" when the last sync was a indeed a Monday but 3 weeks ago
- if (date < sixDaysAgo) {
- dateFormat = {month: 'long', day: 'numeric'};
- } else {
- dateFormat = {weekday: 'long', hour: 'numeric', minute: 'numeric'};
}
- let lastSyncDateString = date.toLocaleDateString(undefined, dateFormat);
- return this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDateString], 1);
+
+ // Show the day-of-week and time (HH:MM) of last sync
+ let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
+ let lastSyncLabel =
+ this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
+
+ syncButton.setAttribute("tooltiptext", lastSyncLabel);
},
- onClientsSynced: function() {
- let broadcaster = document.getElementById("sync-syncnow-state");
- if (broadcaster) {
- if (Weave.Service.clientsEngine.stats.numClients > 1) {
- broadcaster.setAttribute("devices-status", "multi");
- } else {
- broadcaster.setAttribute("devices-status", "single");
- }
+ clearError: function SUI_clearError(errorString) {
+ Weave.Notifications.removeAll(errorString);
+ this.updateUI();
+ },
+
+ onSyncFinish: function SUI_onSyncFinish() {
+ let title = this._stringBundle.GetStringFromName("error.sync.title");
+
+ // Clear out sync failures on a successful sync
+ this.clearError(title);
+
+ if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
+ title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
+ this.clearError(title);
+ this._wasDelayed = false;
}
},
onSyncError: function SUI_onSyncError() {
- this.log.debug("onSyncError: login=${login}, sync=${sync}", Weave.Status);
let title = this._stringBundle.GetStringFromName("error.sync.title");
- let error = Weave.Utils.getErrorString(Weave.Status.sync);
- let description =
+
+ if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
+ this.onLoginError();
+ return;
+ }
+
+ let description;
+ if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
+ // Convert to days
+ let lastSync =
+ Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
+ description =
+ this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
+ } else {
+ let error = Weave.Utils.getErrorString(Weave.Status.sync);
+ description =
this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
+ }
let priority = Weave.Notifications.PRIORITY_WARNING;
let buttons = [];
- if (Weave.Status.sync == Weave.OVER_QUOTA) {
- description = this._stringBundle.GetStringFromName("error.sync.quota.description");
+ // Check if the client is outdated in some way
+ let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE;
+ for (let [engine, reason] in Iterator(Weave.Status.engines))
+ outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE;
+
+ if (outdated) {
+ description = this._stringBundle.GetStringFromName(
+ "error.sync.needUpdate.description");
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.needUpdate.label"),
+ this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
+ function() {
+ window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab");
+ return true;
+ }
+ ));
+ }
+ else if (Weave.Status.sync == Weave.OVER_QUOTA) {
+ description = this._stringBundle.GetStringFromName(
+ "error.sync.quota.description");
buttons.push(new Weave.NotificationButton(
- this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
- this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
+ this._stringBundle.GetStringFromName(
+ "error.sync.viewQuotaButton.label"),
+ this._stringBundle.GetStringFromName(
+ "error.sync.viewQuotaButton.accesskey"),
function() { gSyncUI.openQuotaDialog(); return true; } )
);
- // Only show the notification bar on Quota error. the panel will show the rest.
- let notification =
- new Weave.Notification(title, description, null, priority, buttons);
- Weave.Notifications.replaceTitle(notification);
+ }
+ else if (Weave.Status.enforceBackoff) {
+ priority = Weave.Notifications.PRIORITY_INFO;
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
+ function() { gSyncUI.openServerStatus(); return true; }
+ ));
+ }
+ else {
+ priority = Weave.Notifications.PRIORITY_INFO;
+ buttons.push(new Weave.NotificationButton(
+ this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
+ this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
+ function() { gSyncUI.doSync(); return true; }
+ ));
+ }
+
+ let notification =
+ new Weave.Notification(title, description, null, priority, buttons);
+ Weave.Notifications.replaceTitle(notification);
+
+ if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
+ title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
+ Weave.Notifications.removeAll(title);
+ this._wasDelayed = false;
}
this.updateUI();
},
-
observe: function SUI_observe(subject, topic, data) {
- this.log.debug("observed", topic);
if (this._unloaded) {
Cu.reportError("SyncUI observer called after unload: " + topic);
return;
}
- // Unwrap, just like Svc.Obs, but without pulling in that dependency.
- if (subject && typeof subject == "object" &&
- ("wrappedJSObject" in subject) &&
- ("observersModuleSubjectWrapper" in subject.wrappedJSObject)) {
- subject = subject.wrappedJSObject.object;
- }
-
- // First handle "activity" only.
switch (topic) {
case "weave:service:sync:start":
this.onActivityStart();
break;
- case "weave:service:sync:finish":
- case "weave:service:sync:error":
- this.onActivityStop();
- break;
- }
- // Now non-activity state (eg, enabled, errors, etc)
- // Note that sync uses the ":ui:" notifications for errors because sync.
- switch (topic) {
case "weave:ui:sync:finish":
- // Do nothing.
+ this.onSyncFinish();
break;
case "weave:ui:sync:error":
this.onSyncError();
break;
- case "weave:service:setup-complete":
- case "weave:service:login:finish":
- case "weave:service:login:start":
- case "weave:service:start-over":
- this.updateUI();
+ case "weave:service:sync:delayed":
+ this.onSyncDelay();
break;
case "weave:service:quota:remaining":
this.onQuotaNotice();
break;
+ case "weave:service:setup-complete":
+ this.onSetupComplete();
+ break;
+ case "weave:service:login:start":
+ this.onActivityStart();
+ break;
+ case "weave:service:login:finish":
+ this.onLoginFinish();
+ break;
case "weave:ui:login:error":
- case "weave:service:login:error":
this.onLoginError();
break;
case "weave:service:logout:finish":
this.onLogout();
break;
- case "weave:service:start-over:finish":
- this.updateUI();
+ case "weave:service:start-over":
+ this.onStartOver();
break;
case "weave:service:ready":
this.initUI();
@@ -529,16 +444,8 @@ var gSyncUI = {
case "weave:notification:added":
this.initNotifications();
break;
- case "weave:engine:sync:finish":
- if (data != "clients") {
- return;
- }
- this.onClientsSynced();
- break;
- case "quit-application":
- // Stop the animation timer on shutdown, since we can't update the UI
- // after this.
- clearTimeout(this._syncAnimationTimer);
+ case "weave:ui:clear-error":
+ this.clearError();
break;
}
},
@@ -550,19 +457,10 @@ var gSyncUI = {
};
XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
- // XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
+ //XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
// but for now just make it work
return Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle("chrome://weave/locale/services/sync.properties");
});
-XPCOMUtils.defineLazyGetter(gSyncUI, "log", function() {
- return Log.repository.getLogger("browserwindow.syncui");
-});
-
-XPCOMUtils.defineLazyGetter(gSyncUI, "weaveService", function() {
- return Components.classes["@mozilla.org/weave/service;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
-});