Show toolbar icon and collections pane while items are loading

Items in a library are now loaded only when a library is clicked on and
at sync time. There might be some other areas where they need to be
loaded or where this causes problems (e.g., drag and drop, word
processor integration).
This commit is contained in:
Dan Stillman 2016-04-10 18:58:01 -04:00
parent be335acc65
commit 0469d6506a
7 changed files with 87 additions and 21 deletions

View file

@ -59,7 +59,6 @@ var ZoteroOverlay = new function()
} }
ZoteroPane_Overlay = ZoteroPane; ZoteroPane_Overlay = ZoteroPane;
ZoteroPane.init();
// Open Zotero app tab, if in Fx 4 and requested by pref // Open Zotero app tab, if in Fx 4 and requested by pref
showInPref = Components.classes["@mozilla.org/preferences-service;1"] showInPref = Components.classes["@mozilla.org/preferences-service;1"]
@ -106,6 +105,8 @@ var ZoteroOverlay = new function()
Zotero.logError(e); Zotero.logError(e);
} }
ZoteroPane.init();
// TODO: Add only when progress window is open // TODO: Add only when progress window is open
document.getElementById('appcontent').addEventListener('mousemove', Zotero.ProgressWindowSet.updateTimers, false); document.getElementById('appcontent').addEventListener('mousemove', Zotero.ProgressWindowSet.updateTimers, false);

View file

@ -416,19 +416,23 @@ Zotero.DataObjects.prototype._loadDataType = Zotero.Promise.coroutine(function*
Zotero.DataObjects.prototype.loadAll = Zotero.Promise.coroutine(function* (libraryID, ids) { Zotero.DataObjects.prototype.loadAll = Zotero.Promise.coroutine(function* (libraryID, ids) {
var t = new Date(); var t = new Date();
var libraryName = Zotero.Libraries.get(libraryID).name; var library = Zotero.Libraries.get(libraryID)
Zotero.debug("Loading " Zotero.debug("Loading "
+ (ids ? ids.length : "all") + " " + (ids ? ids.length : "all") + " "
+ (ids && ids.length == 1 ? this._ZDO_object : this._ZDO_objects) + (ids && ids.length == 1 ? this._ZDO_object : this._ZDO_objects)
+ " in " + libraryName); + " in " + library.name);
library.setDataLoading(this._ZDO_object);
let dataTypes = this.ObjectClass.prototype._dataTypes; let dataTypes = this.ObjectClass.prototype._dataTypes;
for (let i = 0; i < dataTypes.length; i++) { for (let i = 0; i < dataTypes.length; i++) {
yield this._loadDataType(dataTypes[i], libraryID, ids); yield this._loadDataType(dataTypes[i], libraryID, ids);
} }
Zotero.debug(`Loaded all data in ${libraryName} in ${new Date() - t} ms`); Zotero.debug(`Loaded all ${this._ZDO_objects} in ${library.name} in ${new Date() - t} ms`);
library.setDataLoaded(this._ZDO_object);
}); });

View file

@ -31,6 +31,9 @@ Zotero.Library = function(params = {}) {
this._changed = {}; this._changed = {};
this._dataLoaded = {};
this._dataLoadedDeferreds = {};
this._hasCollections = null; this._hasCollections = null;
this._hasSearches = null; this._hasSearches = null;
this._storageDownloadNeeded = false; this._storageDownloadNeeded = false;
@ -344,6 +347,45 @@ Zotero.Library.prototype.loadAllDataTypes = Zotero.Promise.coroutine(function* (
yield Zotero.Items.loadAll(this.libraryID); yield Zotero.Items.loadAll(this.libraryID);
}); });
//
// Methods to handle promises that are resolved when object data is loaded for the library
//
Zotero.Library.prototype.getDataLoaded = function (objectType) {
return this._dataLoaded[objectType] || null;
};
Zotero.Library.prototype.setDataLoading = function (objectType) {
if (this._dataLoadedDeferreds[objectType]) {
throw new Error("Items already loading for library " + this.libraryID);
}
this._dataLoadedDeferreds[objectType] = Zotero.Promise.defer();
};
Zotero.Library.prototype.getDataLoadedPromise = function (objectType) {
return this._dataLoadedDeferreds[objectType]
? this._dataLoadedDeferreds[objectType].promise : null;
};
Zotero.Library.prototype.setDataLoaded = function (objectType) {
this._dataLoaded[objectType] = true;
this._dataLoadedDeferreds[objectType].resolve();
};
Zotero.Library.prototype.waitForDataLoad = Zotero.Promise.coroutine(function* (objectType) {
if (this.getDataLoaded(objectType)) return;
let promise = this.getDataLoadedPromise(objectType);
// If items are already being loaded, wait for them
if (promise) {
yield promise;
}
// Otherwise load them now
else {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(objectType);
yield objectsClass.loadAll(this.libraryID);
}
});
Zotero.Library.prototype.isChildObjectAllowed = function(type) { Zotero.Library.prototype.isChildObjectAllowed = function(type) {
return this._childObjectTypes.indexOf(type) != -1; return this._childObjectTypes.indexOf(type) != -1;
}; };

View file

