commit
c0ab16e79d
7 changed files with 267 additions and 8 deletions
|
@ -252,6 +252,15 @@ Zotero.Prefs = new function(){
|
||||||
else {
|
else {
|
||||||
Zotero.Sync.EventListeners.AutoSyncListener.unregister();
|
Zotero.Sync.EventListeners.AutoSyncListener.unregister();
|
||||||
Zotero.Sync.EventListeners.IdleListener.unregister();
|
Zotero.Sync.EventListeners.IdleListener.unregister();
|
||||||
|
Zotero.Prefs.set('sync.reminder.autoSync.enabled', true);
|
||||||
|
// We don't want to immediately display reminder so bump this value
|
||||||
|
Zotero.Prefs.set('sync.reminder.autoSync.lastDisplayed', Math.round(Date.now() / 1000));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Zotero.getActiveZoteroPane().initSyncReminders(false);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
[ "search.quicksearch-mode", function(val) {
|
[ "search.quicksearch-mode", function(val) {
|
||||||
|
|
|
@ -229,6 +229,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
ZoteroPane.showRetractionBanner();
|
ZoteroPane.showRetractionBanner();
|
||||||
|
ZoteroPane.initSyncReminders(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TEMP: Clean up extra files from Mendeley imports <5.0.51
|
// TEMP: Clean up extra files from Mendeley imports <5.0.51
|
||||||
|
@ -355,6 +356,9 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
if(this.collectionsView) this.collectionsView.unregister();
|
if(this.collectionsView) this.collectionsView.unregister();
|
||||||
if(this.itemsView) this.itemsView.unregister();
|
if(this.itemsView) this.itemsView.unregister();
|
||||||
|
if (_syncRemindersObserverID) {
|
||||||
|
Zotero.Notifier.unregisterObserver(_syncRemindersObserverID);
|
||||||
|
}
|
||||||
|
|
||||||
this.uninitContainers();
|
this.uninitContainers();
|
||||||
|
|
||||||
|
@ -2249,6 +2253,205 @@ var ZoteroPane = new function()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.sync = function () {
|
||||||
|
let syncReminder = document.getElementById('sync-reminder-container');
|
||||||
|
if (!syncReminder.collapsed) {
|
||||||
|
syncReminder.collapsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.Sync.Server.canAutoResetClient = true;
|
||||||
|
Zotero.Sync.Server.manualSyncRequired = false;
|
||||||
|
Zotero.Sync.Runner.sync();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var _syncRemindersObserverID = null;
|
||||||
|
this.initSyncReminders = function (startup) {
|
||||||
|
if (startup) {
|
||||||
|
Zotero.Notifier.registerObserver(
|
||||||
|
{
|
||||||
|
notify: (event) => {
|
||||||
|
// When the API Key is deleted we need to add an observer
|
||||||
|
if (event === 'delete') {
|
||||||
|
Zotero.Prefs.set('sync.reminder.setUp.enabled', true);
|
||||||
|
Zotero.Prefs.set('sync.reminder.setUp.lastDisplayed', Math.round(Date.now() / 1000));
|
||||||
|
ZoteroPane.initSyncReminders(false);
|
||||||
|
}
|
||||||
|
// When API Key is added we can remove the observer
|
||||||
|
else if (event === 'add') {
|
||||||
|
ZoteroPane.initSyncReminders(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'api-key');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both reminders are disabled, we don't need an observer
|
||||||
|
if (!Zotero.Prefs.get('sync.reminder.setUp.enabled')
|
||||||
|
&& !Zotero.Prefs.get('sync.reminder.autoSync.enabled')) {
|
||||||
|
if (_syncRemindersObserverID) {
|
||||||
|
Zotero.Notifier.unregisterObserver(_syncRemindersObserverID);
|
||||||
|
_syncRemindersObserverID = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are syncing and auto-syncing then no need for observer
|
||||||
|
if (Zotero.Sync.Runner.enabled && Zotero.Prefs.get('sync.autoSync')) {
|
||||||
|
if (_syncRemindersObserverID) {
|
||||||
|
Zotero.Notifier.unregisterObserver(_syncRemindersObserverID);
|
||||||
|
_syncRemindersObserverID = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we already have an observer don't add another one
|
||||||
|
if (_syncRemindersObserverID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventTypes = ['add', 'modify', 'delete'];
|
||||||
|
_syncRemindersObserverID = Zotero.Notifier.registerObserver(
|
||||||
|
{
|
||||||
|
notify: (event) => {
|
||||||
|
if (!eventTypes.includes(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSetUpSyncReminder();
|
||||||
|
this.showAutoSyncReminder();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'item',
|
||||||
|
'syncReminder');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.showSetUpSyncReminder = function () {
|
||||||
|
const sevenDays = 60 * 60 * 24 * 7;
|
||||||
|
|
||||||
|
// Reasons not to show reminder:
|
||||||
|
// - User turned reminder off
|
||||||
|
// - Sync is enabled
|
||||||
|
if (!Zotero.Prefs.get('sync.reminder.setUp.enabled')
|
||||||
|
|| Zotero.Sync.Runner.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check lastDisplayed was 7+ days ago
|
||||||
|
let lastDisplayed = Zotero.Prefs.get('sync.reminder.setUp.lastDisplayed');
|
||||||
|
if (lastDisplayed > Math.round(Date.now() / 1000) - sevenDays) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showSyncReminder('setUp', { learnMoreURL: ZOTERO_CONFIG.SYNC_INFO_URL });
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.showAutoSyncReminder = function () {
|
||||||
|
const sevenDays = 60 * 60 * 24 * 7;
|
||||||
|
|
||||||
|
// Reasons not to show reminder:
|
||||||
|
// - User turned reminder off
|
||||||
|
// - Sync is not enabled
|
||||||
|
// - Auto-Sync is enabled
|
||||||
|
// - Last sync for all libraries was within 7 days
|
||||||
|
if (!Zotero.Prefs.get('sync.reminder.autoSync.enabled')
|
||||||
|
|| !Zotero.Sync.Runner.enabled
|
||||||
|
|| Zotero.Prefs.get('sync.autoSync')
|
||||||
|
|| Zotero.Libraries.getAll()
|
||||||
|
.every(library => !library.syncable
|
||||||
|
|| library.lastSync.getTime() > Date.now() - 1000 * sevenDays)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check lastDisplayed was 7+ days ago
|
||||||
|
let lastDisplayed = Zotero.Prefs.get('sync.reminder.autoSync.lastDisplayed');
|
||||||
|
if (lastDisplayed > Math.round(Date.now() / 1000) - sevenDays) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showSyncReminder('autoSync');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the UI and show the sync reminder panel for a given type of reminder
|
||||||
|
*
|
||||||
|
* @param {String} reminderType - Possible values: 'setUp' or 'autoSync'
|
||||||
|
* @param {Object} [options]
|
||||||
|
* @param {String} [options.learnMoreURL] - Show "Learn More" link to this URL
|
||||||
|
*/
|
||||||
|
this.showSyncReminder = function (reminderType, options = {}) {
|
||||||
|
if (!['setUp', 'autoSync'].includes(reminderType)) {
|
||||||
|
throw new Error(`Invalid reminder type: ${reminderType}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let panel = document.getElementById('sync-reminder-container');
|
||||||
|
const closePanel = function () {
|
||||||
|
panel.setAttribute('collapsed', true);
|
||||||
|
Zotero.Prefs.set(`sync.reminder.${reminderType}.lastDisplayed`, Math.round(Date.now() / 1000));
|
||||||
|
};
|
||||||
|
|
||||||
|
let message = document.getElementById('sync-reminder-message');
|
||||||
|
message.textContent = Zotero.getString(`sync.reminder.${reminderType}.message`, Zotero.appName);
|
||||||
|
|
||||||
|
let actionLink = document.getElementById('sync-reminder-action');
|
||||||
|
switch (reminderType) {
|
||||||
|
case 'autoSync':
|
||||||
|
var actionStr = Zotero.getString('general.enable');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
var actionStr = Zotero.getString(`sync.reminder.${reminderType}.action`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
actionLink.textContent = actionStr;
|
||||||
|
actionLink.onclick = function () {
|
||||||
|
closePanel();
|
||||||
|
|
||||||
|
switch (reminderType) {
|
||||||
|
case 'setUp':
|
||||||
|
Zotero.Utilities.Internal.openPreferences('zotero-prefpane-sync');
|
||||||
|
break;
|
||||||
|
case 'autoSync':
|
||||||
|
Zotero.Prefs.set(`sync.autoSync`, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let learnMoreLink = document.getElementById('sync-reminder-learn-more');
|
||||||
|
learnMoreLink.textContent = Zotero.getString('general.learnMore');
|
||||||
|
learnMoreLink.hidden = !options.learnMoreURL;
|
||||||
|
learnMoreLink.onclick = function () {
|
||||||
|
Zotero.launchURL(options.learnMoreURL);
|
||||||
|
};
|
||||||
|
|
||||||
|
let dontShowAgainLink = document.getElementById('sync-reminder-disable');
|
||||||
|
dontShowAgainLink.textContent = Zotero.getString('general.dontAskAgain');
|
||||||
|
dontShowAgainLink.onclick = function () {
|
||||||
|
closePanel();
|
||||||
|
Zotero.Prefs.set(`sync.reminder.${reminderType}.enabled`, false);
|
||||||
|
// Check if we no longer need to observe item modifications
|
||||||
|
ZoteroPane.initSyncReminders(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
let remindMeLink = document.getElementById('sync-reminder-remind');
|
||||||
|
remindMeLink.textContent = Zotero.getString('general.remindMeLater');
|
||||||
|
remindMeLink.onclick = function () {
|
||||||
|
closePanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
let closeButton = document.getElementById('sync-reminder-close');
|
||||||
|
closeButton.onclick = function () {
|
||||||
|
closePanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
panel.removeAttribute('collapsed');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
this.selectItem = async function (itemID, inLibraryRoot) {
|
this.selectItem = async function (itemID, inLibraryRoot) {
|
||||||
if (!itemID) {
|
if (!itemID) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -221,7 +221,7 @@
|
||||||
<panel id="zotero-sync-error-panel" type="arrow"/>
|
<panel id="zotero-sync-error-panel" type="arrow"/>
|
||||||
|
|
||||||
<toolbarbutton id="zotero-tb-sync" class="zotero-tb-button" tooltip="_child"
|
<toolbarbutton id="zotero-tb-sync" class="zotero-tb-button" tooltip="_child"
|
||||||
oncommand="Zotero.Sync.Server.canAutoResetClient = true; Zotero.Sync.Server.manualSyncRequired = false; Zotero.Sync.Runner.sync()">
|
oncommand="ZoteroPane.sync()">
|
||||||
<tooltip
|
<tooltip
|
||||||
id="zotero-tb-sync-tooltip"
|
id="zotero-tb-sync-tooltip"
|
||||||
onpopupshowing="Zotero.Sync.Runner.registerSyncStatus(this)"
|
onpopupshowing="Zotero.Sync.Runner.registerSyncStatus(this)"
|
||||||
|
@ -236,6 +236,18 @@
|
||||||
</hbox>
|
</hbox>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
|
|
||||||
|
<vbox id="sync-reminder-container" collapsed="true">
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" id="sync-reminder-banner">
|
||||||
|
<div id="sync-reminder-message"/>
|
||||||
|
<a id="sync-reminder-action" class="sync-reminder-link"/>
|
||||||
|
<a id="sync-reminder-learn-more" class="sync-reminder-link"/>
|
||||||
|
<div id="sync-reminder-spacer"/>
|
||||||
|
<a id="sync-reminder-disable" class="sync-reminder-link"/>
|
||||||
|
<a id="sync-reminder-remind" class="sync-reminder-link"/>
|
||||||
|
<div id="sync-reminder-close">×</div>
|
||||||
|
</div>
|
||||||
|
</vbox>
|
||||||
|
|
||||||
<vbox id="retracted-items-container" collapsed="true">
|
<vbox id="retracted-items-container" collapsed="true">
|
||||||
<div xmlns="http://www.w3.org/1999/xhtml" id="retracted-items-banner">
|
<div xmlns="http://www.w3.org/1999/xhtml" id="retracted-items-banner">
|
||||||
<div id="retracted-items-message"/>
|
<div id="retracted-items-message"/>
|
||||||
|
|
|
@ -49,6 +49,7 @@ general.import = Import
|
||||||
general.export = Export
|
general.export = Export
|
||||||
general.update = Update
|
general.update = Update
|
||||||
general.moreInformation = More Information
|
general.moreInformation = More Information
|
||||||
|
general.learnMore = Learn More
|
||||||
general.seeForMoreInformation = See %S for more information.
|
general.seeForMoreInformation = See %S for more information.
|
||||||
general.open = Open %S
|
general.open = Open %S
|
||||||
general.close = Close
|
general.close = Close
|
||||||
|
@ -65,6 +66,8 @@ general.openPreferences = Open Preferences
|
||||||
general.keys.ctrlShift = Ctrl+Shift+
|
general.keys.ctrlShift = Ctrl+Shift+
|
||||||
general.keys.cmdShift = Cmd+Shift+
|
general.keys.cmdShift = Cmd+Shift+
|
||||||
general.dontShowAgain = Don’t Show Again
|
general.dontShowAgain = Don’t Show Again
|
||||||
|
general.dontAskAgain = Don’t Ask Again
|
||||||
|
general.remindMeLater = Remind Me Later
|
||||||
general.fix = Fix…
|
general.fix = Fix…
|
||||||
general.tryAgain = Try Again
|
general.tryAgain = Try Again
|
||||||
general.tryLater = Try Later
|
general.tryLater = Try Later
|
||||||
|
@ -993,6 +996,10 @@ sync.resetGroupFilesAndSync = Reset Group Files and Sync
|
||||||
sync.skipGroup = Skip Group
|
sync.skipGroup = Skip Group
|
||||||
sync.removeGroupsAndSync = Remove Groups and Sync
|
sync.removeGroupsAndSync = Remove Groups and Sync
|
||||||
|
|
||||||
|
sync.reminder.setUp.message = Back up your library with %S syncing.
|
||||||
|
sync.reminder.setUp.action = Set Up Syncing
|
||||||
|
sync.reminder.autoSync.message = %S hasn’t synced in a while. Do you want to enable automatic syncing?
|
||||||
|
|
||||||
sync.error.usernameNotSet = Username not set
|
sync.error.usernameNotSet = Username not set
|
||||||
sync.error.usernameNotSet.text = You must enter your zotero.org username and password in the Zotero preferences to sync with the Zotero server.
|
sync.error.usernameNotSet.text = You must enter your zotero.org username and password in the Zotero preferences to sync with the Zotero server.
|
||||||
sync.error.passwordNotSet = Password not set
|
sync.error.passwordNotSet = Password not set
|
||||||
|
|
|
@ -533,11 +533,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sync error panel */
|
/* Sync error panel */
|
||||||
#zotero-sync-error-panel {
|
#zotero-sync-error-panel, #zotero-sync-reminder-panel {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-sync-error-panel .error-header {
|
#zotero-sync-error-panel .error-header, #zotero-sync-reminder-panel .header {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
@ -552,7 +552,7 @@
|
||||||
margin-bottom: 1.1em;
|
margin-bottom: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-sync-error-panel description {
|
#zotero-sync-error-panel description, #zotero-sync-reminder-panel description {
|
||||||
width: 370px;
|
width: 370px;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
@ -635,7 +635,7 @@
|
||||||
margin-left: 3px !important;
|
margin-left: 3px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#retracted-items-banner {
|
#retracted-items-banner, #sync-reminder-banner {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: #d93425;
|
background: #d93425;
|
||||||
|
@ -646,23 +646,46 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0 2em;
|
padding: 0 2em;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#retracted-items-message {
|
#sync-reminder-banner {
|
||||||
|
background: rgb(255, 234, 80);
|
||||||
|
border-bottom: #a9a9a9 .5px solid;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#retracted-items-message, #sync-reminder-message {
|
||||||
margin-right: .8em;
|
margin-right: .8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#sync-reminder-spacer {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
#retracted-items-link {
|
#retracted-items-link {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
margin-left: .3em;
|
margin-left: .3em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sync-reminder-link {
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
#retracted-items-link:active {
|
#retracted-items-link:active {
|
||||||
color: #f9e8e2;
|
color: #f9e8e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#retracted-items-close {
|
.sync-reminder-link:active {
|
||||||
|
color: #4b4b4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#retracted-items-close, #sync-reminder-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
top: -2px;
|
top: -2px;
|
||||||
|
|
|
@ -160,6 +160,10 @@ pref("extensions.zotero.sync.storage.groups.enabled", true);
|
||||||
pref("extensions.zotero.sync.storage.downloadMode.personal", "on-sync");
|
pref("extensions.zotero.sync.storage.downloadMode.personal", "on-sync");
|
||||||
pref("extensions.zotero.sync.storage.downloadMode.groups", "on-sync");
|
pref("extensions.zotero.sync.storage.downloadMode.groups", "on-sync");
|
||||||
pref("extensions.zotero.sync.fulltext.enabled", true);
|
pref("extensions.zotero.sync.fulltext.enabled", true);
|
||||||
|
pref("extensions.zotero.sync.reminder.setUp.enabled", true);
|
||||||
|
pref("extensions.zotero.sync.reminder.setUp.lastDisplayed", 0);
|
||||||
|
pref("extensions.zotero.sync.reminder.autoSync.enabled", true);
|
||||||
|
pref("extensions.zotero.sync.reminder.autoSync.lastDisplayed", 0);
|
||||||
|
|
||||||
// Proxy
|
// Proxy
|
||||||
pref("extensions.zotero.proxies.autoRecognize", true);
|
pref("extensions.zotero.proxies.autoRecognize", true);
|
||||||
|
|
|
@ -21,6 +21,7 @@ var ZOTERO_CONFIG = {
|
||||||
QUICK_START_URL: "https://www.zotero.org/support/quick_start_guide",
|
QUICK_START_URL: "https://www.zotero.org/support/quick_start_guide",
|
||||||
PDF_TOOLS_URL: "https://www.zotero.org/download/xpdf/",
|
PDF_TOOLS_URL: "https://www.zotero.org/download/xpdf/",
|
||||||
SUPPORT_URL: "https://www.zotero.org/support/",
|
SUPPORT_URL: "https://www.zotero.org/support/",
|
||||||
|
SYNC_INFO_URL: "https://www.zotero.org/support/sync",
|
||||||
TROUBLESHOOTING_URL: "https://www.zotero.org/support/getting_help",
|
TROUBLESHOOTING_URL: "https://www.zotero.org/support/getting_help",
|
||||||
FEEDBACK_URL: "https://forums.zotero.org/",
|
FEEDBACK_URL: "https://forums.zotero.org/",
|
||||||
CONNECTORS_URL: "https://www.zotero.org/download/connectors",
|
CONNECTORS_URL: "https://www.zotero.org/download/connectors",
|
||||||
|
|
Loading…
Reference in a new issue