Allow choosing of synced libraries in sync preferences (#1033)

Affects Sync button and auto-sync. Manual library sync will be possible later via library context menu.
This commit is contained in:
Adomas Ven 2016-06-27 19:47:11 +03:00 committed by Dan Stillman
parent 11e7cef057
commit b0f3a234d0
7 changed files with 255 additions and 40 deletions

View File

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 2007 Center for History and New Media
George Mason University, Fairfax, Virginia, USA
http://zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://zotero/skin/preferences.css"?>
<!DOCTYPE window [
<!ENTITY % prefWindow SYSTEM "chrome://zotero/locale/preferences.dtd">
%prefWindow;
<!ENTITY % common SYSTEM "chrome://zotero/locale/zotero.dtd">
%common;
]>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="" buttons="accept"
id="zotero-librariesToSync"
onload="Zotero_Preferences.Sync.initLibrariesToSync(); sizeToContent()" >
<script src="chrome://zotero/content/include.js"/>
<script src="preferences.js"/>
<script src="preferences_sync.js"/>
<groupbox>
<caption label="&zotero.preferences.sync.librariesToSync;"/>
<tree id="libraries-to-sync-tree" flex="1" width="415" hidecolumnpicker="true" rows="10" seltype="single" editable="true"
ondblclick="Zotero_Preferences.Sync.dblClickLibraryToSync(event);"
onclick="Zotero_Preferences.Sync.clickLibraryToSync(event)"
onkeyup="if (event.keyCode == event.DOM_VK_SPACE) { Zotero_Preferences.Sync.toggleLibraryToSync(this.currentIndex); }">
<treecols>
<treecol editable="true" type="checkbox" id="libraries-to-sync-checked" label="&zotero.preferences.sync.librariesToSync.sync;"/>
<treecol editable="false" id="libraries-to-sync-name" flex="1" label="&zotero.preferences.sync.librariesToSync.library;"/>
</treecols>
<treechildren id="libraries-to-sync-rows"/>
</tree>
</groupbox>
<script>
<![CDATA[
var io = window.arguments[0];
]]>
</script>
</dialog>

View File

@ -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* () {

View File

@ -103,46 +103,45 @@
<groupbox>
<caption label="&zotero.preferences.sync.syncServer;"/>
<hbox>
<grid>
<columns>
<column/>
<column/>
</columns>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<label value="&zotero.preferences.sync.username;"/>
<rows>
<row>
<label value="&zotero.preferences.sync.username;"/>
<hbox>
<label id="sync-username" value="Username"/>
</row>
<row>
<box/>
<button label="&zotero.preferences.sync.unlinkAccount;"
oncommand="Zotero_Preferences.Sync.unlinkAccount()"/>
</row>
<!--
<row>
<box/>
<button label="Access Control" oncommand="Zotero.alert('Not implemented');"/>
</row>
-->
<row>
<box/>
<checkbox label="&zotero.preferences.sync.syncAutomatically;"
preference="pref-sync-autosync"/>
</row>
<row>
<box/>
<checkbox label="&zotero.preferences.sync.syncFullTextContent;"
preference="pref-sync-fulltext-enabled"
tooltiptext="&zotero.preferences.sync.syncFullTextContent.desc;"/>
</row>
</rows>
</grid>
<vbox>
<label class="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</vbox>
</hbox>
</hbox>
</row>
<row>
<box/>
<box>
<button id="sync-libraries-button" label="&zotero.preferences.sync.librariesToSync.button;"
oncommand="Zotero_Preferences.Sync.showLibrariesToSyncDialog()"/>
</box>
</row>
<row>
<box/>
<checkbox label="&zotero.preferences.sync.syncAutomatically;"
preference="pref-sync-autosync"/>
</row>
<row>
<box/>
<checkbox label="&zotero.preferences.sync.syncFullTextContent;"
preference="pref-sync-fulltext-enabled"
tooltiptext="&zotero.preferences.sync.syncFullTextContent.desc;"/>
</row>
<row>
<box/>
<label class="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</row>
</rows>
</grid>
</groupbox>
@ -267,7 +266,7 @@
</groupbox>
</vbox>
</tabpanel>
<tabpanel id="zotero-reset" orient="vertical">
<!-- This doesn't wrap without an explicit width, for some reason -->
<description width="45em">&zotero.preferences.sync.reset.warning1;<label style="margin-left: 0; margin-right: 0" class="zotero-text-link" href="http://zotero.org/support/kb/sync_reset_options">&zotero.preferences.sync.reset.warning2;</label>&zotero.preferences.sync.reset.warning3;</description>

View File

@ -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;

View File

@ -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");
}

View File

@ -76,6 +76,10 @@
<!ENTITY zotero.preferences.sync.fileSyncing.download.onDemand "as needed">
<!ENTITY zotero.preferences.sync.fileSyncing.tos1 "By using Zotero storage, you agree to become bound by its">
<!ENTITY zotero.preferences.sync.fileSyncing.tos2 "terms and conditions">
<!ENTITY zotero.preferences.sync.librariesToSync "Libraries to Sync">
<!ENTITY zotero.preferences.sync.librariesToSync.button "Choose Libraries...">
<!ENTITY zotero.preferences.sync.librariesToSync.sync "Sync">
<!ENTITY zotero.preferences.sync.librariesToSync.library "Library">
<!ENTITY zotero.preferences.sync.reset.warning1 "The following operations are for use only in rare, specific situations and should not be used for general troubleshooting. In many cases, resetting will cause additional problems. See ">
<!ENTITY zotero.preferences.sync.reset.warning2 "Sync Reset Options">
<!ENTITY zotero.preferences.sync.reset.warning3 " for more information.">

View File

@ -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