From e84bbc704ad50b3f1db2082fc42b153dad017adb Mon Sep 17 00:00:00 2001 From: Kit Cambridge Date: Fri, 22 Apr 2016 07:19:16 -0700 Subject: [PATCH] Bug 1239042 - Show sync status for a minimum of 1.6s. r=markh MozReview-Commit-ID: FKpSe9r6Td9 --HG-- extra : rebase_source : 8808c86764e75f047a22901a37ecf4c5a1ddf3bf --- browser/base/content/browser-syncui.js | 72 +++++++++++++++++--------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/browser/base/content/browser-syncui.js b/browser/base/content/browser-syncui.js index 6a2d65cfba50..bcf4031881a4 100644 --- a/browser/base/content/browser-syncui.js +++ b/browser/base/content/browser-syncui.js @@ -12,6 +12,8 @@ if (AppConstants.MOZ_SERVICES_CLOUDSYNC) { XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", "resource://gre/modules/FxAccounts.jsm"); +const MIN_STATUS_ANIMATION_DURATION = 1600; + // gSyncUI handles updating the tools menu and displaying notifications. var gSyncUI = { _obs: ["weave:service:sync:start", @@ -32,8 +34,10 @@ var gSyncUI = { ], _unloaded: false, - // The number of "active" syncs - while this is non-zero, our button will spin - _numActiveSyncTasks: 0, + // 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"); @@ -52,6 +56,7 @@ var gSyncUI = { 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. @@ -59,6 +64,7 @@ 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) { @@ -154,6 +160,9 @@ var gSyncUI = { // 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 @@ -181,36 +190,44 @@ var gSyncUI = { if (!gBrowser) return; - this.log.debug("onActivityStart with numActive", this._numActiveSyncTasks); - if (++this._numActiveSyncTasks == 1) { - let broadcaster = document.getElementById("sync-status"); - broadcaster.setAttribute("syncstatus", "active"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label")); - broadcaster.setAttribute("disabled", "true"); - } + this.log.debug("onActivityStart"); + + clearTimeout(this._syncAnimationTimer); + this._syncStartTime = Date.now(); + + let broadcaster = document.getElementById("sync-status"); + broadcaster.setAttribute("syncstatus", "active"); + broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label")); + broadcaster.setAttribute("disabled", "true"); + + this.updateUI(); + }, + + _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(); }, onActivityStop() { if (!gBrowser) return; - this.log.debug("onActivityStop with numActive", this._numActiveSyncTasks); - if (--this._numActiveSyncTasks) { - if (this._numActiveSyncTasks < 0) { - // This isn't particularly useful (it seems more likely we'll set a - // "start" without a "stop" meaning it forever remains > 0) but it - // might offer some value... - this.log.error("mismatched onActivityStart/Stop calls", - new Error("active=" + this._numActiveSyncTasks)); - } - return; // active tasks are still ongoing... - } + this.log.debug("onActivityStop"); - let broadcaster = document.getElementById("sync-status"); - broadcaster.removeAttribute("syncstatus"); - broadcaster.removeAttribute("disabled"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label")); - this.updateUI(); + let now = Date.now(); + let syncDuration = now - this._syncStartTime; + + if (syncDuration < MIN_STATUS_ANIMATION_DURATION) { + let animationTime = MIN_STATUS_ANIMATION_DURATION - syncDuration; + clearTimeout(this._syncAnimationTimer); + this._syncAnimationTimer = setTimeout(() => this._updateSyncStatus(), animationTime); + } else { + this._updateSyncStatus(); + } }, onLoginError: function SUI_onLoginError() { @@ -488,6 +505,11 @@ var gSyncUI = { } this.onClientsSynced(); break; + case "quit-application": + // Stop the animation timer on shutdown, since we can't update the UI + // after this. + clearTimeout(this._syncAnimationTimer); + break; } },