commit 2200badef240cebc25d031b4cada11b373e249ba
parent 63f206c80e05210ee748e42cf5bd85e8e718f84b
Author: Dan Stillman <dstillman@zotero.org>
Date: Sun, 18 Feb 2018 15:21:13 -0500
Nicer, localized messages for various field-too-long sync errors
Closes #351
Closes #1177
Diffstat:
2 files changed, 125 insertions(+), 80 deletions(-)
diff --git a/chrome/content/zotero/xpcom/sync/syncRunner.js b/chrome/content/zotero/xpcom/sync/syncRunner.js
@@ -1059,94 +1059,132 @@ Zotero.Sync.Runner_Module = function (options = {}) {
else if (e.name && e.name == 'ZoteroObjectUploadError') {
let { code, data, objectType, object } = e;
- // Tag too long
- if (code == 413 && objectType == 'item') {
- if (data && data.tag !== undefined) {
- // Show long tag fixer and handle result
- e.dialogButtonText = Zotero.getString('general.fix');
- e.dialogButtonCallback = Zotero.Promise.coroutine(function* () {
+ if (code == 413) {
+ // Collection name too long
+ if (objectType == 'collection' && data && data.value) {
+ e.message = Zotero.getString('sync.error.collectionTooLong', [data.value]);
+
+ e.dialogButtonText = Zotero.getString('pane.collections.showCollectionInLibrary');
+ e.dialogButtonCallback = () => {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var lastWin = wm.getMostRecentWindow("navigator:browser");
-
- // Open long tag fixer for every long tag in every editable library we're syncing
- var editableLibraries = options.libraries
- .filter(x => Zotero.Libraries.get(x).editable);
- for (let libraryID of editableLibraries) {
- let oldTagIDs = yield Zotero.Tags.getLongTagsInLibrary(libraryID);
- for (let oldTagID of oldTagIDs) {
- let oldTag = Zotero.Tags.getName(oldTagID);
- let dataOut = { result: null };
- lastWin.openDialog(
- 'chrome://zotero/content/longTagFixer.xul',
- '',
- 'chrome,modal,centerscreen',
- oldTag,
- dataOut
- );
- // If dialog was cancelled, stop
- if (!dataOut.result) {
- return;
- }
- switch (dataOut.result.op) {
- case 'split':
- for (let libraryID of editableLibraries) {
- let itemIDs = yield Zotero.Tags.getTagItems(libraryID, oldTagID);
- yield Zotero.DB.executeTransaction(function* () {
- for (let itemID of itemIDs) {
- let item = yield Zotero.Items.getAsync(itemID);
- for (let tag of dataOut.result.tags) {
- item.addTag(tag);
- }
- item.removeTag(oldTag);
- yield item.save();
- }
- yield Zotero.Tags.purge(oldTagID);
- });
- }
- break;
-
- case 'edit':
- for (let libraryID of editableLibraries) {
- let itemIDs = yield Zotero.Tags.getTagItems(libraryID, oldTagID);
- yield Zotero.DB.executeTransaction(function* () {
- for (let itemID of itemIDs) {
- let item = yield Zotero.Items.getAsync(itemID);
- item.replaceTag(oldTag, dataOut.result.tag);
- yield item.save();
- }
- });
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("navigator:browser");
+ win.ZoteroPane.collectionsView.selectCollection(object.id);
+ };
+ }
+ else if (objectType == 'item') {
+ // Tag too long
+ if (data && data.tag !== undefined) {
+ // Show long tag fixer and handle result
+ e.dialogButtonText = Zotero.getString('general.fix');
+ e.dialogButtonCallback = Zotero.Promise.coroutine(function* () {
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var lastWin = wm.getMostRecentWindow("navigator:browser");
+
+ // Open long tag fixer for every long tag in every editable library we're syncing
+ var editableLibraries = options.libraries
+ .filter(x => Zotero.Libraries.get(x).editable);
+ for (let libraryID of editableLibraries) {
+ let oldTagIDs = yield Zotero.Tags.getLongTagsInLibrary(libraryID);
+ for (let oldTagID of oldTagIDs) {
+ let oldTag = Zotero.Tags.getName(oldTagID);
+ let dataOut = { result: null };
+ lastWin.openDialog(
+ 'chrome://zotero/content/longTagFixer.xul',
+ '',
+ 'chrome,modal,centerscreen',
+ oldTag,
+ dataOut
+ );
+ // If dialog was cancelled, stop
+ if (!dataOut.result) {
+ return;
}
- break;
-
- case 'delete':
- for (let libraryID of editableLibraries) {
- yield Zotero.Tags.removeFromLibrary(libraryID, oldTagID);
+ switch (dataOut.result.op) {
+ case 'split':
+ for (let libraryID of editableLibraries) {
+ let itemIDs = yield Zotero.Tags.getTagItems(libraryID, oldTagID);
+ yield Zotero.DB.executeTransaction(function* () {
+ for (let itemID of itemIDs) {
+ let item = yield Zotero.Items.getAsync(itemID);
+ for (let tag of dataOut.result.tags) {
+ item.addTag(tag);
+ }
+ item.removeTag(oldTag);
+ yield item.save();
+ }
+ yield Zotero.Tags.purge(oldTagID);
+ });
+ }
+ break;
+
+ case 'edit':
+ for (let libraryID of editableLibraries) {
+ let itemIDs = yield Zotero.Tags.getTagItems(libraryID, oldTagID);
+ yield Zotero.DB.executeTransaction(function* () {
+ for (let itemID of itemIDs) {
+ let item = yield Zotero.Items.getAsync(itemID);
+ item.replaceTag(oldTag, dataOut.result.tag);
+ yield item.save();
+ }
+ });
+ }
+ break;
+
+ case 'delete':
+ for (let libraryID of editableLibraries) {
+ yield Zotero.Tags.removeFromLibrary(libraryID, oldTagID);
+ }
+ break;
}
- break;
}
}
+
+ options.restartSync = true;
+ });
+ }
+ else {
+ // Note too long
+ if (object.isNote() || object.isAttachment()) {
+ // Throw an error that adds a button for selecting the item to the sync error dialog
+ if (e.message.includes('<img src="data:image')) {
+ e.message = Zotero.getString('sync.error.noteEmbeddedImage');
+ }
+ else if (e.message.match(/^Note '.*' too long for item/)) {
+ e.message = Zotero.getString(
+ 'sync.error.noteTooLong',
+ Zotero.Utilities.ellipsize(object.getNoteTitle(), 40)
+ );
+ }
+ }
+ // Field or creator too long
+ else if (data && data.field) {
+ e.message = (data.field == 'creator'
+ ? Zotero.getString(
+ 'sync.error.creatorTooLong',
+ [data.value]
+ )
+ : Zotero.getString(
+ 'sync.error.fieldTooLong',
+ [data.field, data.value]
+ ))
+ + '\n\n'
+ + Zotero.getString(
+ 'sync.error.reportSiteIssuesToForums',
+ Zotero.clientName
+ );
}
- options.restartSync = true;
- });
- }
- // Note too long
- else if (object.isNote() || object.isAttachment()) {
- // Throw an error that adds a button for selecting the item to the sync error dialog
- if (e.message.includes('<img src="data:image')) {
- // TODO: Localize
- e.message = "Notes with embedded images cannot currently be synced to "
- + `${ZOTERO_CONFIG.DOMAIN_NAME}.`
+ // Include "Show Item in Library" button
+ e.dialogButtonText = Zotero.getString('pane.items.showItemInLibrary');
+ e.dialogButtonCallback = () => {
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("navigator:browser");
+ win.ZoteroPane.selectItem(object.id);
+ };
}
-
- e.dialogButtonText = Zotero.getString('pane.items.showItemInLibrary');
- e.dialogButtonCallback = () => {
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var win = wm.getMostRecentWindow("navigator:browser");
- win.ZoteroPane.selectItem(object.id);
- };
}
// If not a background sync, show dialog immediately
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
@@ -233,6 +233,7 @@ pane.collections.menu.export.feed = Export Feed…
pane.collections.menu.createBib.collection = Create Bibliography from Collection…
pane.collections.menu.createBib.savedSearch = Create Bibliography from Saved Search…
pane.collections.menu.createBib.feed = Create Bibliography from Feed…
+pane.collections.showCollectionInLibrary = Show Collection in Library
pane.collections.menu.generateReport.collection = Generate Report from Collection…
pane.collections.menu.generateReport.savedSearch = Generate Report from Saved Search…
@@ -908,6 +909,12 @@ sync.error.checkConnection = Error connecting to server. Check your Internet
sync.error.emptyResponseServer = Empty response from server.
sync.error.invalidCharsFilename = The filename '%S' contains invalid characters.\n\nRename the file and try again. If you rename the file via the OS, you will need to relink it in Zotero.
sync.error.apiKeyInvalid = %S could not authenticate your account. Please re-enter your account details.
+sync.error.collectionTooLong = The collection name “%S” is too long to sync. Shorten the name and sync again.
+sync.error.fieldTooLong = The %1$S value “%2$S” in one of your items is too long to sync. Shorten the field and sync again.
+sync.error.creatorTooLong = The creator name “%S” in one of your items is too long to sync. Shorten the field and sync again.
+sync.error.noteEmbeddedImage = Notes with embedded images cannot currently be synced. Syncing of embedded images may be supported in a future version.
+sync.error.noteTooLong = The note “%S” is too long to sync. Shorten the note and sync again.
+sync.error.reportSiteIssuesToForums = If you receive this message repeatedly for items saved from a particular site, you can report this issue in the %S Forums.
account.unlinkWarning = Unlinking your account will prevent %S from syncing your data.
account.unlinkWarning.removeData = Remove my %S data from this computer