0.4.1e 11-Feb-2021
-Spell panel working except for initial and sorting compendium-browser.js - Don't save the filter data (which is most of the memory) and remove the preload limit; instead just save the minimal amount of data - loadAndFilterItems(): Only load the tab you're on - for now just spells -- store compactItems instead of whole decoratedItem (which was used for filtering) -activateListeners(): Split out activateItemListListeners() so we can call them when we reload spell-browser.htmlv0.3.1-spetzel2020
parent
07d3d378f6
commit
4bee393f39
|
@ -19,6 +19,7 @@
|
||||||
9-Feb-2021 0.4.1b Call loadAndFilterItems instead of loadItems; filter as we go, limited by numToPreload
|
9-Feb-2021 0.4.1b Call loadAndFilterItems instead of loadItems; filter as we go, limited by numToPreload
|
||||||
0.4.1c Needed to pass specific spellFilters, itemFilters etc.
|
0.4.1c Needed to pass specific spellFilters, itemFilters etc.
|
||||||
0.4.1d: Fixed img observer on replaced spellData
|
0.4.1d: Fixed img observer on replaced spellData
|
||||||
|
11-Feb-2021 0.4.1e: Don't save the filter data (which is most of the memory) and remove the preload limit; instead just save the minimal amount of data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const CMPBrowser = {
|
const CMPBrowser = {
|
||||||
|
@ -101,44 +102,65 @@ class CompendiumBrowser extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadAndFilterItems(numToPreload=CMPBrowser.PRELOAD) {
|
async loadAndFilterItems(itemType="spell",numToPreload=CMPBrowser.PRELOAD) {
|
||||||
console.log('Load and Filter Items | Started loading items');
|
console.log(`Load and Filter Items | Started loading ${itemType}s`);
|
||||||
console.time("loadAndFilterItems");
|
console.time("loadAndFilterItems");
|
||||||
await this.checkListsLoaded();
|
await this.checkListsLoaded();
|
||||||
|
|
||||||
|
//0.4.1: Load and filter just one of spells, feats, and items (specified by itemType)
|
||||||
let unfoundSpells = '';
|
let unfoundSpells = '';
|
||||||
let numSpellsLoaded = 0;
|
|
||||||
let numFeatsLoaded = 0;
|
|
||||||
let numItemsLoaded = 0;
|
let numItemsLoaded = 0;
|
||||||
|
let compactItems = {};
|
||||||
let items = {
|
let items = {
|
||||||
spells: {},
|
spells: {},
|
||||||
feats: {},
|
feats: {},
|
||||||
items: {}
|
items: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Filter the full list, but only save the core compendium information + level
|
||||||
for (let pack of game.packs) {
|
for (let pack of game.packs) {
|
||||||
if (pack['metadata']['entity'] === "Item" && this.settings.loadedSpellCompendium[pack.collection].load) {
|
if (pack['metadata']['entity'] === "Item" && this.settings.loadedSpellCompendium[pack.collection].load) {
|
||||||
//FIXME: How much could we do with the loaded index rather than all content?
|
//FIXME: How much could we do with the loaded index rather than all content?
|
||||||
await pack.getContent().then(content => {
|
await pack.getContent().then(content => {
|
||||||
for (let item5e of content) {
|
for (let item5e of content) {
|
||||||
const decoratedItem = this.decorateCompendiumEntry(item5e);
|
if (item5e.type === itemType) {
|
||||||
if (decoratedItem) {
|
const decoratedItem = this.decorateCompendiumEntry(item5e);
|
||||||
decoratedItem.compendium = pack.collection;
|
if (decoratedItem) {
|
||||||
if ((decoratedItem.type === "spell") && this.getFilterResult(decoratedItem, this.spellFilters.activeFilters) && (numSpellsLoaded < numToPreload)) {
|
let altItemSort = null;
|
||||||
numSpellsLoaded++;
|
decoratedItem.compendium = pack.collection;
|
||||||
items.spells[decoratedItem._id] = decoratedItem;
|
if (decoratedItem.type === "spell") {
|
||||||
} else if ((decoratedItem.type === "feat") && this.getFilterResult(decoratedItem, this.featFilters.activeFilters) && (numFeatsLoaded < numToPreload)) {
|
if (this.getFilterResult(decoratedItem, this.spellFilters.activeFilters)) {
|
||||||
numFeatsLoaded++;
|
altItemSort = decoratedItem.data?.level;
|
||||||
items.feats[decoratedItem._id] = decoratedItem;
|
}
|
||||||
} else if (this.getFilterResult(decoratedItem, this.itemFilters.activeFilters) && (numItemsLoaded < numToPreload)) {
|
} else if (decoratedItem.type === "feat") {
|
||||||
numItemsLoaded++;
|
if (this.getFilterResult(decoratedItem, this.featFilters.activeFilters)) {
|
||||||
items.items[decoratedItem._id] = decoratedItem;
|
altItemSort = item5e.name; //FIXME
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.getFilterResult(decoratedItem, this.itemFilters.activeFilters)) {
|
||||||
|
altItemSort = item5e.name; //FIXME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (altItemSort) { //Indicates it passed the filters
|
||||||
|
compactItems[decoratedItem._id] = {
|
||||||
|
compendium : pack.collection,
|
||||||
|
name : decoratedItem.name,
|
||||||
|
img: decoratedItem.img,
|
||||||
|
data : {
|
||||||
|
level : decoratedItem.data?.level,
|
||||||
|
components : decoratedItem.data?.components
|
||||||
|
},
|
||||||
|
altItemSort : altItemSort
|
||||||
|
}
|
||||||
|
if (numItemsLoaded++ >= numToPreload) break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}//for item5e of content
|
}//for item5e of content
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ((numSpellsLoaded >= numToPreload) && (numFeatsLoaded >= numToPreload) && (numItemsLoaded >= numToPreload)) break;
|
if (numItemsLoaded >= numToPreload) break;
|
||||||
}//for packs
|
}//for packs
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -148,9 +170,9 @@ class CompendiumBrowser extends Application {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
this.itemsLoaded = true;
|
this.itemsLoaded = true;
|
||||||
console.timeEnd("loadItems");
|
console.timeEnd("loadAndFilterItems");
|
||||||
console.log(`Load and Filter Items | Finished loading items: ${Object.keys(items.spells).length} spells, ${Object.keys(items.feats).length} features, ${Object.keys(items.items).length} items `);
|
console.log(`Load and Filter Items | Finished loading ${Object.keys(compactItems).length} ${itemType}s`);
|
||||||
return items;
|
return compactItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadItems(numToPreload=CMPBrowser.PRELOAD) {
|
async loadItems(numToPreload=CMPBrowser.PRELOAD) {
|
||||||
|
@ -427,7 +449,7 @@ class CompendiumBrowser extends Application {
|
||||||
//0.4.1 Filter as we load to support new way of filtering
|
//0.4.1 Filter as we load to support new way of filtering
|
||||||
//Previously loaded all data and filtered in place; now loads minimal (preload) amount, filtered as we go
|
//Previously loaded all data and filtered in place; now loads minimal (preload) amount, filtered as we go
|
||||||
//First time (when you press Compendium Browser button) is called with filters unset
|
//First time (when you press Compendium Browser button) is called with filters unset
|
||||||
this.items = await this.loadAndFilterItems(numToPreload);
|
this.items = await this.loadAndFilterItems("spell",numToPreload);
|
||||||
if (!this.npcsLoaded) {
|
if (!this.npcsLoaded) {
|
||||||
this.npcs = await this.loadNpcs(numToPreload); //also sets this.npcsLoaded
|
this.npcs = await this.loadNpcs(numToPreload); //also sets this.npcsLoaded
|
||||||
}
|
}
|
||||||
|
@ -452,6 +474,38 @@ class CompendiumBrowser extends Application {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activateItemListListeners(html) {
|
||||||
|
// show entity sheet
|
||||||
|
html.find('.item-edit').click(ev => {
|
||||||
|
let itemId = $(ev.currentTarget).parents("li").attr("data-entry-id");
|
||||||
|
let compendium = $(ev.currentTarget).parents("li").attr("data-entry-compendium");
|
||||||
|
let pack = game.packs.find(p => p.collection === compendium);
|
||||||
|
pack.getEntity(itemId).then(entity => {
|
||||||
|
entity.sheet.render(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// make draggable
|
||||||
|
//0.4.1: Avoid the game.packs lookup
|
||||||
|
html.find('.draggable').each((i, li) => {
|
||||||
|
li.setAttribute("draggable", true);
|
||||||
|
li.addEventListener('dragstart', event => {
|
||||||
|
let packName = li.getAttribute("data-entry-compendium");
|
||||||
|
let itemType = li.parents('.tab').data('tab');
|
||||||
|
let pack = game.packs.find(p => p.collection === packName);
|
||||||
|
if (!pack) {
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
event.dataTransfer.setData("text/plain", JSON.stringify({
|
||||||
|
type: pack.entity,
|
||||||
|
pack: pack.collection,
|
||||||
|
id: li.getAttribute("data-entry-id")
|
||||||
|
}));
|
||||||
|
}, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
// localizing title
|
// localizing title
|
||||||
|
@ -473,34 +527,7 @@ class CompendiumBrowser extends Application {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.activateItemListListeners(html);
|
||||||
// show entity sheet
|
|
||||||
html.find('.item-edit').click(ev => {
|
|
||||||
let itemId = $(ev.currentTarget).parents("li").attr("data-entry-id");
|
|
||||||
let compendium = $(ev.currentTarget).parents("li").attr("data-entry-compendium");
|
|
||||||
let pack = game.packs.find(p => p.collection === compendium);
|
|
||||||
pack.getEntity(itemId).then(entity => {
|
|
||||||
entity.sheet.render(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// make draggable
|
|
||||||
html.find('.draggable').each((i, li) => {
|
|
||||||
li.setAttribute("draggable", true);
|
|
||||||
li.addEventListener('dragstart', event => {
|
|
||||||
let packName = li.getAttribute("data-entry-compendium");
|
|
||||||
let pack = game.packs.find(p => p.collection === packName);
|
|
||||||
if (!pack) {
|
|
||||||
event.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
event.dataTransfer.setData("text/plain", JSON.stringify({
|
|
||||||
type: pack.entity,
|
|
||||||
pack: pack.collection,
|
|
||||||
id: li.getAttribute("data-entry-id")
|
|
||||||
}));
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// toggle visibility of filter containers
|
// toggle visibility of filter containers
|
||||||
html.find('.filtercontainer h3, .multiselect label').click(async ev => {
|
html.find('.filtercontainer h3, .multiselect label').click(async ev => {
|
||||||
|
@ -619,10 +646,9 @@ class CompendiumBrowser extends Application {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// activating or deactivating filters - in place
|
// activating or deactivating filters
|
||||||
|
//0.4.1: Now does a re-load and updates just the data side
|
||||||
// text filters
|
// text filters
|
||||||
|
|
||||||
html.find('.filter[data-type=text] input, .filter[data-type=text] select').on('keyup change paste', ev => {
|
html.find('.filter[data-type=text] input, .filter[data-type=text] select').on('keyup change paste', ev => {
|
||||||
let path = $(ev.target).parents('.filter').data('path');
|
let path = $(ev.target).parents('.filter').data('path');
|
||||||
let key = path.replace(/\./g, '');
|
let key = path.replace(/\./g, '');
|
||||||
|
@ -688,7 +714,6 @@ class CompendiumBrowser extends Application {
|
||||||
|
|
||||||
let list = null;
|
let list = null;
|
||||||
let subjects = null;
|
let subjects = null;
|
||||||
let items = null;
|
|
||||||
if (itemType === 'spell') {
|
if (itemType === 'spell') {
|
||||||
list = html.find('.spell-browser li');
|
list = html.find('.spell-browser li');
|
||||||
subjects = this.items.spells;
|
subjects = this.items.spells;
|
||||||
|
@ -726,7 +751,7 @@ class CompendiumBrowser extends Application {
|
||||||
path: path,
|
path: path,
|
||||||
type: filterType,
|
type: filterType,
|
||||||
valIsArray: valIsArray,
|
valIsArray: valIsArray,
|
||||||
values: [ value ]
|
values: [value]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this[filterTarget].activeFilters[key].values.push(value);
|
this[filterTarget].activeFilters[key].values.push(value);
|
||||||
|
@ -788,6 +813,7 @@ class CompendiumBrowser extends Application {
|
||||||
if (itemType === 'spell') {
|
if (itemType === 'spell') {
|
||||||
list = html.find('.spell-browser li');
|
list = html.find('.spell-browser li');
|
||||||
subjects = this.items.spells;
|
subjects = this.items.spells;
|
||||||
|
this.replaceSpells(html, observer);
|
||||||
} else if (itemType === 'npc') {
|
} else if (itemType === 'npc') {
|
||||||
list = html.find('.npc-browser li');
|
list = html.find('.npc-browser li');
|
||||||
subjects = this.npcs;
|
subjects = this.npcs;
|
||||||
|
@ -815,15 +841,19 @@ class CompendiumBrowser extends Application {
|
||||||
replacement.setAttribute("id","CBSpells");
|
replacement.setAttribute("id","CBSpells");
|
||||||
replacement.innerHTML = newSpellsHTML;
|
replacement.innerHTML = newSpellsHTML;
|
||||||
items[0].parentNode.replaceChild(replacement, items[0]);
|
items[0].parentNode.replaceChild(replacement, items[0]);
|
||||||
|
|
||||||
//Lazy load images
|
//Lazy load images
|
||||||
$(replacement).find("img").each((i, img) => observer.observe(img));
|
$(replacement).find("img").each((i, img) => observer.observe(img));
|
||||||
|
|
||||||
|
//Reactivate listeners for clicking and dragging
|
||||||
|
this.activateItemListListeners($(replacement));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async renderSpellData() {
|
async renderSpellData() {
|
||||||
const items = await this.loadAndFilterItems();
|
const items = await this.loadAndFilterItems("spell");
|
||||||
const spellData = items?.spells;
|
const spellData = items;
|
||||||
const html = await renderTemplate("modules/compendium-browser/template/spell-browser-list.html", {spells : spellData});
|
const html = await renderTemplate("modules/compendium-browser/template/spell-browser-list.html", {spells : spellData});
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
{{#each spells as |spell id|}}
|
{{#each spells as |spell id|}}
|
||||||
<li class="spell flexrow draggable" data-entry-compendium="{{spell.compendium}}" data-entry-id="{{spell._id}}">
|
<li class="spell flexrow draggable" data-entry-compendium="{{spell.compendium}}" data-entry-id="{{id}}">
|
||||||
<div class="item-image">
|
<div class="item-image">
|
||||||
<img class="" data-src="{{spell.img}}" title="{{spell.name}}" width="32" height="32"/>
|
<img class="" data-src="{{spell.img}}" title="{{spell.name}}" width="32" height="32"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue