diff --git a/src/components/search.js b/src/components/search.js index b74e290..b9c5a47 100644 --- a/src/components/search.js +++ b/src/components/search.js @@ -19,6 +19,10 @@ AFRAME.registerComponent('search', { // Less hits on normal searches. this.queryObject.hitsPerPage = 30; + + this.el.sceneEl.addEventListener('genreclear', () => { + this.search(''); + }); }, superkeyboardchange: bindEvent(function (evt) { @@ -49,6 +53,42 @@ AFRAME.registerComponent('search', { } }); +/** + * Select genre filter. + */ +AFRAME.registerComponent('search-genre', { + init: function () { + this.eventDetail = {isGenreSearch: true, genre: '', results: []}; + this.queryObject = { + filters: '', + hitsPerPage: 100 + }; + + this.el.addEventListener('click', evt => { + this.search(evt.target.closest('.genre').dataset.genre); + }); + }, + + search: function (genre) { + if (genre === 'Video Game') { + this.queryObject.filters = `genre:"Video Game" OR genre:"Video Games"`; + } else { + this.queryObject.filters = `genre:"${genre}"`; + } + algolia.search(this.queryObject, (err, content) => { + if (err) { + this.el.sceneEl.emit('searcherror', null, false); + console.error(err); + return; + } + + this.eventDetail.genre = genre; + this.eventDetail.results = content.hits; + this.el.sceneEl.emit('searchresults', this.eventDetail); + }); + } +}); + /** * Click listener for search result. */ diff --git a/src/constants/genres.js b/src/constants/genres.js new file mode 100644 index 0000000..54335bc --- /dev/null +++ b/src/constants/genres.js @@ -0,0 +1,22 @@ +module.exports = [ + 'Pop', + 'R&B', + 'Rap', + 'Rock', + 'Soundtrack', + 'Video Game', + + 'Electronic', + 'Hip Hop', + 'House', + 'J-Pop', + 'K-Pop', + 'Meme', + + 'Alternative', + 'Anime', + 'Comedy', + 'Disney', + 'Dubstep', + 'EDM' +]; diff --git a/src/state/index.js b/src/state/index.js index 7bd8f53..c63aacb 100644 --- a/src/state/index.js +++ b/src/state/index.js @@ -30,6 +30,8 @@ const DEBUG_CHALLENGE = { * `bind__=": some.item.in.state"` */ AFRAME.registerState({ + nonBindedStateKeys: ['genres'], + initialState: { activeHand: localStorage.getItem('hand') || 'right', challenge: { // Actively playing challenge. @@ -44,6 +46,9 @@ AFRAME.registerState({ songSubName: '' }, damage: 0, + genre: '', + genres: require('../constants/genres'), + genreMenuOpen: false, inVR: false, isGameOver: false, // Game over screen. isPaused: false, // Playing, but paused. Not active during menu. @@ -211,6 +216,18 @@ AFRAME.registerState({ state.challenge.id = ''; }, + genreclear: (state) => { + state.genre = ''; + }, + + genremenuclose: (state) => { + state.genreMenuOpen = false; + }, + + genremenuopen: (state) => { + state.genreMenuOpen = true; + }, + keyboardclose: (state) => { state.isSearching = false; }, @@ -314,7 +331,15 @@ AFRAME.registerState({ challengeDataStore[result.id] = result; } computeSearchPagination(state); - computeMenuSelectedChallengeIndex(state); + + if (payload.isGenreSearch) { + state.genreMenuOpen = false; + state.genre = payload.genre; + state.menuSelectedChallenge.id = ''; + } else { + state.genre = ''; + computeMenuSelectedChallengeIndex(state); + } }, songfetchfinish: (state) => { diff --git a/src/templates/menu.html b/src/templates/menu.html index d6ab115..16ad329 100644 --- a/src/templates/menu.html +++ b/src/templates/menu.html @@ -106,145 +106,169 @@ bind__visible="menuActive" position="0 1.1 -2" visible="false"> - - + - + + - {{ searchResults() }} + - - - + {{ searchResults() }} + + + + + - - - + + - - - - {% raw %} - - {% endraw %} + + + + {% raw %} + + {% endraw %} + - - - + + id="menuSelectedChallengePanel" + bind__visible="!!menuSelectedChallenge.id" + position="0.82 0 0.001"> + - - - - + + + + + + + - + + id="genreMenu" + bind-for="for: genre; in: genres; updateInPlace: true" + bind__visible="genreMenuOpen" + layout="type: box; columns: 6; marginRow: 0.4; marginColumn: 0.4; align: center" + search-genre> + + - + + + + + + + + + + + + + + +