Add syncing reminders (#2354)

There are two:
- Sync never set up (no username in DB) / set up, but unlinked
- Sync set up but auto-sync disabled and sync not completed in 30 days

Checks are trigged on item adds.
This commit is contained in:
Fletcher Hazlehurst 2020-12-18 10:11:01 -07:00 committed by Dan Stillman
parent 1cc03492c4
commit 1a3f6301b7
6 changed files with 225 additions and 8 deletions

View file

@ -252,6 +252,15 @@ Zotero.Prefs = new function(){
else {
Zotero.Sync.EventListeners.AutoSyncListener.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', String(Date.now()));
}
try {
Zotero.getActiveZoteroPane().setupSyncReminders(false);
}
catch (e) {
Zotero.logError(e);
}
}],
[ "search.quicksearch-mode", function(val) {

View file

@ -229,6 +229,7 @@ var ZoteroPane = new function()
setTimeout(function () {
ZoteroPane.showRetractionBanner();
ZoteroPane.setupSyncReminders(true);
});
// 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.itemsView) this.itemsView.unregister();
if (this._syncRemindersObserverID) {
Zotero.Notifier.unregisterObserver(this._syncRemindersObserverID);
}
this.uninitContainers();
@ -2249,6 +2253,173 @@ 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();
};
this._syncRemindersObserverID = null;
this.setupSyncReminders = 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', String(Date.now()));
ZoteroPane.setupSyncReminders(false);
}
// When API Key is added we can remove the observer
else if (event === 'add') {
ZoteroPane.setupSyncReminders(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 (this._syncRemindersObserverID) {
Zotero.Notifier.unregisterObserver(this._syncRemindersObserverID);
this._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 (this._syncRemindersObserverID) {
Zotero.Notifier.unregisterObserver(this._syncRemindersObserverID);
this._syncRemindersObserverID = null;
}
return;
}
// If we already have an observer don't add another one
if (this._syncRemindersObserverID) {
return;
}
const eventTypes = ['add', 'modify', 'delete'];
this._syncRemindersObserverID = Zotero.Notifier.registerObserver(
{ notify: (event) => {
if (!eventTypes.includes(event)) {
return;
}
setTimeout(() => {
this.showSetupSyncReminder();
this.showAutoSyncOffReminder();
}, 5000);
} },
'item',
'syncReminder');
};
this.showAutoSyncOffReminder = function () {
// Reasons not to show reminder:
// - User turned reminder off
// - Sync is not enabled
// - Auto-Sync is enabled
// - Last sync for all libraries was within 30 days
if (!Zotero.Prefs.get('sync.reminder.autoSync.enabled')
|| !Zotero.Sync.Runner.enabled
|| Zotero.Prefs.get('sync.autoSync')
|| !Zotero.Libraries.getAll()
.find(library => library.lastSync.getTime() < (Date.now() - 2592000000))) {
return;
}
// Check lastDisplayed was 30+ days ago
let lastDisplayed = parseInt(Zotero.Prefs.get(`sync.reminder.autoSync.lastDisplayed`));
if (lastDisplayed > (Date.now() - 2592000000)) {
return;
}
this.showSyncReminder('autoSync', false);
};
this.showSetupSyncReminder = function () {
// 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 = parseInt(Zotero.Prefs.get(`sync.reminder.setup.lastDisplayed`));
if (lastDisplayed > (Date.now() - 604800000)) {
return;
}
// When we have not seen the first warning, hide the checkbox
this.showSyncReminder('setup', lastDisplayed === 0);
};
/**
* Configure the UI and show the sync reminder panel for a given type of reminder
*
* @param reminderType - Possible values: 'setup' or 'autoSync'
* @param hideDisable - True if the 'Don't show again' link is hidden
*/
this.showSyncReminder = function (reminderType, hideDisable) {
let panel = document.getElementById('sync-reminder-container');
const closePanel = function () {
panel.setAttribute('collapsed', true);
Zotero.Prefs.set(`sync.reminder.${reminderType}.lastDisplayed`, String(Date.now()));
};
let message = document.getElementById('sync-reminder-message');
message.textContent = Zotero.getString(`sync.reminder.${reminderType}.message`);
message.onclick = function () {
closePanel();
Zotero.Utilities.Internal.openPreferences('zotero-prefpane-sync');
};
let actionLink = document.getElementById('sync-reminder-action');
actionLink.textContent = Zotero.getString(`sync.reminder.${reminderType}.action`);
actionLink.onclick = function () {
closePanel();
Zotero.Utilities.Internal.openPreferences('zotero-prefpane-sync');
};
let dontShowAgainLink = document.getElementById('sync-reminder-disable');
dontShowAgainLink.textContent = Zotero.getString('general.dontAskMeAgain');
dontShowAgainLink.hidden = hideDisable;
dontShowAgainLink.onclick = function () {
closePanel();
Zotero.Prefs.set(`sync.reminder.${reminderType}.enabled`, false);
// Check if we no longer need to observe item modifications
ZoteroPane.setupSyncReminders(false);
};
let remindMeLink = document.getElementById('sync-reminder-remind');
remindMeLink.textContent = Zotero.getString('sync.reminder.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) {
if (!itemID) {
return false;

View file

@ -221,7 +221,7 @@
<panel id="zotero-sync-error-panel" type="arrow"/>
<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
id="zotero-tb-sync-tooltip"
onpopupshowing="Zotero.Sync.Runner.registerSyncStatus(this)"
@ -235,6 +235,17 @@
</toolbarbutton>
</hbox>
</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"/>
<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">
<div xmlns="http://www.w3.org/1999/xhtml" id="retracted-items-banner">

View file

@ -3,6 +3,7 @@ extensions.zotero@chnm.gmu.edu.description = The Next-Generation Research Tool
general.success = Success
general.error = Error
general.warning = Warning
general.dontAskMeAgain = Don't ask me again
general.dontShowWarningAgain = Don't show this warning again.
general.dontShowAgainFor = Dont show again today;Dont show again for %1$S days
general.browserIsOffline = %S is currently in offline mode.
@ -993,6 +994,12 @@ sync.resetGroupFilesAndSync = Reset Group Files and Sync
sync.skipGroup = Skip Group
sync.removeGroupsAndSync = Remove Groups and Sync
sync.reminder.setup.message = Back up your library with Zotero syncing.
sync.reminder.setup.action = Set Up Syncing
sync.reminder.autoSync.message = Zotero can automatically sync after you make changes.
sync.reminder.autoSync.action = Enable Automatic Sync
sync.reminder.remindMeLater = Remind Me Later
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.passwordNotSet = Password not set

View file

@ -533,11 +533,11 @@
}
/* Sync error panel */
#zotero-sync-error-panel {
#zotero-sync-error-panel, #zotero-sync-reminder-panel {
margin-right: 0;
}
#zotero-sync-error-panel .error-header {
#zotero-sync-error-panel .error-header, #zotero-sync-reminder-panel .header {
font-size: 14px;
font-weight: bold;
margin-bottom: 1em;
@ -552,7 +552,7 @@
margin-bottom: 1.1em;
}
#zotero-sync-error-panel description {
#zotero-sync-error-panel description, #zotero-sync-reminder-panel description {
width: 370px;
white-space: pre-wrap;
}
@ -635,7 +635,7 @@
margin-left: 3px !important;
}
#retracted-items-banner {
#retracted-items-banner, #sync-reminder-banner {
display: flex;
justify-content: center;
background: #d93425;
@ -648,21 +648,36 @@
position: relative;
}
#retracted-items-message {
#sync-reminder-banner {
background: rgb(89, 139, 236);
}
#retracted-items-message, #sync-reminder-message {
margin-right: .8em;
}
#sync-reminder-spacer {
flex: 1;
}
#retracted-items-link {
text-decoration: underline;
margin-left: .3em;
cursor: pointer;
}
#retracted-items-link:active {
.sync-reminder-link {
text-decoration: underline;
cursor: pointer;
padding-left: 0.5em;
padding-right: 0.5em;
}
#retracted-items-link:active, .sync-reminder-link:active {
color: #f9e8e2;
}
#retracted-items-close {
#retracted-items-close, #sync-reminder-close {
position: absolute;
cursor: pointer;
top: -2px;

View file

@ -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.groups", "on-sync");
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
pref("extensions.zotero.proxies.autoRecognize", true);