diff --git a/pointercrate-demonlist-pages/static/js/modules/statsviewer.js b/pointercrate-demonlist-pages/static/js/modules/statsviewer.js index 4041da583..1e86d4bd1 100644 --- a/pointercrate-demonlist-pages/static/js/modules/statsviewer.js +++ b/pointercrate-demonlist-pages/static/js/modules/statsviewer.js @@ -65,11 +65,11 @@ export class StatsViewer extends FilteredPaginator { }); } - let demonSortingModeDropdown = new Dropdown( + this.demonSortingModeDropdown = new Dropdown( document.getElementById("demon-sorting-mode-dropdown") ); - demonSortingModeDropdown.addEventListener((selected) => { + this.demonSortingModeDropdown.addEventListener((selected) => { window.localStorage.setItem("demon_sorting_mode", selected); if (selected === "Alphabetical") { @@ -87,7 +87,7 @@ export class StatsViewer extends FilteredPaginator { } }); - demonSortingModeDropdown.select( + this.demonSortingModeDropdown.select( localStorage.getItem("demon_sorting_mode") ?? "Alphabetical", true ); // default to alphabetical @@ -182,6 +182,35 @@ export class StatsViewer extends FilteredPaginator { return element; } + + /** + * Sort demons by the selected sorting option + * @param {string} sortOption - The sorting option ("Alphabetical" or "Position") + * @param data - Demon data to sort + * @returns Sorted data + */ + sortStatsViewerRow(sortOption, data) { + if (sortOption === "Alphabetical") { + data.sort((r1, r2) => { + if (r1.demon) { + return r1.demon.name.localeCompare(r2.demon.name) + } else { + // nation unbeaten section does not have "demon" key + return r1.name.localeCompare(r2.name) + } + }); + } else if (sortOption === "Position") { + data.sort((r1, r2) => { + if (r1.demon) { + return r1.demon.position - r2.demon.position + } else { + // nation unbeaten section does not have "demon" key + return r1.position - r2.position + } + }); + } + return data; + } } export function formatInto(parent, childs) { diff --git a/pointercrate-demonlist-pages/static/js/statsviewer/individual.js b/pointercrate-demonlist-pages/static/js/statsviewer/individual.js index 8716c479c..f1d103081 100644 --- a/pointercrate-demonlist-pages/static/js/statsviewer/individual.js +++ b/pointercrate-demonlist-pages/static/js/statsviewer/individual.js @@ -25,9 +25,11 @@ class IndividualStatsViewer extends StatsViewer { this.setName(playerData.name, playerData.nationality); - this.formatDemonsInto(this._created, playerData.created); - this.formatDemonsInto(this._published, playerData.published); - this.formatDemonsInto(this._verified, playerData.verified); + const selectedSort = this.demonSortingModeDropdown.selected + + this.formatDemonsInto(this._created, this.sortStatsViewerRow(selectedSort, playerData.created)); + this.formatDemonsInto(this._published, this.sortStatsViewerRow(selectedSort, playerData.published)); + this.formatDemonsInto(this._verified, this.sortStatsViewerRow(selectedSort, playerData.verified)); let beaten = playerData.records.filter((record) => record.progress === 100); @@ -80,10 +82,16 @@ class IndividualStatsViewer extends StatsViewer { this.setHardest(hardest.name === "None" ? undefined : hardest); let non100Records = playerData.records - .filter((record) => record.progress !== 100) - .sort((r1, r2) => r1.progress - r2.progress); + .filter((record) => record.progress !== 100); + + this.formatRecordsInto(this._progress, this.sortStatsViewerRow(selectedSort, non100Records)); - this.formatRecordsInto(this._progress, non100Records); + this.demonSortingModeDropdown.addEventListener((selected) => { + this.formatDemonsInto(this._created, this.sortStatsViewerRow(selected, playerData.created)) + this.formatDemonsInto(this._published, this.sortStatsViewerRow(selected, playerData.published)) + this.formatDemonsInto(this._verified, this.sortStatsViewerRow(selected, playerData.verified)) + this.formatRecordsInto(this._progress, this.sortStatsViewerRow(selected, non100Records)) + }); } formatDemonsInto(element, demons) { diff --git a/pointercrate-demonlist-pages/static/js/statsviewer/nation.js b/pointercrate-demonlist-pages/static/js/statsviewer/nation.js index 99954a8bd..b9496555e 100644 --- a/pointercrate-demonlist-pages/static/js/statsviewer/nation.js +++ b/pointercrate-demonlist-pages/static/js/statsviewer/nation.js @@ -23,6 +23,8 @@ class NationStatsViewer extends StatsViewer { let nationData = response.data.data; + let selectedSort = this.demonSortingModeDropdown.selected; + this.setName(nationData.nation, nationData); let beaten = []; @@ -105,23 +107,18 @@ class NationStatsViewer extends StatsViewer { .map((record) => this.formatDemonFromRecord(record, true)) ); - nationData.unbeaten.sort((r1, r2) => r1.name.localeCompare(r2.name)); - progress.sort((r1, r2) => r2.progress - r1.progress); - nationData.created.sort((r1, r2) => - r1.demon.name.localeCompare(r2.demon.name) - ); formatInto( this._unbeaten, - nationData.unbeaten.map((demon) => this.formatDemon(demon)) + this.sortStatsViewerRow(selectedSort, nationData.unbeaten).map((demon) => this.formatDemon(demon)) ); formatInto( this._progress, - progress.map((record) => this.formatDemonFromRecord(record)) + this.sortStatsViewerRow(selectedSort, progress).map((record) => this.formatDemonFromRecord(record)) ); formatInto( this._created, - nationData.created.map((creation) => { + this.sortStatsViewerRow(selectedSort, nationData.created).map((creation) => { return this.makeTooltip( this.formatDemon(creation.demon), "(Co)created by " + @@ -135,7 +132,7 @@ class NationStatsViewer extends StatsViewer { ); formatInto( this._verified, - nationData.verified.map((verification) => { + this.sortStatsViewerRow(selectedSort, nationData.verified).map((verification) => { return this.makeTooltip( this.formatDemon(verification.demon), "Verified by: ", @@ -145,7 +142,7 @@ class NationStatsViewer extends StatsViewer { ); formatInto( this._published, - nationData.published.map((publication) => { + this.sortStatsViewerRow(selectedSort, nationData.published).map((publication) => { return this.makeTooltip( this.formatDemon(publication.demon), "Published by: ", @@ -153,6 +150,46 @@ class NationStatsViewer extends StatsViewer { ); }) ); + + this.demonSortingModeDropdown.addEventListener((selected) => { + if (nationData.created.length > 0) { + formatInto(this._created, this.sortStatsViewerRow(selected, nationData.created).map((creation) => { + return this.makeTooltip( + this.formatDemon(creation.demon), + "(Co)created by " + + creation.players.length + + " player" + + (creation.players.length === 1 ? "" : "s") + + " in this country: ", + creation.players.join(", ") + ); + })); + } + + if (nationData.published.length > 0) { + formatInto(this._published, this.sortStatsViewerRow(selected, nationData.published).map((publication) => { + return this.makeTooltip( + this.formatDemon(publication.demon), + "Published by: ", + publication.players.join(", ") + ); + })); + } + if (nationData.verified.length > 0) { + formatInto(this._verified, this.sortStatsViewerRow(selected, nationData.verified).map((verification) => { + return this.makeTooltip( + this.formatDemon(verification.demon), + "Verified by: ", + verification.players.join(", ") + ); + })); + } + if (progress.length > 0) + formatInto(this._progress, this.sortStatsViewerRow(selected, progress).map((record) => this.formatDemonFromRecord(record))); + + if (nationData.unbeaten.length > 0) + formatInto(this._unbeaten, this.sortStatsViewerRow(selected, nationData.unbeaten).map((demon) => this.formatDemon(demon))); + }); } makeTooltip(hoverElement, title, content) {