diff --git a/src/main.rs b/src/main.rs index 0633b74a9..439028ca1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,7 @@ struct Mod { title: String, description: String, keywords: Vec, + versions: Vec, } impl Document for Mod { @@ -45,6 +46,7 @@ impl Document for Mod { pub struct SearchRequest { q: Option, f: Option, + v: Option, } #[post("search")] @@ -79,6 +81,7 @@ fn search(web::Query(info): web::Query) -> Vec { let mut search_query = "".to_string(); let mut filters = "".to_string(); + if let Some(q) = info.q { search_query = q; } @@ -87,6 +90,15 @@ fn search(web::Query(info): web::Query) -> Vec { filters = f; } + if let Some(v) = info.v { + if filters.is_empty() { + filters = v; + } + else { + filters = format!("({}) AND {}", filters, v); + } + } + let mut query = Query::new(&search_query).with_limit(10); if !filters.is_empty() { @@ -129,24 +141,28 @@ async fn main() -> std::io::Result<()> { title: String::from("Magic Mod"), description: String::from("An illustrious magic mod for magical wizards"), keywords: vec![String::from("fabric"), String::from("magic"), String::from("library")], + versions: vec![String::from("1.15.2"), String::from("1.15.1"), String::from("1.15")], }, Mod { mod_id: 1, title: String::from("Tech Mod"), description: String::from("An technological mod for complete NERDS"), keywords: vec![String::from("fabric"), String::from("utility"), String::from("technology")], + versions: vec![String::from("1.14.1"), String::from("1.15.1"), String::from("1.15")], }, Mod { mod_id: 2, title: String::from("Gamer Mod"), description: String::from("A gamer mod to roleplay as if you were an epic gamer person."), - keywords: vec![String::from("cursed"), String::from("adventure"), String::from("forge")] + keywords: vec![String::from("cursed"), String::from("adventure"), String::from("forge")], + versions: vec![String::from("20w20a"), String::from("1.15.1"), String::from("1.15")], }, Mod { mod_id: 3, title: String::from("Adventure Mod"), description: String::from("An epic gamer adventure mod for epic adventure gamers"), - keywords: vec![String::from("decoration"), String::from("utility"), String::from("worldgen")] + keywords: vec![String::from("decoration"), String::from("utility"), String::from("worldgen")], + versions: vec![String::from("1.12.2"), String::from("1.15.1"), String::from("1.15")] }, ], Some("mod_id")).unwrap(); diff --git a/static/css/search.css b/static/css/search.css index 21a69c0d8..3b3c021b7 100644 --- a/static/css/search.css +++ b/static/css/search.css @@ -1,18 +1,96 @@ -.column { - display: flex; - flex-direction: column; - width: 50%; +.clear-button { + margin: 30px auto 0 40px; + height: 33px; + width: 175px; + + background-color: white; + border-radius: 5px; + border: 1px solid darkgrey; } -.categories-flex { - position: sticky; +.versions { + display: flex; + flex-direction: column; width: 25%; } +.version-type { + margin-top: 20px; + margin-left: 40px; + margin-right: auto; +} + +.version-scroll { + height: 400px; + overflow-y: scroll; +} + +.version-type-label { + width: 165px; + height: 25px; + margin-bottom: 0; + padding: 2px 5px; + cursor: pointer; + + font-weight: bold; + color: white; + background-color: black; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.version { + height: 25px; + padding: 2px 5px; + cursor: pointer; + width: 152px; + margin: 0; + + font-weight: bold; + color: black; + background-color: white; + border-bottom: 1px solid darkgrey; + border-top: 1px solid darkgrey; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.left-flex { + display: flex; + flex-direction: column; + width: 25%; +} + +.filters { + margin-top: 30px; + margin-right: 25px; + margin-left: auto; +} + +.filters select { + height: 33px; + width: 175px; + + border-radius: 5px; + padding: 0 24px; + background-color: #ffffff; + background-image: none; + border: 1px solid darkgrey; +} + .categories { - position: relative; - top: 100px; + margin-top: 30px; padding: 5px; + margin-right: 20px; + margin-left: auto; } .categories-label { @@ -29,8 +107,6 @@ padding: 2px 5px; cursor: pointer; width: 165px; - margin-left: auto; - margin-right: 20px; -webkit-touch-callout: none; -webkit-user-select: none; @@ -53,6 +129,12 @@ margin-left: 10px; } +.search-main { + display: flex; + flex-direction: column; + width: 50%; +} + .search-bar { position: -webkit-sticky !important; position: sticky !important; @@ -82,7 +164,7 @@ .results { width: 100%; - margin: auto; + margin: 0 auto; } .result { diff --git a/static/images/icon/downarrow.svg b/static/images/icon/downarrow.svg new file mode 100644 index 000000000..38e48912c --- /dev/null +++ b/static/images/icon/downarrow.svg @@ -0,0 +1,2 @@ + + diff --git a/static/js/search.js b/static/js/search.js index 023011c0b..472138c85 100644 --- a/static/js/search.js +++ b/static/js/search.js @@ -13,6 +13,8 @@ let category_inputs = { "fabric": false, } +let version_inputs = {}; + let resultContainer = document.getElementById("results"); window.onload = function () { @@ -25,6 +27,85 @@ window.onload = function () { category.appendChild(ghost); } + + let releases = document.getElementById("releases"); + let snapshots = document.getElementById("snapshots"); + let archaic = document.getElementById("archaic"); + + let xmlHttp = new XMLHttpRequest(); + + xmlHttp.onreadystatechange = function() { + if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { + let versions = JSON.parse(xmlHttp.responseText); + + for (let version of versions.versions) { + let versionElement = document.createElement('p'); + versionElement.className = "version"; + versionElement.innerHTML = version.id; + versionElement.id = version.id; + versionElement.setAttribute("onclick", "activateVersion(this)"); + + version_inputs[version.id] = false; + + if(version.type === "release") + releases.appendChild(versionElement) + else if (version.type === "snapshot") + snapshots.appendChild(versionElement) + else if (version.type === "old_alpha" || version.type === "old_beta") + archaic.appendChild(versionElement) + else + versionElement.outerHTML = ""; + } + } + } + + xmlHttp.open("GET", "https://launchermeta.mojang.com/mc/game/version_manifest.json", true); + xmlHttp.send(null); +} + +function clearFilters() { + for (let key in category_inputs) { + if (category_inputs.hasOwnProperty(key)) { + if(category_inputs[key]) { + let element = document.getElementById(key); + + element.style.width = "165px"; + element.style.boxShadow = "0 0"; + + document.getElementById(key + "-ghost").className = "category-ghost"; + + category_inputs[key] = false; + } + } + } + + for (let key in version_inputs) { + if (version_inputs.hasOwnProperty(key)) { + if(version_inputs[key]) { + let element = document.getElementById(key); + + element.style.width = "152px"; + element.style.boxShadow = "0 0"; + + version_inputs[key] = false; + } + } + } + + handleSearch(); +} + +function toggleVisibility(e) { + let element = e.parentElement.lastElementChild; + + if (element.style.display === "none") { + element.style.display = "block"; + e.innerHTML = e.innerHTML.replace("+", "-") + } + else { + element.style.display = "none" + e.innerHTML = e.innerHTML.replace("-", "+") + } } function activateCategory(element) { @@ -45,11 +126,26 @@ function activateCategory(element) { handleSearch(); } +function activateVersion(element) { + version_inputs[element.id] = !version_inputs[element.id] + + if (version_inputs[element.id]) { + element.style.width = "142px"; + element.style.boxShadow = "10px 0" + element.style.color; + } else { + element.style.width = "152px"; + element.style.boxShadow = "0 0"; + } + + handleSearch(); +} + function handleSearch() { let safeName = encodeURIComponent(input.value).replace(/%20/g,'+'); let queryString = "search?q=" + safeName; let filterString = ""; + let versionString = ""; for (let key in category_inputs) { if (category_inputs.hasOwnProperty(key)) { @@ -59,13 +155,27 @@ function handleSearch() { } } - let takeOffLength = " AND keywords=".length; + let filterTakeOffLength = " AND keywords=".length; - if(filterString.length > takeOffLength) { - filterString = filterString.substring(0, filterString.length - takeOffLength) + if(filterString.length > filterTakeOffLength) { + filterString = filterString.substring(0, filterString.length - filterTakeOffLength) queryString += "&f=" + encodeURIComponent( "keywords=" + filterString).replace(/%20/g,'+'); } + for (let key in version_inputs) { + if (version_inputs.hasOwnProperty(key)) { + if(version_inputs[key]) + versionString += key + " OR versions="; + } + } + + let versionTakeOffLength = " OR versions=".length; + + if(versionString.length > versionTakeOffLength) { + versionString = versionString.substring(0, versionString.length - versionTakeOffLength) + queryString += "&v=" + encodeURIComponent( "versions=" + versionString).replace(/%20/g,'+'); + } + let xmlHttp = new XMLHttpRequest(); xmlHttp.onreadystatechange = function() { diff --git a/templates/search.hbs b/templates/search.hbs index ae51231a2..9dcf91178 100644 --- a/templates/search.hbs +++ b/templates/search.hbs @@ -26,10 +26,19 @@
@@ -67,18 +76,6 @@

CURSED

{{/contains}} - {{#contains this.keywords "forge"}} -
- forge -

FORGE

-
- {{/contains}} - {{#contains this.keywords "fabric"}} -
- fabric -

FABRIC

-
- {{/contains}} {{/each}}