diff --git a/templates/base.html b/templates/base.html index 1aae139..1ae4d1d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -35,6 +35,7 @@ var themes = {{ themes }}; {% include 'js/buildTagAndFeatureSelectionDivs.js' %} {% include 'js/buildSelectionMenu.js' %} {% include 'js/buildThemeTableRow.js' %} +{% include 'js/getSortedThemes.js' %} {% include 'js/buildPage.js' %} {% include 'js/selectionMenuCollapse.js' %} diff --git a/templates/js/buildButton.js b/templates/js/buildButton.js index 3e2b8eb..a1a7acf 100644 --- a/templates/js/buildButton.js +++ b/templates/js/buildButton.js @@ -14,7 +14,7 @@ function buildRadioButton( result.style.margin = ".5rem"; let inputAttsA = `id=${inputID} type="radio" name=${inputName} value=${inputValue}`; - let inputAttsB = `onclick="buildResults()" style="margin:0 1rem 0 0"`; + let inputAttsB = `onclick="buildResults()" style="margin:0 1rem 0 0" class=${inputName}`; let inputAttsC = sortedBy === sortedBySelector ? " checked" : ""; let resultButtonInput = ``; diff --git a/templates/js/buildPage.js b/templates/js/buildPage.js index 4f6321f..6354b47 100644 --- a/templates/js/buildPage.js +++ b/templates/js/buildPage.js @@ -1,17 +1,12 @@ function getSortBy() { - let sortByLastCommitInput = document.getElementById("sortByDate"); - if (sortByLastCommitInput === null) { - return "date"; + let a = document.getElementsByClassName("sortBy"); + if (a.length > 0) { + return [ + ...[...a].filter((y) => y.checked).map((x) => x.value), + ...[...a].filter((y) => !y.checked).map((x) => x.value), + ]; } else { - return sortByLastCommitInput.checked ? "date" : "stars"; - } -} - -function getSortedThemes(themeList, sortedBy) { - if (sortedBy === "date") { - return themeList.sort((a, b) => b.date_in_seconds - a.date_in_seconds); - } else { - return themeList.sort((a, b) => b.num_stars - a.num_stars); + return ["date", "stars", "name", "minVer", "license"]; } } @@ -118,14 +113,15 @@ function buildResults() { let selectedTags = getSelectedTags(); let selectedFeatures = getSelectedFeatures(); let sortedBy = getSortBy(); - let filtered_themes = getFilteredThemes(selectedTags, selectedFeatures); - let sorted_themes = getSortedThemes(filtered_themes, sortedBy); + // let filtered_themes = getFilteredThemes(selectedTags, selectedFeatures); + let sorted_themes = getFilteredThemes(selectedTags, selectedFeatures); + sortThemes(sorted_themes, sortedBy); sorted_themes.forEach((theme) => addThemeTableRow(theme, selectedColumns)); // from buildSelectionMenu.js buildSelectionMenu( (sorted_themes = sorted_themes), - (sortedBy = sortedBy), + (sortBy = sortedBy), (selectedTags = selectedTags), (selectedFeatures = selectedFeatures), (selectedColumns = selectedColumns), diff --git a/templates/js/buildSelectionMenu.js b/templates/js/buildSelectionMenu.js index f43b4ce..67dee4f 100644 --- a/templates/js/buildSelectionMenu.js +++ b/templates/js/buildSelectionMenu.js @@ -57,7 +57,7 @@ function buildColumnSelectionDiv(selectedColumns, dState, eParent) { // called from buildPage.js function buildSelectionMenu( sorted_themes, - sortedBy, + sortBy, selectedTags, selectedFeatures, selectedColumns, @@ -73,7 +73,7 @@ function buildSelectionMenu( let availableFeatures = getAvailableFeatures(sorted_themes, featureSortBy); // from buildSortByDiv.js - buildSortByDiv(sortedBy, dState.sortByRow); + buildSortByDiv((sortedBy = sortBy), (sortByRowDisplay = dState.sortByRow)); buildColumnSelectionDiv( (selectedColumns = selectedColumns), diff --git a/templates/js/buildSortByDiv.js b/templates/js/buildSortByDiv.js index 5b3e316..bf11f27 100644 --- a/templates/js/buildSortByDiv.js +++ b/templates/js/buildSortByDiv.js @@ -1,14 +1,15 @@ // called from buildSelectionMenu.js -function buildSortByDiv(sortedBy, sortByRowDisplay) { +function buildSortByDiv(sortBy, sortByRowDisplay) { let menuDiv = document.getElementById("selection-menu"); menuDiv.innerHTML = ""; menuDiv.style.maxWidth = "100%"; let sortByRow = document.createElement("div"); sortByRow.id = "sortByRow"; - sortByRow.style.width = "500px"; + // sortByRow.style.width = "500px"; sortByRow.style.maxWidth = "100%"; sortByRow.style.display = sortByRowDisplay; + sortByRow.style.flexWrap = "wrap"; sortByRow.style.justifyContent = "space-around"; sortByRow.style.margin = "1rem auto 1rem auto"; @@ -18,28 +19,88 @@ function buildSortByDiv(sortedBy, sortByRowDisplay) { sortByPrompt.innerHTML = "Sort By:"; sortByRow.appendChild(sortByPrompt); + // from buildButton.js let sortByStarsButton = buildRadioButton( (inputID = "sortByStars"), (inputName = "sortBy"), (inputValue = "stars"), - (sortedBy = sortedBy), + (sortedBy = sortBy[0]), (sortedBySelector = "stars"), (labelText = "Stars") ); + // from buildButton.js let sortByLastCommitButton = buildRadioButton( (inputID = "sortByDate"), (inputName = "sortBy"), (inputValue = "date"), - (sortedBy = sortedBy), + (sortedBy = sortBy[0]), (sortedBySelector = "date"), (labelText = "Latest Commit Date") ); - sortByRow.appendChild(sortByStarsButton); - sortByRow.appendChild(sortByLastCommitButton); + // from buildButton.js + let sortByMinVerButton = buildRadioButton( + (inputID = "sortByMinVer"), + (inputName = "sortBy"), + (inputValue = "minVer"), + (sortedBy = sortBy[0]), + (sortedBySelector = "minVer"), + (labelText = "Min Hugo Version") + ); + + // from buildButton.js + let sortByLicenseButton = buildRadioButton( + (inputID = "sortByLicense"), + (inputName = "sortBy"), + (inputValue = "license"), + (sortedBy = sortBy[0]), + (sortedBySelector = "license"), + (labelText = "License") + ); + + // from buildButton.js + let sortByNameButton = buildRadioButton( + (inputID = "sortByName"), + (inputName = "sortBy"), + (inputValue = "name"), + (sortedBy = sortBy[0]), + (sortedBySelector = "name"), + (labelText = "Name") + ); + + sortBy.forEach((x) => { + if (x === "date") { + sortByRow.appendChild(sortByLastCommitButton); + } else if (x === "name") { + sortByRow.appendChild(sortByNameButton); + } else if (x === "minVer") { + sortByRow.appendChild(sortByMinVerButton); + } else if (x === "license") { + sortByRow.appendChild(sortByLicenseButton); + } else if (x === "stars") { + sortByRow.appendChild(sortByStarsButton); + } + }); + menuDiv.appendChild(sortByRow); + let sortByMinVerInput = document.getElementById("sortByMinVer"); + sortByMinVerButton.onclick = function () { + if (!sortByMinVerInput.checked) { + sortByMinVerInput.checked = true; + buildResults(); + } + }; + + let sortByLicenseInput = document.getElementById("sortByLicense"); + sortByLicenseButton.onclick = function () { + if (!sortByLicenseInput.checked) { + sortByLicenseInput.checked = true; + buildResults(); + } + }; + let sortByStarsInput = document.getElementById("sortByStars"); sortByStarsButton.onclick = function () { if (!sortByStarsInput.checked) { @@ -54,4 +115,12 @@ function buildSortByDiv(sortedBy, sortByRowDisplay) { buildResults(); } }; + + let sortByNameInput = document.getElementById("sortByName"); + sortByNameButton.onclick = function () { + if (!sortByNameInput.checked) { + sortByNameInput.checked = true; + buildResults(); + } + }; } diff --git a/templates/js/getSortedThemes.js b/templates/js/getSortedThemes.js new file mode 100644 index 0000000..e186b80 --- /dev/null +++ b/templates/js/getSortedThemes.js @@ -0,0 +1,97 @@ +function dateCompare(x, y) { + let xRay = x.split("-").map((j) => parseInt(j)); + let yRay = y.split("-").map((k) => parseInt(k)); + return xRay[0] > yRay[0] + ? 1 + : xRay[0] < yRay[0] + ? -1 + : xRay[1] > yRay[1] + ? 1 + : xRay[1] < yRay[1] + ? -1 + : xRay[2] > yRay[2] + ? 1 + : xRay[2] < yRay[2] + ? -1 + : 0; +} + +function semVerCompare(y, x) { + let xRay = x.split(".").map((j) => parseInt(j)); + let yRay = y.split(".").map((k) => parseInt(k)); + [xRay, yRay].forEach((i) => { + if (i.length < 1) { + i[0] = 0; + i[1] = 0; + i[2] = 0; + } else if (i.length < 2) { + i[1] = 0; + i[2] = 0; + } else if (i.length < 3) { + i[2] = 0; + } + }); + return xRay[0] > yRay[0] + ? 1 + : xRay[0] < yRay[0] + ? -1 + : xRay[1] > yRay[1] + ? 1 + : xRay[1] < yRay[1] + ? -1 + : xRay[2] > yRay[2] + ? 1 + : xRay[2] < yRay[2] + ? -1 + : 0; +} + +function compareTheme(x, y, sortedBy) { + if (sortedBy[0] === "date") { + let dComp = dateCompare(y.date, x.date); + return dComp === 1 + ? 1 + : dComp === -1 + ? -1 + : sortedBy.length < 2 + ? -1 + : compareTheme(x, y, sortedBy.slice(1)); + } else if (sortedBy[0] === "stars") { + return y.num_stars > x.num_stars + ? 1 + : y.num_stars < x.num_stars + ? -1 + : sortedBy.length < 2 + ? -1 + : compareTheme(x, y, sortedBy.slice(1)); + } else if (sortedBy[0] === "name") { + return x.cname.localeCompare(y.cname) === 1 + ? 1 + : x.cname.localeCompare(y.cname) === -1 + ? -1 + : sortedBy.length < 2 + ? -1 + : compareTheme(x, y, sortedBy.slice(1)); + } else if (sortedBy[0] === "minVer") { + let svComp = semVerCompare(x.min_ver, y.min_ver); + return svComp === 1 + ? 1 + : svComp === -1 + ? -1 + : sortedBy.length < 2 + ? -1 + : compareTheme(x, y, sortedBy.slice(1)); + } else if (sortedBy[0] === "license") { + return x.license.localeCompare(y.license) === 1 + ? 1 + : x.license.localeCompare(y.license) === -1 + ? -1 + : sortedBy.length < 2 + ? -1 + : compareTheme(x, y, sortedBy.slice(1)); + } +} + +function sortThemes(themeList, sortedBy) { + themeList.sort((a, b) => compareTheme(a, b, sortedBy)); +} diff --git a/templates/js/selectionMenuCollapse.js b/templates/js/selectionMenuCollapse.js index dc73bb1..1ff4ffe 100644 --- a/templates/js/selectionMenuCollapse.js +++ b/templates/js/selectionMenuCollapse.js @@ -44,6 +44,7 @@ document.getElementById("plus-button").onclick = function () { document.getElementById("minus-button").onclick = function () { if (areAnyCloseAbleMenusOpen()) { closeMenus(); + showSelectionOptionsButtons(); } else { document.getElementById("selection-options-menu").style.display = "none"; this.style.display = "none";