Skip to content

Commit

Permalink
Sorting category upgrade + fix for issue #68 (#72)
Browse files Browse the repository at this point in the history
* Category retrieval has changed

* Adding security when sorting articles (title may be null)

* Takin into accout Gorkam tips

* reviews
  • Loading branch information
adrien-schiehle authored Sep 9, 2023
1 parent 2e1f592 commit 12ca12c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 32 deletions.
64 changes: 37 additions & 27 deletions module/framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,10 @@ async function _getCategories({cache=true}={}) {
id: CATEGORY_ID.root,
title: `[WA] ${anvil.world.name}`,
position: 0,
copyForSort: [],
articles: [],
articleIds: [],
children: [],
childrenIds: [],
folder: null
};
categories.set(root.id, root);
Expand All @@ -576,42 +578,50 @@ async function _getCategories({cache=true}={}) {
id: CATEGORY_ID.uncategorized,
title: game.i18n.localize('WA.CategoryUncategorized'),
position: 9e9,
copyForSort: [],
children : [],
parent: root,
articles: [],
articleIds: [],
children: [],
childrenIds: [],
isUncategorized: true
};
categories.set(uncategorized.id, uncategorized);

// Retrieve categories from the World Anvil API (build map)
const request = await anvil.getCategories();
for ( let c of (request?.categories || []) ) {

// First loop : Store in map
const reqCategories = (request?.categories || []);
for ( let c of reqCategories ) {
categories.set(c.id, c);
c.copyForSort = c.children?.categories ?? [];
c.children = [];
c.parentCategoryId = c.parent?.id;
c.parent = undefined;
c.folder = undefined;
}
// Append children
for( let c of (request?.categories || []) ) {
const parentId = c.parentCategoryId ?? CATEGORY_ID.root;
const parent = categories.get(parentId) ?? root;
c.parent = parent;
parent.children.push(c);
}
// Sort children
for( let c of categories.values() ) {

c.children.sort( (a,b) => {
const indexA = c.copyForSort.findIndex( cc => cc.id === a.id );
const indexB = c.copyForSort.findIndex( cc => cc.id === b.id );
const substr = indexA - indexB;
if( substr != 0 ) { return substr; }
return a.title.localeCompare(b.title);

// Second loop : Add id listings and set category.children
for ( let c of reqCategories ) {
c.articleIds = (c.articles ?? []).map( a => a.id );
c.childrenIds = (c.children ?? []).map( ch => ch.id );
c.articles = [];
c.children = c.childrenIds.map( id => {
const child = categories.get(id);
child.parent = c;
return child;
});
c.copyForSort = undefined;
}

// Third loop : Put the ones without parent as root children
root.children = reqCategories.filter( c => {
if ( c.parent ) return false;
c.parent = root;
return true;
});

root.children.sort( (a,b) => {
const titleA = a.title ?? "";
const titleB = b.title ?? "";
return titleA.localeCompare(titleB);
});

// Add uncategorized on last place
uncategorized.parent = root;
root.children.push(uncategorized);

return categories;
Expand Down
45 changes: 40 additions & 5 deletions module/journal.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export default class WorldAnvilBrowser extends Application {
*/
categories;

/**
* On first init, close subcategories
* @type {boolean}
*/
#firstInit = true;

/**
* Flag whether to display draft articles
* @type {boolean}
Expand Down Expand Up @@ -73,6 +79,7 @@ export default class WorldAnvilBrowser extends Application {
async getData() {
const world = this.anvil.world || await this.anvil.getWorld(this.anvil.worldId);
const tree = await this.getContentTree();
this._refreshCategoryVisibility();
return {
world: world,
tree: tree,
Expand All @@ -99,6 +106,7 @@ export default class WorldAnvilBrowser extends Application {
// Reset status of each category
for ( let category of categories.values() ) {
category.articles = [];
category.unsortedArticles = [];
}
const uncategorized = categories.get( CATEGORY_ID.uncategorized );

Expand All @@ -116,16 +124,25 @@ export default class WorldAnvilBrowser extends Application {

// Get the category to which the article belongs
const category = categories.get(article.category?.id) || uncategorized;
category.articles.push(article);
category.unsortedArticles.push(article);
}

// Sort articles within each category
for ( let category of categories.values() ) {
category.articles.sort( (a,b) => a.title.localeCompare(b.title) );
category.articles = category.articleIds.reduce( (_articles, id) => {
const unsorted = category.unsortedArticles.find( a => a.id === id );
return unsorted ? [..._articles, unsorted] : _articles;
}, []);

// Some may not be referenced (created after)
const unreferencedArticles = category.unsortedArticles.filter(a => !category.articles.find( a2 => a == a2) );
unreferencedArticles.sort( (a,b) => {
const titleA = a.title ?? "";
const titleB = b.title ?? "";
return titleA.localeCompare(titleB);
});
category.articles.push(...unreferencedArticles);
}

// Add empty attribute on categories.
this._calculateCategoryVisibility(tree);
return contentTree;
}

Expand Down Expand Up @@ -396,6 +413,24 @@ export default class WorldAnvilBrowser extends Application {

/* -------------------------------------------- */

/**
* Calls ._calculateCategoryVisibility
* On first call will init ._collapsedCategories before calling it.
*/
_refreshCategoryVisibility() {
if(this.#firstInit) {
const firstLevelsIds = this.tree.children.map( c => c.id );
firstLevelsIds.push(CATEGORY_ID.root);

this._collapsedCategories = [];
for ( const category of this.categories.values() ) {
if ( !firstLevelsIds.includes(category.id ) ) this._collapsedCategories.push(category.id);
}
}
this._calculateCategoryVisibility(this.tree);
this.#firstInit = false;
}

/**
* Recursive
* Set .displayVisibilityButtons, .visibleByPlayers, .hasChildrenWithContent, .hasContent
Expand Down

0 comments on commit 12ca12c

Please sign in to comment.