diff --git a/src/components/search.js b/src/components/search.js index 0ece76af..d0533f1e 100644 --- a/src/components/search.js +++ b/src/components/search.js @@ -24,13 +24,14 @@ AFRAME.registerComponent('search', { }, init: function () { - this.eventDetail = { query: '', results: topSearch }; + this.eventDetail = { query: '', results: topSearch, url: '', page: 0 }; this.keyboardEl = document.getElementById('keyboard'); this.popularHits = topSearch; shuffle(this.popularHits); this.queryObject = { hitsPerPage: 0, query: '' }; this.el.sceneEl.addEventListener('searchclear', () => { - this.search('');}); + this.search(''); + }); }, update: function (oldData) { @@ -78,49 +79,75 @@ AFRAME.registerComponent('search', { // Favorites. if (this.data.playlist === 'favorites') { - this.eventDetail.results = JSON.parse(localStorage.getItem('favorites')); + this.eventDetail.results = JSON.parse(localStorage.getItem('favorites-v2')); this.el.sceneEl.emit('searchresults', this.eventDetail); return; } - if (this.data.difficultyFilter || this.data.genre || this.data.playlist) { - filters.length = 0; - - // Difficulty filter. - if (this.data.difficultyFilter && this.data.difficultyFilter !== 'All') { - filters.push(`difficulties:"${this.data.difficultyFilter}"`); - } - - // Genre filter. - if (this.data.genre === 'Video Games') { - filters.push(`genre:"Video Game" OR genre:"Video Games"`); - } else if (this.data.genre) { - filters.push(`genre:"${this.data.genre}"`); - } - - // Playlist filter. - if (this.data.playlist) { - filters.push(`playlists:"${this.data.playlist}"`); - } - - this.queryObject.filters = filters.join(' AND '); + /* if (this.data.difficultyFilter || this.data.genre || this.data.playlist) { + filters.length = 0 + + // Difficulty filter. + if (this.data.difficultyFilter && this.data.difficultyFilter !== 'All') { + filters.push(`difficulties:"${this.data.difficultyFilter}"`) + } + + // Genre filter. + if (this.data.genre === 'Video Games') { + filters.push(`genre:"Video Game" OR genre:"Video Games"`) + } else if (this.data.genre) { + filters.push(`genre:"${this.data.genre}"`) + } + + // Playlist filter. + if (this.data.playlist) { + filters.push(`playlists:"${this.data.playlist}"`) + } + + this.queryObject.filters = filters.join(' AND ') + } else { + delete this.queryObject.filters + } */ + let url = `https://beatsaver.com/api/search/text/CURRENT_PAGE_INDEX?sortOrder=Rating&automapper=true&q=${encodeURIComponent(query)}`; + + if (this.data.genre) { + const genreMap = { + 'Pop': 'pop', + 'R&B': 'rb', + 'Rap': 'hip-hop-rap', + 'Rock': 'rock', + 'Soundtrack': 'tv-movie-soundtrack', + 'Video Games': 'video-game-soundtrack', + 'Electronic': 'electronic', + 'Hip Hop': 'hip-hop-rap', + 'House': 'house', + 'J-Pop': 'j-pop', + 'K-Pop': 'k-pop', + 'Meme': 'comedy-meme', + 'Alternative': 'alternative', + 'Anime': 'anime', + 'Comedy': 'comedy-meme', + 'Dubstep': 'dubstep', + 'Dance': 'dance' + }; + const tag = genreMap[this.data.genre]; + url = `https://beatsaver.com/api/search/text/CURRENT_PAGE_INDEX?sortOrder=Rating&automapper=true&tags=${encodeURIComponent(tag)}`; } else { - delete this.queryObject.filters; + if (query && query.length < 3) { return; } } - if (query && query.length < 3) { return; } - - algolia.search(this.queryObject, (err, content) => { - if (err) { - this.el.sceneEl.emit('searcherror', null, false); - console.error(err); - return; - } + fetch(url.replaceAll('CURRENT_PAGE_INDEX', 0)) + .then(r => { + return r.json();}) + .then(res => { + var hits = res['docs'].map(convertBeatmap); - this.eventDetail.results = content.hits; + this.eventDetail.results = hits; + this.eventDetail.url = url; + this.eventDetail.urlPage = 0; - this.el.sceneEl.emit('searchresults', this.eventDetail); - }); + this.el.sceneEl.emit('searchresults', this.eventDetail); + }); } }); diff --git a/src/components/song-preview.js b/src/components/song-preview.js index e756b8ba..8459d56a 100644 --- a/src/components/song-preview.js +++ b/src/components/song-preview.js @@ -7,43 +7,25 @@ const PREVIEW_VOLUME = 0.5; */ AFRAME.registerComponent('song-preview-system', { schema: { - previewStartTime: { type: 'int' }, - selectedChallengeId: { type: 'string' } + selectedChallengeId: { type: 'string' }, + selectedChallengeVersion: { type: 'string' } }, init: function () { this.audio = document.createElement('audio'); this.audio.volume = PREVIEW_VOLUME; - - function deepGet (obj, properties) { - if (obj === undefined || obj === null) { - return; - } - if (properties.length === 0) { - return obj; - } - var foundSoFar = obj[properties[0]]; - var remainingProperties = properties.slice(1); - return deepGet(foundSoFar, remainingProperties); - } - - this.el.addEventListener('ziploaderend', evt => { - const audioSrc = evt.detail.audio; - this.audio.pause(); - - const data = this.data; - - if (data.selectedChallengeId /* && oldData.selectedChallengeId !== data.selectedChallengeId */) { - this.audio.setAttribute('src', audioSrc); - this.audio.currentTime = deepGet(evt.detail, ['info', '_previewStartTime']) || data.previewStartTime || 12; - this.audio.play(); - } - }); }, update: function (oldData) { const data = this.data; - if (!data.selectedChallengeId || oldData.selectedChallengeId !== data.selectedChallengeId) { + console.log('update-song', oldData, data); + + if (data.selectedChallengeId && oldData.selectedChallengeId !== data.selectedChallengeId) { + this.audio.pause(); + this.audio.setAttribute('src', 'https://cdn.beatsaver.com/' + data.selectedChallengeVersion + '.mp3'); + this.audio.currentTime = 0; + this.audio.play(); + } else if (!data.selectedChallengeId) { this.audio.pause(); } } diff --git a/src/constants/genres.js b/src/constants/genres.js index fbf8b27a..0753ff08 100644 --- a/src/constants/genres.js +++ b/src/constants/genres.js @@ -16,7 +16,7 @@ module.exports = [ {name: 'Alternative', row: 3, column: 1}, {name: 'Anime', row: 3, column: 2}, {name: 'Comedy', row: 3, column: 3}, - {name: 'Disney', row: 3, column: 4}, + /* {name: 'TODO', row: 3, column: 4}, */ {name: 'Dubstep', row: 3, column: 5}, - {name: 'EDM', row: 3, column: 6} + {name: 'Dance', row: 3, column: 6} ]; diff --git a/src/scene.html b/src/scene.html index 49f92d7e..42f0818e 100644 --- a/src/scene.html +++ b/src/scene.html @@ -12,7 +12,7 @@ bind__leaderboard="difficulty: menuSelectedChallenge.difficulty || challenge.difficulty; beatmapCharacteristic: menuSelectedChallenge.beatmapCharacteristic || challenge.beatmapCharacteristic; gameMode: gameMode; inVR: inVR; isVictory: isVictory; menuSelectedChallengeId: menuSelectedChallenge.id; challengeId: challenge.id" bind__search="difficultyFilter: difficultyFilter; genre: genre; playlist: playlist; query: search.query" bind__song="audio: challenge.audio; challengeId: challenge.id; isLoading: isLoading; isPlaying: isPlaying; isBeatsPreloaded: challenge.isBeatsPreloaded; isGameOver: isGameOver; isVictory: isVictory" - bind__song-preview-system="previewStartTime: menuSelectedChallenge.previewStartTime; selectedChallengeId: menuSelectedChallenge.id" + bind__song-preview-system="selectedChallengeId: menuSelectedChallenge.id; selectedChallengeVersion: menuSelectedChallenge.version" bind__stage-colors="colorScheme: colorScheme" bind__tunnels="isPlaying: isPlaying; songDuration: challenge.metadata.duration" bind__zip-loader="difficulties: menuDifficulties; isLoading: isLoading; version: menuSelectedChallenge.version; directDownload: menuSelectedChallenge.directDownload; bpm: menuSelectedChallenge.metadata.bpm" diff --git a/src/state/index.js b/src/state/index.js index 5326790a..67cde9b1 100644 --- a/src/state/index.js +++ b/src/state/index.js @@ -1,6 +1,7 @@ /* global localStorage */ import COLORS from '../constants/colors'; const utils = require('../utils'); +const convertBeatmap = require('../lib/convert-beatmap'); const challengeDataStore = {}; let HAS_LOGGED_VR = false; @@ -38,7 +39,7 @@ const SKIP_INTRO = AFRAME.utils.getUrlParameter('skipintro') === 'true'; const colorScheme = localStorage.getItem('colorScheme') || 'default'; -let favorites = localStorage.getItem('favorites'); +let favorites = localStorage.getItem('favorites-v2'); if (favorites) { try { favorites = JSON.parse(favorites); @@ -169,7 +170,10 @@ AFRAME.registerState({ queryText: '', results: [], songNameTexts: '', // All names in search results merged together. - songSubNameTexts: '' // All sub names in search results merged together. + songSubNameTexts: '', // All sub names in search results merged together. + // url and urlPage are used to load more results from the API when scrolling down + url: '', + urlPage: 0, }, searchResultsPage: [], speed: 10 @@ -353,7 +357,7 @@ AFRAME.registerState({ for (let i = 0; i < state.favorites.length; i++) { if (state.favorites[i].id === id) { state.favorites.splice(i, 1); - localStorage.setItem('favorites', JSON.stringify(state.favorites)); + localStorage.setItem('favorites-v2', JSON.stringify(state.favorites)); return; } } @@ -362,7 +366,7 @@ AFRAME.registerState({ state.menuSelectedChallenge.isFavorited = true; if (state.favorites.filter(favorite => favorite.id === id).length) { return; } state.favorites.push(challenge) - localStorage.setItem('favorites', JSON.stringify(state.favorites)); + localStorage.setItem('favorites-v2', JSON.stringify(state.favorites)); } }, @@ -675,6 +679,28 @@ AFRAME.registerState({ } state.search.page++; computeSearchPagination(state); + + if (state.search.url === undefined) { + return; + } + + if ((state.search.page + 3) > Math.floor(state.search.results.length / SEARCH_PER_PAGE)) { + + state.search.urlPage = state.search.urlPage + 1; + + fetch(state.search.url.replaceAll('CURRENT_PAGE_INDEX', state.search.urlPage)) + .then(r => { return r.json() }) + .then(res => { + var hits = res['docs'].map(convertBeatmap) + + state.search.results.push(...hits); + + for (i = 0; i < hits.length; i++) { + let result = hits[i]; + challengeDataStore[result.id] = result; + } + }) + } }, /** @@ -684,6 +710,8 @@ AFRAME.registerState({ var i; state.search.hasError = false; state.search.page = 0; + state.search.url = payload.url; + state.search.urlPage = payload.urlPage; state.search.query = payload.query; state.search.queryText = truncate(payload.query, 10); state.search.results = payload.results; diff --git a/src/templates/menu.html b/src/templates/menu.html index c1c01641..6b562060 100644 --- a/src/templates/menu.html +++ b/src/templates/menu.html @@ -199,7 +199,7 @@ --> - + - +