0.4.2f 16-Feb-2021

- Working with Loading and Maximum message at top
- Reset Filters is not resetting filter display

compendium-browser.js
- Change preload to maxLoaded and display a message to filter if you want more
- replaceList(): Pass updateLoading function (with max warning) to renderItemData

en.json
CMPBrowser.SETTING.Preload -> Maxload
CMPBrowser.LOADING.Message, .MaxLoaded: ADDED

*-browser.html
- Add messages line, convert to flexcol

*-browser-list.html
- Use same argument (listItems)

loading.html
- Message (including maximum if found)

compendium-browser.css
- Add .list-area styling consistent with flex
- Adjust max-width
- Remove ul setting of width
v0.3.1-spetzel2020
opus1217 2021-02-16 20:39:39 -08:00
parent 0aeecb6963
commit 4ddad55232
12 changed files with 96 additions and 93 deletions

View File

@ -53,12 +53,22 @@
position: sticky; position: sticky;
display: block; display: block;
min-width: 250px; min-width: 250px;
max-width: 400px; max-width: 50%;
width: 300px; width: 350px;
height: 100%; height: 100%;
padding-right: 5px; padding-right: 5px;
overflow: scroll; overflow: scroll;
} }
.compendium-browser .list-area {
position: sticky;
display: flex;
min-width: 250px;
max-width: 50%;
width: 400px;
height: 100%;
padding-right: 5px;
overflow-y: scroll;
}
.compendium-browser .control-area button { .compendium-browser .control-area button {
background: rgba(0, 0, 0, 0.05); background: rgba(0, 0, 0, 0.05);
border: 1px solid #bbb; border: 1px solid #bbb;
@ -129,7 +139,6 @@
float: right; float: right;
display: block; display: block;
min-width: 335px; min-width: 335px;
width: 785px;
margin: 0; margin: 0;
height: 100%; height: 100%;
overflow: auto; overflow: auto;

View File

@ -31,13 +31,13 @@
0.4.2b: Add Loading... message for NPCs 0.4.2b: Add Loading... message for NPCs
0.4.2c: Correct Loading... message on initial tab, but not on tab switch 0.4.2c: Correct Loading... message on initial tab, but not on tab switch
0.4.2d: Display the type of item being loaded 0.4.2d: Display the type of item being loaded
16-Dec-2021 0.4.2f: Change preload to maxLoaded and display a message to filter if you want more
*/ */
const CMPBrowser = { const CMPBrowser = {
MODULE_NAME : "compendium-browser", MODULE_NAME : "compendium-browser",
MODULE_VERSION : "0.4.2", MODULE_VERSION : "0.4.2",
PRELOAD : 9999, //How many items, spells, or NPCs you load at once (to minimize memory usage) - ignored for now MAXLOAD : 500, //Default for the maximum number to load before displaying a message that you need to filter to see more
VISIBLE_ROWS : 50 //Plug for maximum rows visible in window - fetch more when actual < this
} }
class CompendiumBrowser extends Application { class CompendiumBrowser extends Application {
@ -62,15 +62,7 @@ class CompendiumBrowser extends Application {
if (this.settings === undefined) { if (this.settings === undefined) {
this.initSettings(); this.initSettings();
} }
const numToPreload = game.settings.get(CMPBrowser.MODULE_NAME, "preload") ?? CMPBrowser.PRELOAD;
/*
this.loadItems(numToPreload).then(obj => {
this.items = obj;
});
this.loadNpcs(numToPreload).then(obj => {
this.npcs = obj;
}); //Plug
*/
await loadTemplates([ await loadTemplates([
"modules/compendium-browser/template/spell-browser.html", "modules/compendium-browser/template/spell-browser.html",
"modules/compendium-browser/template/spell-browser-list.html", "modules/compendium-browser/template/spell-browser-list.html",
@ -129,15 +121,7 @@ class CompendiumBrowser extends Application {
/** override */ /** override */
async getData() { async getData() {
//Only called on initial display or refresh (including when settings are changed)
const numToPreload = game.settings.get(CMPBrowser.MODULE_NAME, "preload") ?? CMPBrowser.PRELOAD;
/*
if (!this.spellsLoaded) {
// spells will be stored locally to not require full loading each time the browser is opened
this.items = await this.loadItems(numToPreload); //also sets this.spellsLoaded
}
*/
//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
@ -474,11 +458,13 @@ class CompendiumBrowser extends Application {
} }
} }
async loadAndFilterItems(browserTab="spell",updateLoading, numToPreload=CMPBrowser.PRELOAD) { async loadAndFilterItems(browserTab="spell",updateLoading=null) {
console.log(`Load and Filter Items | Started loading ${browserTab}s`); console.log(`Load and Filter Items | Started loading ${browserTab}s`);
console.time("loadAndFilterItems"); console.time("loadAndFilterItems");
await this.checkListsLoaded(); await this.checkListsLoaded();
const maxLoad = game.settings.get(CMPBrowser.MODULE_NAME, "maxload") ?? CMPBrowser.MAXLOAD;
//0.4.1: Load and filter just one of spells, feats, and items (specified by browserTab) //0.4.1: Load and filter just one of spells, feats, and items (specified by browserTab)
let unfoundSpells = ''; let unfoundSpells = '';
let numItemsLoaded = 0; let numItemsLoaded = 0;
@ -524,7 +510,7 @@ class CompendiumBrowser extends Application {
} }
if (compactItem) { //Indicates it passed the filters if (compactItem) { //Indicates it passed the filters
compactItems[decoratedItem._id] = compactItem; compactItems[decoratedItem._id] = compactItem;
if (numItemsLoaded++ >= numToPreload) break; if (numItemsLoaded++ >= maxLoad) break;
//0.4.2e: Update the UI (e.g. "Loading 142 spells") //0.4.2e: Update the UI (e.g. "Loading 142 spells")
if (updateLoading) {updateLoading(numItemsLoaded);} if (updateLoading) {updateLoading(numItemsLoaded);}
} }
@ -532,7 +518,7 @@ class CompendiumBrowser extends Application {
}//for item5e of content }//for item5e of content
}); });
}//end if pack entity === Item }//end if pack entity === Item
if (numItemsLoaded >= numToPreload) break; if (numItemsLoaded >= maxLoad) break;
}//for packs }//for packs
/* /*
@ -689,12 +675,14 @@ class CompendiumBrowser extends Application {
return items; return items;
} }
async loadAndFilterNpcs(numToPreload=CMPBrowser.PRELOAD) { async loadAndFilterNpcs(updateLoading=null) {
console.log('NPC Browser | Started loading NPCs'); console.log('NPC Browser | Started loading NPCs');
console.time("loadAndFilterNpcs"); console.time("loadAndFilterNpcs");
let npcs = {}; let npcs = {};
let numberLoaded = 0; const maxLoad = game.settings.get(CMPBrowser.MODULE_NAME, "maxload") ?? CMPBrowser.MAXLOAD;
let numNpcsLoaded = 0;
this.npcsLoaded = false; this.npcsLoaded = false;
for (let pack of game.packs) { for (let pack of game.packs) {
if (pack['metadata']['entity'] == "Actor" && this.settings.loadedNpcCompendium[pack.collection].load) { if (pack['metadata']['entity'] == "Actor" && this.settings.loadedNpcCompendium[pack.collection].load) {
@ -717,15 +705,17 @@ class CompendiumBrowser extends Application {
} }
if (compactNpc) { if (compactNpc) {
npcs[decoratedNpc._id] = compactNpc; npcs[decoratedNpc._id] = compactNpc;
//0.4.2 Don't load more than maxLoad; display a message to filter
if (numNpcsLoaded++ > maxLoad) break;
//0.4.2e: Update the UI (e.g. "Loading 142 NPCs")
if (updateLoading) {updateLoading(numNpcsLoaded);}
} }
//0.4.1 Only preload a limited number and fill more in as needed
if (numberLoaded++ > numToPreload) break;
} }
} }
}); });
} }
//0.4.1 Only preload a limited number and fill more in as needed //0.4.1 Only preload a limited number and fill more in as needed
if (numberLoaded > numToPreload) break; if (numNpcsLoaded >= maxLoad) break;
} }
this.npcsLoaded = true; this.npcsLoaded = true;
@ -775,21 +765,28 @@ class CompendiumBrowser extends Application {
//After rendering the first time or re-rendering trigger the load/reload of visible data //After rendering the first time or re-rendering trigger the load/reload of visible data
let elements = null; let elements = null;
//0.4.2 Display a Loading... message while the data is being loaded and filtered
let loadingMessage = null;
if (browserTab === 'spell') { if (browserTab === 'spell') {
elements = html.find("ul#CBSpells"); elements = html.find("ul#CBSpells");
loadingMessage = html.find("#CBSpellsMessage");
} else if (browserTab === 'npc') { } else if (browserTab === 'npc') {
elements = html.find("ul#CBNPCs"); elements = html.find("ul#CBNPCs");
loadingMessage = html.find("#CBNpcsMessage");
} else if (browserTab === 'feat') { } else if (browserTab === 'feat') {
elements = html.find("ul#CBFeats"); elements = html.find("ul#CBFeats");
loadingMessage = html.find("#CBFeatsMessage");
} else if (browserTab === 'item') { } else if (browserTab === 'item') {
elements = html.find("ul#CBItems"); elements = html.find("ul#CBItems");
loadingMessage = html.find("#CBItemsMessage");
} }
if (elements?.length) { if (elements?.length) {
//0.4.2b: On a tab-switch, only reload if there isn't any data already //0.4.2b: On a tab-switch, only reload if there isn't any data already
if (options?.reload || !elements[0].children.length) { if (options?.reload || !elements[0].children.length) {
//0.4.2 Display a Loading... message while the data is being loaded and filtered
const maxLoad = game.settings.get(CMPBrowser.MODULE_NAME, "maxload") ?? CMPBrowser.MAXLOAD;
const updateLoading = async numLoaded => { const updateLoading = async numLoaded => {
this.renderLoading(elements[0], browserTab, numLoaded); if (loadingMessage.length) {this.renderLoading(loadingMessage[0], browserTab, numLoaded, numLoaded>=maxLoad);}
} }
updateLoading(0); updateLoading(0);
@ -811,35 +808,22 @@ class CompendiumBrowser extends Application {
} }
async renderLoading(rootElement, itemType, numLoaded) { async renderLoading(messageElement, itemType, numLoaded, maxLoaded=false) {
if (!rootElement) return; if (!messageElement) return;
const loadingProgress = {
name: "Loading...",
img: "icons/sundries/books/book-open-turquoise.webp",
numLoaded: numLoaded,
itemType: itemType
}
let loadingHTML = await renderTemplate("modules/compendium-browser/template/loading.html", { loadingProgress: loadingProgress }); let loadingHTML = await renderTemplate("modules/compendium-browser/template/loading.html", {numLoaded: numLoaded, itemType: itemType, maxLoaded: maxLoaded});
rootElement.innerHTML = loadingHTML; messageElement.innerHTML = loadingHTML;
} }
async renderItemData(browserTab, updateLoading=null) { async renderItemData(browserTab, updateLoading=null) {
let items; let listItems;
let html; if (browserTab === "npc") {
if (browserTab === "spell") { listItems = await this.loadAndFilterNpcs(updateLoading);
items = await this.loadAndFilterItems(browserTab, updateLoading);
html = await renderTemplate("modules/compendium-browser/template/spell-browser-list.html", {spells : items});
} else if (browserTab === "feat") {
items = await this.loadAndFilterItems(browserTab, updateLoading);
html = await renderTemplate("modules/compendium-browser/template/feat-browser-list.html", {feats : items});
} else if (browserTab === "npc") {
const npcs = await this.loadAndFilterNpcs(updateLoading);
html = await renderTemplate("modules/compendium-browser/template/npc-browser-list.html", {npcs : npcs});
} else { } else {
items = await this.loadAndFilterItems(browserTab, updateLoading); listItems = await this.loadAndFilterItems(browserTab, updateLoading);
html = await renderTemplate("modules/compendium-browser/template/item-browser-list.html", {items : items});
} }
const html = await renderTemplate(`modules/compendium-browser/template/${browserTab}-browser-list.html`, {listItems : listItems})
return html; return html;
} }
@ -1202,16 +1186,16 @@ class CompendiumBrowser extends Application {
this.settings = settings; this.settings = settings;
} }
}); });
game.settings.register(CMPBrowser.MODULE_NAME, "preload", { game.settings.register(CMPBrowser.MODULE_NAME, "maxload", {
name: game.i18n.localize("CMPBrowser.SETTING.Preload.NAME"), name: game.i18n.localize("CMPBrowser.SETTING.Maxload.NAME"),
hint: game.i18n.localize("CMPBrowser.SETTING.Preload.HINT"), hint: game.i18n.localize("CMPBrowser.SETTING.Maxload.HINT"),
scope: "world", scope: "world",
config: true, config: true,
default: CMPBrowser.PRELOAD, default: CMPBrowser.MAXLOAD,
type: Number, type: Number,
range: { // If range is specified, the resulting setting will be a range slider range: { // If range is specified, the resulting setting will be a range slider
min: 20, min: 200,
max: 9999, max: 5000,
step: 100 step: 100
} }
}); });

View File

@ -60,7 +60,9 @@
"CMPBrowser.Tab.ItemBrowser": "Item Browser", "CMPBrowser.Tab.ItemBrowser": "Item Browser",
"CMPBrowser.Tab.NPCBrowser":"NPC Browser", "CMPBrowser.Tab.NPCBrowser":"NPC Browser",
"CMPBrowser.Tab.Settings":"Settings", "CMPBrowser.Tab.Settings":"Settings",
"CMPBrowser.SETTING.Preload.NAME" : "Number to preload", "CMPBrowser.SETTING.Maxload.NAME" : "Maximum load",
"CMPBrowser.SETTING.Preload.HINT" : "How many spells, feats, items, and NPCs to preload to keep memory manageable. " "CMPBrowser.SETTING.Maxload.HINT" : "Maximum number of spells, feats, items, or NPCs to display; to see more use the filters. This setting is to allow manageing memory and server load.",
"CMPBrowser.LOADING.Message" : "Loaded...{numLoaded} {itemType}s",
"CMPBrowser.LOADING.MaxLoaded" : "(maximum displayed; to see more, use the filters)"
} }

View File

@ -1,4 +1,4 @@
{{#each feats as |feat id|}} {{#each listItems as |feat id|}}
<li class="feat flexrow draggable" data-entry-compendium="{{feat.compendium}}" data-entry-id="{{id}}"> <li class="feat flexrow draggable" data-entry-compendium="{{feat.compendium}}" data-entry-id="{{id}}">
<div class="item-image"> <div class="item-image">
<img class="" data-src="{{feat.img}}" title="{{feat.name}}" width="32" height="32" /> <img class="" data-src="{{feat.img}}" title="{{feat.name}}" width="32" height="32" />

View File

@ -15,8 +15,11 @@
</div> </div>
{{> "modules/compendium-browser/template/filter-container.html" filters=featFilters}} {{> "modules/compendium-browser/template/filter-container.html" filters=featFilters}}
</div> </div>
<ul id="CBFeats"> <div class="list-area flexcol">
{{> "modules/compendium-browser/template/feat-browser-list.html" feats=items}} <span id="CBFeatsMessage" style="flex:0"></span>
</ul> <ul id="CBFeats">
{{> "modules/compendium-browser/template/feat-browser-list.html" feats=items}}
</ul>
</div>
</div> </div>

View File

@ -1,4 +1,4 @@
{{#each items as |item id|}} {{#each listItems as |item id|}}
<li class="item flexrow draggable" data-entry-compendium="{{item.compendium}}" data-entry-id="{{id}}"> <li class="item flexrow draggable" data-entry-compendium="{{item.compendium}}" data-entry-id="{{id}}">
<div class="item-image"> <div class="item-image">
<img class="" data-src="{{item.img}}" title="{{item.name}}" width="32" height="32" /> <img class="" data-src="{{item.img}}" title="{{item.name}}" width="32" height="32" />

View File

@ -15,8 +15,10 @@
</div> </div>
{{> "modules/compendium-browser/template/filter-container.html" filters=itemFilters}} {{> "modules/compendium-browser/template/filter-container.html" filters=itemFilters}}
</div> </div>
<ul id="CBItems"> <div class="list-area flexcol">
{{> "modules/compendium-browser/template/item-browser-list.html" items=items}} <span id="CBItemsMessage" style="flex:0"></span>
</ul> <ul id="CBItems">
{{> "modules/compendium-browser/template/item-browser-list.html" items=items}}
</ul>
</div>
</div> </div>

View File

@ -1,9 +1,6 @@
<li class="spell flexrow loading"> <img class="" src="icons/sundries/books/book-open-turquoise.webp" title="Loading book" width="32" height="32"/>
<div class="item-image"> <span class="item-edit" >
<img class="" src="{{loadingProgress.img}}" title="{{loadingProgress.name}}" width="32" height="32"/> {{localize "CMPBrowser.LOADING.Message" numLoaded=numLoaded itemType=itemType}}
</div> {{#if maxLoaded}}{{localize "CMPBrowser.LOADING.MaxLoaded"}}{{/if}}
<div class="item-name"> </span>
<span class="item-edit" >{{loadingProgress.name}} {{loadingProgress.numLoaded}} {{loadingProgress.itemType}}s</span>
</div>
</li>

View File

@ -1,4 +1,4 @@
{{#each npcs as |npc id|}} {{#each listItems as |npc id|}}
<li class="npc flexrow draggable" data-entry-compendium="{{npc.compendium}}" data-entry-id="{{id}}"> <li class="npc flexrow draggable" data-entry-compendium="{{npc.compendium}}" data-entry-id="{{id}}">
<div class="npc-image"> <div class="npc-image">
<img class="" data-src="{{npc.img}}" title="{{npc.name}}" width="32" height="32" /> <img class="" data-src="{{npc.img}}" title="{{npc.name}}" width="32" height="32" />

View File

@ -16,8 +16,10 @@
</div> </div>
{{> "modules/compendium-browser/template/filter-container.html" filters=npcFilters}} {{> "modules/compendium-browser/template/filter-container.html" filters=npcFilters}}
</div> </div>
<ul id="CBNPCs"> <div class="list-area flexcol">
{{> "modules/compendium-browser/template/npc-browser-list.html" npcs=npcs}} <span id="CBNpcsMessage" style="flex:0"></span>
</ul> <ul id="CBNPCs">
{{> "modules/compendium-browser/template/npc-browser-list.html" npcs=npcs}}
</ul>
</div>
</div> </div>

View File

@ -1,5 +1,5 @@
{{#each spells as |spell id|}} {{#each listItems as |spell id|}}
<li class="spell flexrow draggable" data-entry-compendium="{{spell.compendium}}" data-entry-id="{{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"/>
@ -22,3 +22,4 @@
</div> </div>
</li> </li>
{{/each}} {{/each}}

View File

@ -15,7 +15,10 @@
</div> </div>
{{> "modules/compendium-browser/template/filter-container.html" filters=spellFilters}} {{> "modules/compendium-browser/template/filter-container.html" filters=spellFilters}}
</div> </div>
<ul id="CBSpells"> <div class="list-area flexcol">
{{> "modules/compendium-browser/template/spell-browser-list.html" spells=items}} <span id="CBSpellsMessage" style="flex:0"></span>
</ul> <ul id="CBSpells">
{{> "modules/compendium-browser/template/spell-browser-list.html" spells=items}}
</ul>
</div>
</div> </div>