diff --git a/chrome/content/zotero/preferences/librariesToSync.xul b/chrome/content/zotero/preferences/librariesToSync.xul
new file mode 100644
index 000000000..e11d842c2
--- /dev/null
+++ b/chrome/content/zotero/preferences/librariesToSync.xul
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+ %prefWindow;
+
+ %common;
+]>
+
+
\ No newline at end of file
diff --git a/chrome/content/zotero/preferences/preferences_sync.js b/chrome/content/zotero/preferences/preferences_sync.js
index a5d2ee621..7f83bd289 100644
--- a/chrome/content/zotero/preferences/preferences_sync.js
+++ b/chrome/content/zotero/preferences/preferences_sync.js
@@ -148,7 +148,6 @@ Zotero_Preferences.Sync = {
Zotero.Sync.Runner.deleteAPIKey();
return;
}
-
this.displayFields(json.username);
}),
@@ -195,8 +194,138 @@ Zotero_Preferences.Sync = {
}
this.displayFields();
+ Zotero.Prefs.clear('sync.librariesToSync');
yield Zotero.Sync.Runner.deleteAPIKey();
}),
+
+
+ showLibrariesToSyncDialog: function() {
+ var io = {};
+ window.openDialog('chrome://zotero/content/preferences/librariesToSync.xul',
+ "zotero-preferences-librariesToSyncDialog", "chrome,modal,centerscreen", io);
+ },
+
+
+ dblClickLibraryToSync: function (event) {
+ var tree = document.getElementById("libraries-to-sync-tree");
+ var row = {}, col = {}, child = {};
+ tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, child);
+
+ if (col.value.element.id == 'libraries-to-sync-checked') {
+ return;
+ }
+ // if dblclicked anywhere but the checkbox update pref
+ return this.toggleLibraryToSync(row.value);
+ },
+
+
+ clickLibraryToSync: function (event) {
+ var tree = document.getElementById("libraries-to-sync-tree");
+ var row = {}, col = {}, child = {};
+ tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, child);
+
+ if (col.value.element.id != 'libraries-to-sync-checked') {
+ return;
+ }
+ // if clicked on checkbox update pref
+ return this.toggleLibraryToSync(row.value);
+ },
+
+
+ toggleLibraryToSync: function (index) {
+ var treechildren = document.getElementById('libraries-to-sync-rows');
+ if (index >= treechildren.childNodes.length) {
+ return;
+ }
+ var row = treechildren.childNodes[index];
+ var val = row.firstChild.childNodes[1].getAttribute('value');
+ if (!val) {
+ return
+ }
+
+ var librariesToSkip = JSON.parse(Zotero.Prefs.get('sync.librariesToSkip') || '[]');
+ var indexOfId = librariesToSkip.indexOf(val);
+ if (indexOfId == -1) {
+ librariesToSkip.push(val);
+ } else {
+ librariesToSkip.splice(indexOfId, 1);
+ }
+ Zotero.Prefs.set('sync.librariesToSkip', JSON.stringify(librariesToSkip));
+
+ var cell = row.firstChild.firstChild;
+ cell.setAttribute('value', indexOfId != -1);
+ },
+
+
+ initLibrariesToSync: Zotero.Promise.coroutine(function* () {
+ var tree = document.getElementById("libraries-to-sync-tree");
+ var treechildren = document.getElementById('libraries-to-sync-rows');
+ while (treechildren.hasChildNodes()) {
+ treechildren.removeChild(treechildren.firstChild);
+ }
+
+ function addRow(libraryName, id, checked=false, editable=true) {
+ var treeitem = document.createElement('treeitem');
+ var treerow = document.createElement('treerow');
+ var checkboxCell = document.createElement('treecell');
+ var nameCell = document.createElement('treecell');
+
+ nameCell.setAttribute('label', libraryName);
+ nameCell.setAttribute('value', id);
+ nameCell.setAttribute('editable', false);
+ checkboxCell.setAttribute('value', checked);
+ checkboxCell.setAttribute('editable', editable);
+
+ treerow.appendChild(checkboxCell);
+ treerow.appendChild(nameCell);
+ treeitem.appendChild(treerow);
+ treechildren.appendChild(treeitem);
+ }
+
+ // Add loading row while we're loading a group list
+ var loadingLabel = Zotero.getString("zotero.preferences.sync.librariesToSync.loadingLibraries");
+ addRow(loadingLabel, "loading", false, false);
+
+ var apiKey = Zotero.Sync.Data.Local.getAPIKey();
+ var client = Zotero.Sync.Runner.getAPIClient({apiKey});
+ var groups = [];
+ try {
+ // Load up remote groups
+ var keyInfo = yield Zotero.Sync.Runner.checkAccess(client, {timeout: 5000});
+ groups = yield client.getGroups(keyInfo.userID);
+ }
+ catch (e) {
+ // Connection problems
+ if ((e instanceof Zotero.HTTP.UnexpectedStatusException)
+ || (e instanceof Zotero.HTTP.TimeoutException)
+ || (e instanceof Zotero.HTTP.BrowserOfflineException)) {
+ Zotero.alert(
+ window,
+ Zotero.getString('general.error'),
+ Zotero.getString('sync.error.checkConnection', Zotero.clientName)
+ );
+ }
+ else {
+ throw e;
+ }
+ document.getElementsByTagName('dialog')[0].acceptDialog();
+ }
+
+ // Remove the loading row
+ treechildren.removeChild(treechildren.firstChild);
+
+ var librariesToSkip = JSON.parse(Zotero.Prefs.get('sync.librariesToSkip') || '[]');
+ // Add default rows
+ addRow(Zotero.getString("pane.collections.libraryAndFeeds"), "L" + Zotero.Libraries.userLibraryID,
+ librariesToSkip.indexOf("L" + Zotero.Libraries.userLibraryID) == -1);
+ addRow(Zotero.getString("pane.collections.publications"), "L" + Zotero.Libraries.publicationsLibraryID,
+ librariesToSkip.indexOf("L" + Zotero.Libraries.publicationsLibraryID) == -1);
+
+ // Add group rows
+ for (let group of groups) {
+ addRow(group.data.name, "G" + group.id, librariesToSkip.indexOf("G" + group.id) == -1);
+ }
+ }),
updateStorageSettingsUI: Zotero.Promise.coroutine(function* () {
diff --git a/chrome/content/zotero/preferences/preferences_sync.xul b/chrome/content/zotero/preferences/preferences_sync.xul
index 266546723..0155d0560 100644
--- a/chrome/content/zotero/preferences/preferences_sync.xul
+++ b/chrome/content/zotero/preferences/preferences_sync.xul
@@ -103,46 +103,45 @@
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -267,7 +266,7 @@
-
+
&zotero.preferences.sync.reset.warning1;&zotero.preferences.sync.reset.warning3;
diff --git a/chrome/content/zotero/xpcom/sync/syncAPIClient.js b/chrome/content/zotero/xpcom/sync/syncAPIClient.js
index 40b7dab50..80457da0a 100644
--- a/chrome/content/zotero/xpcom/sync/syncAPIClient.js
+++ b/chrome/content/zotero/xpcom/sync/syncAPIClient.js
@@ -75,12 +75,26 @@ Zotero.Sync.APIClient.prototype = {
return this._parseJSON(xmlhttp.responseText);
}),
+ /**
+ * Get group metadata for userID
+ *
+ * @param {Integer} userID
+ * @return {Object} - Group metadata response
+ */
+ getGroups: Zotero.Promise.coroutine(function* (userID) {
+ if (!userID) throw new Error("User ID not provided");
+
+ var uri = this.baseURL + "users/" + userID + "/groups";
+ var xmlhttp = yield this.makeRequest("GET", uri);
+ return this._parseJSON(xmlhttp.responseText);
+ }),
+
/**
* @param {Integer} groupID
* @return {Object|false} - Group metadata response, or false if group not found
*/
- getGroupInfo: Zotero.Promise.coroutine(function* (groupID) {
+ getGroup: Zotero.Promise.coroutine(function* (groupID) {
if (!groupID) throw new Error("Group ID not provided");
var uri = this.baseURL + "groups/" + groupID;
diff --git a/chrome/content/zotero/xpcom/sync/syncRunner.js b/chrome/content/zotero/xpcom/sync/syncRunner.js
index f8bc98b2d..126e1c465 100644
--- a/chrome/content/zotero/xpcom/sync/syncRunner.js
+++ b/chrome/content/zotero/xpcom/sync/syncRunner.js
@@ -452,7 +452,7 @@ Zotero.Sync.Runner_Module = function (options = {}) {
// Update metadata and permissions on missing or outdated groups
for (let groupID of groupsToDownload) {
- let info = yield client.getGroupInfo(groupID);
+ let info = yield client.getGroup(groupID);
if (!info) {
throw new Error("Group " + groupID + " not found");
}
diff --git a/chrome/locale/en-US/zotero/preferences.dtd b/chrome/locale/en-US/zotero/preferences.dtd
index f23c5bafc..1e5e2bed6 100644
--- a/chrome/locale/en-US/zotero/preferences.dtd
+++ b/chrome/locale/en-US/zotero/preferences.dtd
@@ -76,6 +76,10 @@
+
+
+
+
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
index 363bb2f05..a9fcacf58 100644
--- a/chrome/locale/en-US/zotero/zotero.properties
+++ b/chrome/locale/en-US/zotero/zotero.properties
@@ -180,6 +180,7 @@ pane.collections.rename = Rename collection:
pane.collections.library = My Library
pane.collections.publications = My Publications
pane.collections.feeds = Feeds
+pane.collections.libraryAndFeeds = My Library & Feeds
pane.collections.groupLibraries = Group Libraries
pane.collections.feedLibraries = Feeds
pane.collections.trash = Trash
@@ -568,6 +569,7 @@ zotero.preferences.sync.purgeStorage.title = Purge Attachment Files on Zotero
zotero.preferences.sync.purgeStorage.desc = If you plan to use WebDAV for file syncing and you previously synced attachment files in My Library to the Zotero servers, you can purge those files from the Zotero servers to give you more storage space for groups.\n\nYou can purge files at any time from your account settings on zotero.org.
zotero.preferences.sync.purgeStorage.confirmButton = Purge Files Now
zotero.preferences.sync.purgeStorage.cancelButton = Do Not Purge
+zotero.preferences.sync.librariesToSync.loadingLibraries = Loading libraries…
zotero.preferences.sync.reset.userInfoMissing = You must enter a username and password in the %S tab before using the reset options.
zotero.preferences.sync.reset.restoreFromServer = All data in this copy of Zotero will be erased and replaced with data belonging to user '%S' on the Zotero server.
zotero.preferences.sync.reset.replaceLocalData = Replace Local Data