- Restart sync if items were changed during upload to avoid 404 file sync errors

- Show sync status in all windows
- Don't attempt to auto-sync on Zotero pane open if a sync is already in progress
- Fix some sync process callbacks
This commit is contained in:
Dan Stillman 2010-03-12 08:29:31 +00:00
parent 62a83e38ec
commit 2e76f0128d
2 changed files with 166 additions and 125 deletions

View file

@ -424,7 +424,9 @@ var ZoteroPane = new function()
var d2 = new Date();
Zotero.debug("Purged data tables in " + (d2 - d) + " ms");
if (Zotero.Prefs.get('sync.autoSync') && Zotero.Sync.Server.enabled) {
// Auto-sync on pane open
if (Zotero.Prefs.get('sync.autoSync') && Zotero.Sync.Server.enabled
&& !Zotero.Sync.Server.syncInProgress && !Zotero.Sync.Storage.syncInProgress) {
setTimeout(function () {
Zotero.Sync.Runner.sync(true);
}, 1000);

View file

@ -515,7 +515,7 @@ Zotero.Sync.Runner = new function () {
// TODO: show status in all windows
var msg = "A sync process is already running. To view progress, check "
+ "the window in which the sync began or restart Firefox.";
var e = new Zotero.Error(msg, 0, { dialogButtonText: null })
var e = new Zotero.Error(msg, 0, { dialogButtonText: null, frontWindowOnly: true })
this.setSyncIcon('error', e);
return false;
}
@ -527,6 +527,13 @@ Zotero.Sync.Runner = new function () {
_running = true;
this.setSyncIcon('animate');
var finalCallbacks = {
onSuccess: Zotero.Sync.Runner.stop,
onSkip: Zotero.Sync.Runner.stop,
onStop: Zotero.Sync.Runner.stop,
onError: Zotero.Sync.Runner.error
};
var storageSync = function () {
var syncNeeded = false;
@ -546,21 +553,13 @@ Zotero.Sync.Runner = new function () {
{
// ZFS success
onSuccess: function () {
Zotero.Sync.Server.sync(
Zotero.Sync.Runner.stop,
Zotero.Sync.Runner.stop,
Zotero.Sync.Runner.error
)
Zotero.Sync.Server.sync(finalCallbacks);
},
// ZFS skip
onSkip: function () {
if (syncNeeded) {
Zotero.Sync.Server.sync(
Zotero.Sync.Runner.stop,
Zotero.Sync.Runner.stop,
Zotero.Sync.Runner.error
)
Zotero.Sync.Server.sync(finalCallbacks);
}
},
@ -583,12 +582,7 @@ Zotero.Sync.Runner = new function () {
{
// ZFS success
onSuccess: function () {
Zotero.Sync.Server.sync({
onSuccess: Zotero.Sync.Runner.stop,
onSkip: Zotero.Sync.Runner.stop,
onStop: Zotero.Sync.Runner.stop,
onError: Zotero.Sync.Runner.error
})
Zotero.Sync.Server.sync(finalCallbacks);
},
// ZFS skip
@ -743,6 +737,11 @@ Zotero.Sync.Runner = new function () {
this.setSyncIcon = function (status, e) {
var message;
var buttonText;
var buttonCallback;
var frontWindowOnly = false;
status = status ? status : '';
switch (status) {
@ -752,23 +751,11 @@ Zotero.Sync.Runner = new function () {
case 'error':
break;
default:
throw ("Invalid sync icon status '" + status
+ "' in Zotero.Sync.Runner.setSyncIcon()");
default:
throw ("Invalid sync icon status '" + status
+ "' in Zotero.Sync.Runner.setSyncIcon()");
}
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var win = wm.getMostRecentWindow('navigator:browser');
var warning = win.document.getElementById('zotero-tb-sync-warning');
var icon = win.document.getElementById('zotero-tb-sync');
var message;
var buttonText;
var buttonCallback;
if (e) {
if (e.data) {
if (e.data.dialogText) {
@ -778,6 +765,9 @@ Zotero.Sync.Runner = new function () {
buttonText = e.data.dialogButtonText;
buttonCallback = e.data.dialogButtonCallback;
}
if (e.data.frontWindowOnly) {
frontWindowOnly = e.data.frontWindowOnly;
}
}
if (!message) {
if (e.message) {
@ -789,97 +779,136 @@ Zotero.Sync.Runner = new function () {
}
}
if (status == 'warning' || status == 'error') {
icon.setAttribute('status', '');
warning.hidden = false;
if (Zotero.Sync.Server.upgradeRequired) {
Zotero.Sync.Server.upgradeRequired = false;
warning.setAttribute('mode', 'upgrade');
buttonText = null;
}
else {
warning.setAttribute('mode', status);
}
warning.tooltipText = message;
warning.onclick = function () {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var win = wm.getMostRecentWindow("navigator:browser");
var pr = Components.classes["@mozilla.org/network/default-prompt;1"]
.createInstance(Components.interfaces.nsIPrompt);
// Warning
if (status == 'warning') {
var title = Zotero.getString('general.warning');
// If secondary button not specified, just use an alert
if (!buttonText) {
pr.alert(title, message);
return;
}
var buttonFlags = pr.BUTTON_POS_0 * pr.BUTTON_TITLE_OK
+ pr.BUTTON_POS_1 * pr.BUTTON_TITLE_IS_STRING;
Zotero.debug(buttonFlags);
var index = pr.confirmEx(
title,
message,
buttonFlags,
"",
buttonText,
"", null, {}
);
if (index == 1) {
setTimeout(buttonCallback, 1);
}
}
// Error
else if (status == 'error') {
var errorsLogged = Zotero.getErrors().length > 0;
// Probably not necessary, but let's be sure
if (!errorsLogged) {
Components.utils.reportError(message);
}
if (typeof buttonText == 'undefined') {
buttonText = Zotero.getString('errorReport.reportError');
buttonCallback = function () {
win.ZoteroPane.reportErrors();
}
}
// If secondary button is explicitly null, just use an alert
else if (buttonText === null) {
pr.alert(title, message);
return;
}
var buttonFlags = pr.BUTTON_POS_0 * pr.BUTTON_TITLE_OK
+ pr.BUTTON_POS_1 * pr.BUTTON_TITLE_IS_STRING;
var index = pr.confirmEx(
Zotero.getString('general.error'),
message,
buttonFlags,
"",
buttonText,
"", null, {}
);
if (index == 1) {
setTimeout(buttonCallback, 1);
}
}
}
}
else {
icon.setAttribute('status', status);
warning.hidden = true;
warning.onclick = null;
var upgradeRequired = false;
if (Zotero.Sync.Server.upgradeRequired) {
upgradeRequired = true;
Zotero.Sync.Server.upgradeRequired = false;
}
// Disable button while spinning
icon.disabled = status == 'animate';
if (status == 'error') {
var errorsLogged = Zotero.getErrors().length > 0;
}
if (frontWindowOnly) {
// Fake an nsISimpleEnumerator with just the topmost window
var enumerator = {
_returned: false,
hasMoreElements: function () {
return !this._returned;
},
getNext: function () {
if (this._returned) {
throw ("No more windows to return in Zotero.Sync.Runner.setSyncIcon()");
}
this._returned = true;
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
return wm.getMostRecentWindow("navigator:browser");
}
};
}
// Update all windows
else {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var enumerator = wm.getEnumerator('navigator:browser');
}
while (enumerator.hasMoreElements()) {
var win = enumerator.getNext();
var warning = win.document.getElementById('zotero-tb-sync-warning');
var icon = win.document.getElementById('zotero-tb-sync');
if (status == 'warning' || status == 'error') {
icon.setAttribute('status', '');
warning.hidden = false;
if (upgradeRequired) {
warning.setAttribute('mode', 'upgrade');
buttonText = null;
}
else {
warning.setAttribute('mode', status);
}
warning.tooltipText = message;
warning.onclick = function () {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var win = wm.getMostRecentWindow("navigator:browser");
var pr = Components.classes["@mozilla.org/network/default-prompt;1"]
.createInstance(Components.interfaces.nsIPrompt);
// Warning
if (status == 'warning') {
var title = Zotero.getString('general.warning');
// If secondary button not specified, just use an alert
if (!buttonText) {
pr.alert(title, message);
return;
}
var buttonFlags = pr.BUTTON_POS_0 * pr.BUTTON_TITLE_OK
+ pr.BUTTON_POS_1 * pr.BUTTON_TITLE_IS_STRING;
Zotero.debug(buttonFlags);
var index = pr.confirmEx(
title,
message,
buttonFlags,
"",
buttonText,
"", null, {}
);
if (index == 1) {
setTimeout(buttonCallback, 1);
}
}
// Error
else if (status == 'error') {
// Probably not necessary, but let's be sure
if (!errorsLogged) {
Components.utils.reportError(message);
}
if (typeof buttonText == 'undefined') {
buttonText = Zotero.getString('errorReport.reportError');
buttonCallback = function () {
win.ZoteroPane.reportErrors();
}
}
// If secondary button is explicitly null, just use an alert
else if (buttonText === null) {
pr.alert(title, message);
return;
}
var buttonFlags = pr.BUTTON_POS_0 * pr.BUTTON_TITLE_OK
+ pr.BUTTON_POS_1 * pr.BUTTON_TITLE_IS_STRING;
var index = pr.confirmEx(
Zotero.getString('general.error'),
message,
buttonFlags,
"",
buttonText,
"", null, {}
);
if (index == 1) {
setTimeout(buttonCallback, 1);
}
}
}
}
else {
icon.setAttribute('status', status);
warning.hidden = true;
warning.onclick = null;
}
// Disable button while spinning
icon.disabled = status == 'animate';
}
// Clear tooltip
_tooltip = null;
@ -1255,10 +1284,12 @@ Zotero.Sync.Server = new function () {
if (!restart) {
if (_syncInProgress) {
_error(Zotero.localeJoin([
var msg = Zotero.localeJoin([
Zotero.getString('sync.error.syncInProgress'),
Zotero.getString('sync.error.syncInProgress.wait')
]));
]);
var e = new Zotero.Error(msg, 0, { dialogButtonText: null, frontWindowOnly: true });
_error(e);
}
Zotero.debug("Beginning server sync");
@ -1268,7 +1299,6 @@ Zotero.Sync.Server = new function () {
// Get updated data
var url = _serverURL + 'updated';
var lastsync = Zotero.Sync.Server.lastRemoteSyncTime;
// TODO: use full sync instead? or make this full sync?
if (!lastsync) {
lastsync = 1;
}
@ -1478,6 +1508,15 @@ Zotero.Sync.Server = new function () {
//throw('break2');
Zotero.DB.commitTransaction();
// Check if any items were modified during /upload,
// and restart the sync if so
if (Zotero.Items.getNewer(nextLocalSyncDate)) {
Zotero.debug("Items were modified during upload -- restarting sync");
Zotero.Sync.Server.sync(_callbacks, true, true);
return;
}
_syncInProgress = false;
_callbacks.onSuccess();
}