diff --git a/chrome/content/zotero/xpcom/server.js b/chrome/content/zotero/xpcom/server.js index 6bc4321ba..8138fa025 100755 --- a/chrome/content/zotero/xpcom/server.js +++ b/chrome/content/zotero/xpcom/server.js @@ -28,6 +28,7 @@ Zotero.Server = new function() { this.responseCodes = { 200:"OK", 201:"Created", + 204:"No Content", 300:"Multiple Choices", 400:"Bad Request", 404:"Not Found", diff --git a/chrome/content/zotero/xpcom/server_connector.js b/chrome/content/zotero/xpcom/server_connector.js index efccc6124..c91c35158 100644 --- a/chrome/content/zotero/xpcom/server_connector.js +++ b/chrome/content/zotero/xpcom/server_connector.js @@ -799,6 +799,17 @@ Zotero.Server.Connector.UpdateSession.prototype = { } }; +Zotero.Server.Connector.DelaySync = function () {}; +Zotero.Server.Endpoints["/connector/delaySync"] = Zotero.Server.Connector.DelaySync; +Zotero.Server.Connector.DelaySync.prototype = { + supportedMethods: ["POST"], + + init: async function (options) { + Zotero.Sync.Runner.delaySync(10000); + return [204]; + } +}; + /** * Gets progress for an attachment that is currently being saved * diff --git a/chrome/content/zotero/xpcom/sync/syncRunner.js b/chrome/content/zotero/xpcom/sync/syncRunner.js index 00117cf38..1b4a5e48d 100644 --- a/chrome/content/zotero/xpcom/sync/syncRunner.js +++ b/chrome/content/zotero/xpcom/sync/syncRunner.js @@ -69,6 +69,7 @@ Zotero.Sync.Runner_Module = function (options = {}) { var _enabled = false; var _autoSyncTimer; + var _delaySyncUntil; var _firstInSession = true; var _syncInProgress = false; var _stopping = false; @@ -139,6 +140,14 @@ Zotero.Sync.Runner_Module = function (options = {}) { this.updateIcons('animate'); + // If a delay is set (e.g., from the connector target selector), wait to sync + while (_delaySyncUntil && new Date() < _delaySyncUntil) { + this.setSyncStatus(Zotero.getString('sync.status.waiting')); + let delay = _delaySyncUntil - new Date(); + Zotero.debug(`Waiting ${delay} ms to sync`); + yield Zotero.Promise.delay(delay); + } + // purgeDataObjects() starts a transaction, so if there's an active one then show a // nice message and wait until there's not. Another transaction could still start // before purgeDataObjects() and result in a wait timeout, but this should reduce the @@ -884,11 +893,20 @@ Zotero.Sync.Runner_Module = function (options = {}) { // Implements nsITimerCallback var callback = { - notify: function (timer) { + notify: async function (timer) { if (!_getAPIKey()) { return; } + // If a delay is set (e.g., from the connector target selector), wait to sync. + // We do this in sync() too for manual syncs, but no need to start spinning if + // it's just an auto-sync. + while (_delaySyncUntil && new Date() < _delaySyncUntil) { + let delay = _delaySyncUntil - new Date(); + Zotero.debug(`Waiting ${delay} ms to start auto-sync`); + await Zotero.Promise.delay(delay); + } + if (Zotero.locked) { Zotero.debug('Zotero is locked -- skipping auto-sync', 4); return; @@ -935,6 +953,11 @@ Zotero.Sync.Runner_Module = function (options = {}) { } + this.delaySync = function (ms) { + _delaySyncUntil = new Date(Date.now() + ms); + }; + + /** * Trigger updating of the main sync icon, the sync error icon, and * library-specific sync error icons across all windows