From 6c8b635c2a770ef5062c8ddfd1320d909cd7dbe1 Mon Sep 17 00:00:00 2001 From: Bui Date: Fri, 25 Feb 2022 18:16:11 +0000 Subject: [PATCH] implement song search --- public/assets/img/bg_search.png | Bin 0 -> 598 bytes public/assets/img/crown.png | Bin 0 -> 584 bytes public/assets/img/img.css | 14 ++ public/assets/img/miss.png | Bin 0 -> 714 bytes public/src/css/search.css | 248 ++++++++++++++++++++ public/src/js/assets.js | 11 +- public/src/js/songselect.js | 396 +++++++++++++++++++++++++++++++- public/src/js/strings.js | 35 +++ public/src/views/search.html | 9 + 9 files changed, 707 insertions(+), 6 deletions(-) create mode 100644 public/assets/img/bg_search.png create mode 100644 public/assets/img/crown.png create mode 100644 public/assets/img/miss.png create mode 100644 public/src/css/search.css create mode 100644 public/src/views/search.html diff --git a/public/assets/img/bg_search.png b/public/assets/img/bg_search.png new file mode 100644 index 0000000000000000000000000000000000000000..5878cb8a66a47e1af3f963a69eb8c42486310c74 GIT binary patch literal 598 zcmeAS@N?(olHy`uVBq!ia0vp^IzX(;!3HF+-soJyz`)p&>FgZf>FlgfP?VpRnUl)E zpfRy_qOHea2brVs!Aq5<@|6V?o(Pz`rlZTkOSC&-;TF-TQiGjexM!KDXzKMfWgk4) ze{@xI_vUqc>zWjPFg|+mWXTI9)qnb$TRJ{I*dhP^o$b4Oj82OWg>24d3NStGaWpx} zY`Yd)oMM82Vu!@^87tK+uZBMR`mLF$0imTK;+4bg=^z%iBna=Y_&%9z&I3q%*Y{Q*{Yf@GmxqL*>^{Phv ziCt?7?mb!)mbIqT|KFj6xM5(ej@)Wnk16ovB4k_-iRPv3y> zMm}+%A_q?w$B>A_Z_gR>G8k|$7#w(<_h&VOB)8}41(xg8`BqxEMc@HHcC!{FgZf>FlgfP?VpRnUl)E zpfRy_qOHea2brVs!Aq5<@|6V?o(Pz`rlZTkOSC&-;TF-TQiGjexM!KDXzKMfWgk4) ze{@xI_vUqc>zWjPFg|+mWXTI9)qnb$TRJ{I*dhP^o$b4Oj82OWg>24d3NStGaWpx} zY`Yd)oMM82Vu!@^87tK+uZBMR`mLF$0imTK;+4bg=^z%iBna=Y_&%9z&I3q%*Y{Q*{Yf@GmxqL*>^{Phv ziCt?7?mb!)mbIqT|KFj6xMDA;}Wgh!W@g+}zZ>5(ej@)Wnk16ovB4k_-iRPv3y> zMm}+%A|p>1$B>F!Zx0$W0(plPeD!~u%Dn){#0l~WUNJCkieUN&QsL?9=d#Wzp$Pyt CRpqb% literal 0 HcmV?d00001 diff --git a/public/assets/img/img.css b/public/assets/img/img.css index 2a79238..2f3b5c7 100644 --- a/public/assets/img/img.css +++ b/public/assets/img/img.css @@ -23,3 +23,17 @@ #gamepad-buttons{ background-image: url("settings_gamepad.png"); } +#song-search{ + background: linear-gradient(to top, rgb(245 246 252 / 8%), #ff5963), url("bg_search.png"); + background-size: 3.12vmax; + background-position: -1.2vmax; +} +.song-search-result-course::before{ + background-image: url("difficulty.png"); +} +.song-search-result-crown{ + background-image: url("crown.png"); +} +.song-search-tip-error{ + background-image: url("miss.png"); +} diff --git a/public/assets/img/miss.png b/public/assets/img/miss.png new file mode 100644 index 0000000000000000000000000000000000000000..f6d0ec3af1cf091eb2ffa912f43719b585fdada0 GIT binary patch literal 714 zcmeAS@N?(olHy`uVBq!ia0vp^CqbBl4M=t#6JupyU~I{Bb`J1#c2+1T%1_J8No8Qr zm{>c}*5j~)%+dJZrAkxz$^r^c1k7F2(PiN!+MTd)i)d7-!Okz-vrJSp_4=B!4<774 zx~jQ*^E$qDO$t94AH8_83r^SatHfJ*hn4b1Hnw(^| zU5hPFF+o7FLt^@jmFkzeB`f;YSO54?CH^$>-t&JlwO;p98vIq}CGScU%ojMH6J_Ik24&_RqCGXdh<#8`J%&2=Xs=OUa={h5usDI;m*M|DJza#J|gIPRU`hy zt~CYs9<2$>T2t!(?@&Tqv}f_$X9kZVoR~acdARYWh9oF@t#<3`6nT5x=8toqy{F#H zm{fxzodsN?lOD7GZ@zzbR_jVnb4>~6UGX`;lUX?4FrD3%TQ7gR>@&*;d*<+{+wr*! zo98dNemm+32S+Zm`1M@hd(3*}4UOutMk?-~E{kxnKKR?SPm}%2eWtzHdHHK==h!hw zzRLQ^W?{kN);(qKyN~bYoxAtX_VTOu?7Myx9qBr)FbfzhoCO|{#S9F3${@^GvDCf{ zD9B#o>Fdh=j7d_6#k4FnA1KctS>hT|;+&tGo0?a`;9QiNSdyBeP@Y+mq2TW68xY>e zCk|A!#nZ(xq~g}wgN;BA!{G%#gX14EgffCSgB46?tk7m){J(>B2FQh;u6{1-oD!M< D^T_4E literal 0 HcmV?d00001 diff --git a/public/src/css/search.css b/public/src/css/search.css new file mode 100644 index 0000000..7a6018e --- /dev/null +++ b/public/src/css/search.css @@ -0,0 +1,248 @@ +#song-search-container { + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,0.5); + z-index: 2; +} + +#song-search { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: auto; + display: flex; + flex-direction: column; + width: 60vmax; + height: 80vmin; + border-radius: 0.8vmax; + border: 0.35vmax solid #8C0C42; + color: #fff; + padding: 1vmax 1vmax 0 1vmax; + z-index: 1; +} + +#song-search-input { + width: 100%; + font-size: 2vmax; + padding: 0.8vmax 1.2vmax; + border-radius: 0.3vmax; + border: 0.25vmax black solid; + font-family: TnT; + box-sizing: border-box; + -webkit-box-sizing:border-box; + -moz-box-sizing: border-box; + outline: none; +} + +#song-search-input:focus { + border: 0.25vmax #fff923 solid; +} + +#song-search-results { + margin-top: 0.5vmax; + overflow-y: scroll; + -ms-overflow-style: none; + scrollbar-width: none; + scroll-behavior: smooth; +} + +#song-search-results::-webkit-scrollbar { + display: none; +} + +.song-search-result { + display: flex; + height: 3.2vmax; + margin: 0.2vmax; + padding: 0.7vmax; + flex-direction: row; + text-align: center; + align-items: center; + justify-content: center; + border: 0.3vmax black solid; + position: relative; +} + +.song-search-result::before { + display: block; + position: absolute; + content: ''; + height: 100%; + width: 100%; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +.song-search-result:last-of-type { + margin-bottom: 1vmax; +} + +.song-search-result-info { + flex: 10; + font-size: 1.2vmax; + margin: 0.3vmax; + text-align: left; + z-index: 0; + position: relative; + white-space: nowrap; + padding-left: 0.2vmax; + overflow-x: clip; +} + +.song-search-result-subtitle { + display: block; + font-size: 0.8vmax; + margin-top: 0.5vmax; +} + +.song-search-result-title::before, +.song-search-result-subtitle::before { + content: attr(alt); + position: absolute; + z-index: -1; +} + +.song-search-result-course { + flex: 1; + width: 100%; + height: 100%; + margin: 0.2vmax; + font-size: 1.2vmax; + border-radius: 0.3vmax; + position: relative; + z-index: 1; +} + +.song-search-result-hidden { + visibility: hidden; +} + +.song-search-result:hover { + border-color: #fff923; + cursor: pointer; +} + +.song-search-result-active { + border-color: #fff923; +} + +.song-search-result-course::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.5; + z-index: -1; + background-size: 6vmax; + border-radius: 0.3vmax; +} + +.song-search-result-stars { + bottom: 0; + background: rgb(0 0 0 / 47%); + position: absolute; + width: 100%; + padding: 0.1vmax 0; + border-radius: 0 0 0.3vmax 0.3vmax; +} + +.song-search-result-easy { + background-color: #D13215; +} + +.song-search-result-easy::before { + background-position-x: -1.1vmax; + background-position-y: -0.7vmax; +} + +.song-search-result-normal { + background-color: #799C22; +} + +.song-search-result-normal::before { + background-position-x: -1.2vmax; + background-position-y: -6.4vmax; +} + +.song-search-result-hard { + background-color: #31799B; +} + +.song-search-result-hard::before { + background-position-x: -1.1vmax; + background-position-y: -11.4vmax; +} + +.song-search-result-oni { + background-color: #AF2C7F; +} + +.song-search-result-oni::before { + background-position-x: -1.2vmax; + background-position-y: -16.5vmax; +} + +.song-search-result-ura { + background-color: #604AD5; +} + +.song-search-result-ura::before { + background-position-x: -1.2vmax; + background-position-y: -21.6vmax; +} + +.song-search-result-crown { + background-size: 1.9vmax; + background-position-x: 0.82vmax; + background-repeat: repeat-y; + width: 100%; + position: absolute; + height: 2vmax; +} + +.song-search-result-gold { + background-position-y: 5.15vmax; +} + +.song-search-result-silver { + background-position-y: 7.6vmax; +} + +.song-search-result-noclear { + background-position-y: 0.15vmax; +} + +#song-search-tip { + font-size: 1vmax; + margin-top: 1vmax; + text-align: center; + background-repeat: no-repeat; + background-position: top; + background-size: 10vmax; + background-color: #00000087; + border-radius: 0.5vmax; + padding: 1vmax; +} + +#song-search-close { + position: absolute; + right: -0.77vmax; + top: -1.26vmax; + font-size: 2vmax; + font-family: TnT; + cursor: pointer; +} + +.song-search-tip-error { + height: 8vmax; +} diff --git a/public/src/js/assets.js b/public/src/js/assets.js index ac246ba..27503ac 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -46,7 +46,8 @@ var assets = { "game.css", "debug.css", "songbg.css", - "view.css" + "view.css", + "search.css" ], "assetsCss": [ "img/img.css" @@ -92,7 +93,10 @@ var assets = { "results_mikoshi.png", "results_tetsuohana.png", "results_tetsuohana2.png", - "settings_gamepad.png" + "settings_gamepad.png", + "crown.png", + "miss.png", + "bg_search.png" ], "audioSfx": [ "se_pause.ogg", @@ -149,7 +153,8 @@ var assets = { "settings.html", "account.html", "login.html", - "customsongs.html" + "customsongs.html", + "search.html" ], "songs": [], diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js index 0352884..ad80e89 100644 --- a/public/src/js/songselect.js +++ b/public/src/js/songselect.js @@ -34,6 +34,12 @@ class SongSelect{ border: ["#ffdfff", "#b068b2"], outline: "#b221bb" }, + "search": { + sort: 0, + background: "#FF5266", + border: ["#FF9FB7", "#BE1432"], + outline: "#A50B15" + }, "tutorial": { sort: 0, background: "#29e8aa", @@ -85,6 +91,16 @@ class SongSelect{ } this.songSkin["default"].sort = songSkinLength + 1 + Object.keys(this.songSkin).forEach(key => { + var skin = this.songSkin[key] + var stripped = key.replace(/\W/g, '') + + document.styleSheets[0].insertRule('.song-search-' + stripped + ' { background-color: ' + skin.background + ' }') + document.styleSheets[0].insertRule('.song-search-' + stripped + '::before { border: 0.4vmax solid ' + skin.border[0] + ' ; border-bottom-color: ' + skin.border[1] + ' ; border-right-color: ' + skin.border[1] + ' }') + document.styleSheets[0].insertRule('.song-search-' + stripped + ' .song-search-result-title::before { -webkit-text-stroke: 0.4em ' + skin.outline + ' }') + document.styleSheets[0].insertRule('.song-search-' + stripped + ' .song-search-result-subtitle::before { -webkit-text-stroke: 0.4em ' + skin.outline + ' }') + }) + this.font = strings.font this.songs = [] @@ -117,6 +133,12 @@ class SongSelect{ category: strings.random, canJump: true }) + this.songs.push({ + title: strings.search.search, + skin: this.songSkin.search, + action: "search", + category: strings.random, + }) } if(touchEnabled){ if(fromTutorial === "tutorial"){ @@ -359,7 +381,12 @@ class SongSelect{ pageEvents.send("song-select-difficulty", this.songs[this.selectedSong]) } } - + + setAltText(element, text){ + element.innerText = text + element.setAttribute("alt", text) + } + keyPress(pressed, name, event, repeat){ if(pressed){ if(!this.pressedKeys[name]){ @@ -380,8 +407,41 @@ class SongSelect{ this.state.showWarning = false this.showWarning = false } + }else if (this.search){ + if(name === "back" || (event && event.code === "KeyF" && ctrl)) { + this.removeSearch(true) + }else if(name === "down"){ + if(this.search.input == document.activeElement && this.search.results){ + this.searchSetActive(0) + }else if(this.search.active === this.search.results.length-1){ + this.searchSetActive(null) + this.search.input.focus() + }else if(this.search.active !== null){ + this.searchSetActive(this.search.active+1) + }else{ + this.searchSetActive(0) + } + }else if(name === "up"){ + if(this.search.input == document.activeElement && this.search.results){ + this.searchSetActive(this.search.results.length-1) + }else if(this.search.active === 0){ + this.searchSetActive(null) + this.search.input.focus() + //this.search.input.setSelectionRange(this.search.input.value.length, this.search.input.value.length) + }else if(this.search.active !== null){ + this.searchSetActive(this.search.active-1) + }else{ + this.searchSetActive(this.search.results.length-1) + } + }else if(name === "confirm"){ + if(this.search.active !== null){ + this.searchProceed(parseInt(this.search.results[this.search.active].dataset.song_id)) + } + } }else if(this.state.screen === "song"){ - if(name === "confirm"){ + if(event && event.code === "KeyF" && ctrl){ + this.displaySearch() + }else if(name === "confirm"){ this.toSelectDifficulty() }else if(name === "back"){ this.toTitleScreen() @@ -528,7 +588,7 @@ class SongSelect{ if(408 < mouse.x && mouse.x < 872 && 470 < mouse.y && mouse.y < 550){ moveTo = "showWarning" } - }else if(this.state.screen === "song"){ + }else if(this.state.screen === "song" && !this.search){ if(20 < mouse.y && mouse.y < 90 && 410 < mouse.x && mouse.x < 880 && (mouse.x < 540 || mouse.x > 750)){ moveTo = mouse.x < 640 ? "categoryPrev" : "categoryNext" }else if(!p2.session && 60 < mouse.x && mouse.x < 332 && 640 < mouse.y && mouse.y < 706 && gameConfig.accounts){ @@ -692,6 +752,7 @@ class SongSelect{ } } }else if(this.state.locked === 0 || fromP2){ + this.removeSearch() if(currentSong.courses){ if(currentSong.unloaded){ return @@ -725,6 +786,8 @@ class SongSelect{ this.moveToSong(moveBy, fromP2) }, 200) pageEvents.send("song-select-random") + }else if(currentSong.action === "search"){ + this.displaySearch(true) }else if(currentSong.action === "tutorial"){ this.toTutorial() }else if(currentSong.action === "about"){ @@ -2607,6 +2670,333 @@ class SongSelect{ } return addedSong } + + createSearchResult(song){ + var title = this.getLocalTitle(song.title, song.title_lang) + var subtitle = this.getLocalTitle(title === song.title ? song.subtitle : "", song.subtitle_lang) + + var strippedCat = "default" + if(song.category_id){ + var cat = assets.categories.find(cat => cat.id === song.category_id) + strippedCat = cat.title.replace(/\W/g, '') + } + + var resultDiv = document.createElement("div") + resultDiv.classList.add("song-search-result", "song-search-" + strippedCat) + resultDiv.dataset.song_id = song.id + + var resultInfoDiv = document.createElement("div") + resultInfoDiv.classList.add("song-search-result-info") + var resultInfoTitle = document.createElement("span") + resultInfoTitle.classList.add("song-search-result-title") + this.setAltText(resultInfoTitle, title) + resultInfoDiv.appendChild(resultInfoTitle) + + if(subtitle){ + var resultInfoSubtitle = document.createElement("span") + resultInfoSubtitle.classList.add("song-search-result-subtitle") + this.setAltText(resultInfoSubtitle, subtitle) + resultInfoDiv.appendChild(resultInfoSubtitle) + } + + resultDiv.appendChild(resultInfoDiv) + + var courses = ["easy", "normal", "hard", "oni", "ura"] + courses.forEach(course => { + var courseDiv = document.createElement("div") + courseDiv.classList.add("song-search-result-course", "song-search-result-" + course) + if (song.courses[course]) { + var crown = "noclear" + if (scoreStorage.scores[song.hash]) { + if (scoreStorage.scores[song.hash][course]) { + crown = scoreStorage.scores[song.hash][course].crown || "noclear" + } + } + var courseCrown = document.createElement("div") + courseCrown.classList.add("song-search-result-crown", "song-search-result-" + crown) + var courseStars = document.createElement("div") + courseStars.classList.add("song-search-result-stars") + courseStars.innerText = song.courses[course].stars + '★' + + courseDiv.appendChild(courseCrown) + courseDiv.appendChild(courseStars) + } else { + courseDiv.classList.add("song-search-result-hidden") + } + + resultDiv.appendChild(courseDiv) + }) + + return resultDiv + } + + searchSetActive(idx){ + this.playSound("se_ka") + var active = this.search.div.querySelector(".song-search-result-active") + if(active){ + active.classList.remove("song-search-result-active") + } + + if(idx === null){ + this.search.active = null + return + } + + var el = this.search.results[idx] + this.search.input.blur() + el.classList.add("song-search-result-active") + el.scrollIntoView(); + + this.search.active = idx + } + + displaySearch(fromButton=false){ + if(this.search){ + return this.removeSearch(true) + } + + this.search = {results: []} + this.search.div = document.createElement("div") + this.search.div.innerHTML = assets.pages["search"] + + pageEvents.add(this.search.div.querySelector("#song-search-container"), + ["mousedown", "touchstart"], this.searchClick.bind(this)) + + this.search.input = this.search.div.querySelector("#song-search-input") + this.search.input.setAttribute("placeholder", strings.search.searchInput) + pageEvents.add(this.search.input, ["input"], this.searchInput.bind(this)) + + this.playSound("se_pause") + loader.screen.appendChild(this.search.div) + this.setSearchTip() + this.search.input.focus() + } + + removeSearch(byUser=false){ + if(this.search){ + if(byUser){ + this.playSound("se_cancel") + } + + pageEvents.remove(this.search.div.querySelector("#song-search-container"), + ["mousedown", "touchstart"]) + pageEvents.remove(this.search.input, ["input"]) + + this.search.div.remove() + delete this.search + } + } + + setSearchTip(tip, error=false){ + if(this.search.tip){ + this.search.tip.remove() + delete this.search.tip + } + + if(!tip){ + tip = strings.search.tip + " " + strings.search.tips[Math.floor(Math.random() * strings.search.tips.length)] + } + + var resultsDiv = this.search.div.querySelector("#song-search-results") + resultsDiv.innerHTML = "" + this.search.results = [] + + this.search.tip = document.createElement("div") + this.search.tip.setAttribute("id", "song-search-tip") + this.search.tip.innerText = tip + this.search.div.querySelector("#song-search").appendChild(this.search.tip) + + if(error){ + this.search.tip.classList.add("song-search-tip-error") + } + } + + parseRange(string){ + var range = string.split("-") + if(range.length == 1){ + return {min: parseInt(range[0]), max: parseInt(range[0])} + } else if(range.length == 2){ + return {min: parseInt(range[0]), max: parseInt(range[1])} + } + } + + performSearch(query){ + var results = [] + var filters = {} + + var querySplit = query.split(" ") + var editedSplit = query.split(" ") + querySplit.forEach(word => { + if(word.length > 0){ + var parts = word.toLowerCase().split(":") + if(parts.length > 1){ + switch(parts[0]){ + case "easy": + case "normal": + case "hard": + case "oni": + case "ura": + filters[parts[0]] = this.parseRange(parts[1]) + break + case "extreme": + filters.oni = this.parseRange(parts[1]) + break + case "clear": + case "silver": + case "gold": + case "genre": + case "lyrics": + case "creative": + case "played": + filters[parts[0]] = parts[1] + break + } + + editedSplit.splice(editedSplit.indexOf(word), 1) + } + } + }) + + query = editedSplit.join(" ") + + var songs = assets.songs + // TODO: fix this so it doesn't suck + songs.sort((a, b) => { + var aScore = 0 + var bScore = 0 + var aTitle = a.title.replace(query, "").length + var bTitle = b.title.replace(query, "").length + var aLength = aTitle - query.length + var bLength = bTitle - query.length + aScore += aLength - bLength + bScore += bLength - aLength + + return aScore - bScore + }) + + assets.songs.forEach(song => { + var passedFilters = 0 + + Object.keys(filters).forEach(filter => { + var value = filters[filter] + switch(filter){ + case "easy": + case "normal": + case "hard": + case "oni": + case "ura": + if(song.courses[filter] && song.courses[filter].stars >= value.min && song.courses[filter].stars <= value.max){ + passedFilters++ + } + break + case "clear": + case "silver": + case "gold": + if(value === "any"){ + var score = scoreStorage.scores[song.hash] + scoreStorage.difficulty.forEach(difficulty => { + if(score && score[difficulty] && score[difficulty].crown && (filter === "clear" || score[difficulty].crown === filter)){ + passedFilters++ + } + }) + } else { + var score = scoreStorage.scores[song.hash] + if(score && score[value] && score[value].crown && (filter === "clear" || score[value].crown === filter)){ + passedFilters++ + } + } + break + case "played": + var score = scoreStorage.scores[song.hash] + if((value === "yes" && score) || (value === "no" && !score)){ + passedFilters++ + } + break + case "lyrics": + if((value === "yes" && song.lyrics) || (value === "no" && !song.lyrics)){ + passedFilters++ + } + break + case "creative": + if((value === "yes" && song.maker) || (value === "no" && !song.maker)){ + passedFilters++ + } + break + case "genre": + var cat = assets.categories.find(cat => cat.id === song.category_id) + var aliases = cat.aliases ? cat.aliases.concat([song.category]) : [song.category] + + if(aliases.find(alias => alias.toLowerCase() === value.toLowerCase())){ + passedFilters++ + } + + break + } + }) + + if(passedFilters === Object.keys(filters).length){ + var title = this.getLocalTitle(song.title, song.title_lang) + var subtitle = this.getLocalTitle(title === song.title ? song.subtitle : "", song.subtitle_lang) + + if(title.toLowerCase().includes(query) || (subtitle && subtitle.toLowerCase().includes(query))){ + results.push(song) + } + } + }) + + results = results.slice(0, 100) + return results + } + + searchInput(e){ + var text = e.target.value.toLowerCase() + + if(text.length === 0){ + this.setSearchTip() + return + } + + var new_results = this.performSearch(text) + + if (new_results.length === 0) { + this.setSearchTip(strings.search.noResults, true) + return + } else if (this.search.tip) { + this.search.tip.remove() + delete this.search.tip + } + + var resultsDiv = this.search.div.querySelector("#song-search-results") + resultsDiv.innerHTML = "" + this.search.results = [] + new_results.forEach(song => { + var result = this.createSearchResult(song) + resultsDiv.appendChild(result) + this.search.results.push(result) + }) + } + + searchClick(e){ + if((e.target.id === "song-search-container" || e.target.id === "song-search-close") && e.which === 1){ + this.removeSearch(true) + }else if(e.which === 1){ + var songEl = e.target.closest(".song-search-result") + if(songEl){ + var songId = parseInt(songEl.dataset.song_id) + this.searchProceed(songId) + } + } + } + + searchProceed(songId){ + var song = this.songs.find(song => song.id === songId) + this.removeSearch() + this.drawBackground(song.originalCategory) + + var songIndex = this.songs.findIndex(song => song.id === songId) + this.selectedSong = songIndex + this.toSelectDifficulty() + } onusers(response){ this.songs.forEach(song => { diff --git a/public/src/js/strings.js b/public/src/js/strings.js index 67feb77..f672b58 100644 --- a/public/src/js/strings.js +++ b/public/src/js/strings.js @@ -1332,6 +1332,41 @@ var translations = { ja: "Ver. %s", en: "Version %s" } + }, + search: { + search: { + ja: "曲を検索", + en: "Search Songs" + }, + searchInput: { + ja: "曲を検索...", + en: "Search for songs..." + }, + noResults: { + ja: "結果は見つかりませんでした。", + en: "No results found." + }, + tip: { + ja: "ヒント:", + en: "Tip:" + }, + tips: { + ja: [ + "CTRL+Fで検索窓を開く!" + ], + en: [ + "Open the search window by pressing CTRL+F!", + "Mix and match as many search filters as you want!", + "Only the 100 most relevant search results are shown.", + "Filter by genre by using the \"genre:\" keyword! (e.g. \"genre:variety\", \"genre:namco\")", + "Use filters like \"oni:10\" to search for songs with a particular difficulty!", + "Difficulty filters support ranges, too! Try \"ura:1-5\"!", + "Want to see your full combos? Try \"gold:any\", \"gold:oni\", etc.!", + "Only want to see creative songs? Use the \"creative:yes\" filter!", + "Find songs with lyrics enabled with the \"lyrics:yes\" filter!", + "Feel like trying something new? Use the \"played:no\" filter to only see songs you haven't played yet!" + ] + } } } var allStrings = {} diff --git a/public/src/views/search.html b/public/src/views/search.html new file mode 100644 index 0000000..fb84198 --- /dev/null +++ b/public/src/views/search.html @@ -0,0 +1,9 @@ +
+ +