@ -174,6 +174,15 @@ Zotero.Sync.Runner_Module = function (options = {}) {
keyInfo, keyInfo,
options.libraries ? Array.from(options.libraries) : [] options.libraries ? Array.from(options.libraries) : []
); );
// If items not yet loaded for libraries we need, load them now
for (let libraryID of librariesToSync) {
let library = Zotero.Libraries.get(libraryID);
if (!library.getDataLoaded('item')) {
yield library.waitForDataLoad('item');
}
}
// Sync data and files, and then repeat if necessary // Sync data and files, and then repeat if necessary
let attempt = 1; let attempt = 1;
let nextLibraries = librariesToSync.concat(); let nextLibraries = librariesToSync.concat();
@ -283,6 +292,9 @@ Zotero.Sync.Runner_Module = function (options = {}) {
}); });
/**
* @return {Promise<Integer[]> - IDs of libraries to sync
*/
this.checkLibraries = Zotero.Promise.coroutine(function* (client, options, keyInfo, libraries = []) { this.checkLibraries = Zotero.Promise.coroutine(function* (client, options, keyInfo, libraries = []) {
var access = keyInfo.access; var access = keyInfo.access;

View file

@ -630,11 +630,15 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
yield Zotero.Relations.init(); yield Zotero.Relations.init();
yield Zotero.Feeds.init(); yield Zotero.Feeds.init();
let libraryIDs = Zotero.Libraries.getAll().map(x => x.libraryID); // Load all library data except for items
for (let libraryID of libraryIDs) { yield Zotero.Promise.each(
let library = Zotero.Libraries.get(libraryID); Zotero.Libraries.getAll(),
yield library.loadAllDataTypes(); library => Zotero.Promise.coroutine(function* () {
} yield Zotero.SyncedSettings.loadAll(library.libraryID);
yield Zotero.Collections.loadAll(library.libraryID);
yield Zotero.Searches.loadAll(library.libraryID);
})()
);
yield Zotero.QuickCopy.init(); yield Zotero.QuickCopy.init();
@ -2120,22 +2124,21 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
/* /*
* Clear entries that no longer exist from various tables * Clear entries that no longer exist from various tables
*/ */
this.purgeDataObjects = Zotero.Promise.coroutine(function* (skipStoragePurge) { this.purgeDataObjects = Zotero.Promise.coroutine(function* () {
yield Zotero.DB.executeTransaction(function* () { yield Zotero.DB.executeTransaction(function* () {
return Zotero.Creators.purge(); return Zotero.Creators.purge();
}); });
yield Zotero.DB.executeTransaction(function* () { yield Zotero.DB.executeTransaction(function* () {
return Zotero.Tags.purge(); return Zotero.Tags.purge();
}); });
// TEMP: Disabled until we have async DB (and maybe SQLite FTS) Zotero.Fulltext.purgeUnusedWords();
//Zotero.Fulltext.purgeUnusedWords();
yield Zotero.DB.executeTransaction(function* () { yield Zotero.DB.executeTransaction(function* () {
return Zotero.Items.purge(); return Zotero.Items.purge();
}); });
// DEBUG: this might not need to be permanent // DEBUG: this might not need to be permanent
yield Zotero.DB.executeTransaction(function* () { //yield Zotero.DB.executeTransaction(function* () {
return Zotero.Relations.purge(); // return Zotero.Relations.purge();
}); //});
}); });

View file

@ -1214,6 +1214,15 @@ var ZoteroPane = new function()
ZoteroPane_Local.displayErrorMessage(); ZoteroPane_Local.displayErrorMessage();
}; };
this.itemsView.addEventListener('load', this.setTagScope); this.itemsView.addEventListener('load', this.setTagScope);
// If item data not yet loaded for library, load it now.
// Other data types are loaded at startup
var library = Zotero.Libraries.get(collectionTreeRow.ref.libraryID);
if (!library.getDataLoaded('item')) {
Zotero.debug("Waiting for items to load for library " + library.libraryID);
yield library.waitForDataLoad('item');
}
document.getElementById('zotero-items-tree').view = this.itemsView; document.getElementById('zotero-items-tree').view = this.itemsView;
// Add events to treecolpicker to update menu before showing/hiding // Add events to treecolpicker to update menu before showing/hiding
@ -1920,7 +1929,7 @@ var ZoteroPane = new function()
); );
if (result) { if (result) {
let deleted = yield Zotero.Items.emptyTrash(libraryID); let deleted = yield Zotero.Items.emptyTrash(libraryID);
yield Zotero.purgeDataObjects(true); yield Zotero.purgeDataObjects();
} }
}); });

View file

@ -53,11 +53,6 @@ var loadZoteroPane = Zotero.Promise.coroutine(function* (win) {
Zotero.Prefs.clear('lastViewedFolder'); Zotero.Prefs.clear('lastViewedFolder');
win.ZoteroOverlay.toggleDisplay(true); win.ZoteroOverlay.toggleDisplay(true);
// Hack to wait for pane load to finish. This is the same hack
// we use in ZoteroPane.js, so either it's not good enough
// there or it should be good enough here.
yield Zotero.Promise.delay(52);
yield waitForItemsLoad(win, 0); yield waitForItemsLoad(win, 0);
return win; return win;