search results and audio previews

This commit is contained in:
Kevin Ngo
2018-07-20 09:34:52 +02:00
parent 4cf793848b
commit 86f0ad5641
8 changed files with 108 additions and 76 deletions

11
package-lock.json generated
View File

@@ -81,9 +81,9 @@
}
},
"aframe-animation-component": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/aframe-animation-component/-/aframe-animation-component-4.2.0.tgz",
"integrity": "sha512-XkcaGqcEIjUgkL1UoE1GBph8O0Vixkd9K/mlttZzeiCcQQBKq1XN2BVaDlJIs3krhjRL7MhWT/RdLIlh3ki2CQ==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/aframe-animation-component/-/aframe-animation-component-5.0.0.tgz",
"integrity": "sha512-cqQ5o5iK5RvUUxS8e8VZ419Z/7N3eGvKhP6IUypZE2we71O0YuTOkd3DHGuvjoaI8mhqcJQ20lsUEfE8tWNEYA==",
"requires": {
"animejs": "2.2.0"
}
@@ -98,6 +98,11 @@
"resolved": "https://registry.npmjs.org/aframe-cubemap-component/-/aframe-cubemap-component-0.1.4.tgz",
"integrity": "sha512-9k5CVFltFACmoQxmS9Jf3XpjqpES9iNSRnCxamxSDCpNyXn7myHii7bjnfIuzs6zwSeJU8Gbb72zzRyQ6Csp9g=="
},
"aframe-event-decorators": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/aframe-event-decorators/-/aframe-event-decorators-1.0.2.tgz",
"integrity": "sha512-Y2ngTXj5Zi48mvGyApPtDyXDX78TDhuKriOaMKuDOeInYbw5Z7Irzkamo/GdHKhyCRId/NcaaqgtlOBWlYK+5A=="
},
"aframe-event-set-component": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/aframe-event-set-component/-/aframe-event-set-component-4.1.2.tgz",

View File

@@ -6,9 +6,10 @@
"start": "webpack-dev-server --host 0.0.0.0 --progress --colors --hot --inline --port 3000"
},
"dependencies": {
"aframe-animation-component": "^4.1.1",
"aframe-animation-component": "^5.0.0",
"aframe-animation-timeline-component": "^1.3.1",
"aframe-cubemap-component": "^0.1.2",
"aframe-event-decorators": "^1.0.2",
"aframe-event-set-component": "^4.0.1",
"aframe-gltf-part-component": "1.1.0",
"aframe-haptics-component": "^1.4.1",

View File

@@ -0,0 +1,55 @@
var utils = require('../utils');
/**
* Load beat data (all the beats and such).
*/
AFRAME.registerComponent('beat-loader', {
schema: {
challengeId: {type: 'string'},
difficulty: {type: 'string'}
},
update: function () {
var challengeId = this.data.challengeId;
var el = this.el;
var xhr;
if (!challengeId || !diffjculty) { return; }
// Load beats.
xhr = new XMLHttpRequest();
el.emit('beatloaderstart');
xhr.open('GET', utils.getS3FileUrl(challengeId, `${this.data.difficulty}.json`));
xhr.addEventListener('load', () => {
this.handleBeats(JSON.parse(xhr.responseText));
});
xhr.send();
},
/**
* TODO: Load the beat data into the game.
*/
handleBeats: function (beatData) {
var el = this.el;
history.pushState(
'',
challenge.songName,
updateQueryParam(window.location.href, 'challenge', this.data.challengeId)
);
document.title = `Super Saber - ${challenge.songName}`;
el.emit('beatloaderfinish');
console.log('Finished loading challenge data.');
},
});
function updateQueryParam(uri, key, value) {
var re = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
if (uri.match(re)) {
return uri.replace(re, '$1' + key + '=' + value + '$2');
} else {
return uri + separator + key + '=' + value;
}
}

View File

@@ -1,57 +0,0 @@
AFRAME.registerComponent('song-loader', {
schema: {
challengeId: {type: 'string'},
},
update: async function () {
var challengeId = this.data.challengeId;
var frameSystem = this.el.systems.frames;
var punchSystem = this.el.systems.punches;
if (!challengeId) {
return;
}
const firstClient = new Client({ query: { id: challengeId } });
const resp = await firstClient.challengeById(challengeId);
const challenge = resp.performance;
const auth = firstClient.serialize();
const client = new Client({ auth });
this.el.emit('challengeloadstart');
console.log('Loading punches...');
this.el.emit('challengeloadingpunches');
const punches = await client.challengePunches(challenge);
console.log('Loading frames...');
this.el.emit('challengeloadingframes');
const frames = await client.challengeFrames(challenge);
history.pushState(
'',
challenge.song_name,
updateQueryParam(window.location.href, 'challenge', this.data.challengeId)
);
document.title = `Soundboxing - ${challenge.song_name}`;
this.el.emit('challengeloaded', {
frames: frames,
punches: punches,
title: challenge.song_name,
videoId: challenge.youtube_id,
});
console.log('Finished loading challenge data.');
},
});
function updateQueryParam(uri, key, value) {
var re = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
if (uri.match(re)) {
return uri.replace(re, '$1' + key + '=' + value + '$2');
} else {
return uri + separator + key + '=' + value;
}
}

View File

@@ -1,4 +1,6 @@
var algoliasearch = require('algoliasearch/lite');
var bindEvent = require('aframe-event-decorators').bindEvent;
var utils = require('../utils');
var client = algoliasearch('QULTOY3ZWU', 'be07164192471df7e97e6fa70c1d041d');
var index = client.initIndex('supersaber');
@@ -19,7 +21,6 @@ AFRAME.registerComponent('search', {
this.queryObject.query = query;
index.search(this.queryObject, (err, content) => {
this.eventDetail.results = content.hits;
console.log(content.hits);
this.el.sceneEl.emit('searchresults', this.eventDetail);
});
}
@@ -31,12 +32,33 @@ AFRAME.registerComponent('search', {
AFRAME.registerComponent('search-result', {
init: function() {
var el = this.el;
this.audio = new Audio();
this.audio.currentTime = el.getAttribute('data-preview-start-time');
this.audio.src = utils.getS3FileUrl(el.getAttribute('data-id'), 'song.ogg');
this.eventDetail = {};
el.addEventListener('click', () => {
this.eventDetail.challengeId = el.getAttribute('data-song-id');
this.eventDetail.title = el.getAttribute('data-title');
el.sceneEl.emit('challengeset', this.eventDetail);
});
},
remove: function () {
this.audio.pause();
},
/**
* Preview song.
*/
mouseenter: bindEvent(function () {
this.audio.play();
}),
mouseleave: bindEvent(function () {
this.audio.pause();
}),
click: bindEvent(function () {
var el = this.el;
this.eventDetail.id = el.getAttribute('data-id');
this.eventDetail.title = el.getAttribute('data-title');
// Tell application we are starting a challenge and initiate beat-loader.
el.sceneEl.emit('challengeset', this.eventDetail);
}),
});

View File

@@ -9,14 +9,13 @@
<body>
<audio id="hoverSound" src="/assets/sounds/hover.ogg"></audio>
<a-scene bind__challenge-loader="challengeId: challenge.id"
<a-scene bind__beat-loader="challengeId: challenge.id"
bind__embedded="embedded"
challenge-loader
console-shortcuts
search>
<a-assets timeout="10000">
<a-mixin id="raycaster"
raycaster="objects: [raycastable], [data-ui]; far: 2"></a-mixin>
<a-mixin id="raycaster" raycaster="objects: [raycastable], [data-ui]; far: 2"></a-mixin>
<img id="playImg" src="assets/img/play.png">
<img id="resultImg" src="assets/img/result.png">
<img id="resultIconsImg" src="assets/img/resulticons.png">
@@ -42,7 +41,7 @@
<a-entity id="rightHand"></a-entity>
</a-entity>
<a-entity id="mouseCursor" mixin="raycaster" cursor="rayOrigin: mouse" bind__isPlaying="!inVR"></a-entity>
<a-entity id="mouseCursor" mixin="raycaster" cursor="rayOrigin: mouse" debug-cursor bind__isPlaying="!inVR"></a-entity>
</a-scene>
</body>
</html>

View File

@@ -6,7 +6,9 @@
{% raw %}
<template id="searchResultTemplate">
<a-entity class="searchResult" search-result data-song-id="{{ item.id }}" data-title="{{ item.songName }}">
<a-entity class="searchResult" search-result
data-id="{{ item.id }}" data-title="{{ item.songName }}"
data-preview-start-time="{{ item.previewStartTime }}">
<a-entity>
<a-entity class="searchResultSlice"
geometry="primitive: plane; width: 0.8; height: 0.2"
@@ -19,10 +21,9 @@
<a-entity class="searchResultIcons"
geometry="primitive: plane; width: 0.8; height: 0.2"
material="shader: flat; transparent: true; src: #resultIconsImg; color: #FFF"
position="0 -0.13 -0.005"
raycastable></a-entity>
position="0 -0.13 -0.005"></a-entity>
</a-entity>
<a-entity class="searchResultAuthor" mixin="textFont" text="wrapCount: 48; align: center; color: #54c2fd; value: {{ item.subSongName }}" position="0 -0.060 0"></a-entity>
<a-entity class="searchResultAuthor" mixin="textFont" text="wrapCount: 48; align: center; color: #54c2fd; value: {{ item.songSubName }}" position="0 -0.060 0"></a-entity>
<a-entity class="searchResultTitle" mixin="textFont" text="align: center; color: #FFF; wrapCount: 35; value: {{ item.songName }}" position="0 -0.111 0"></a-entity>
<a-entity class="searchResultDownloads" mixin="textFont" text="color: #cc0856; anchor: left; value: {{ item.downloads }}" position="0.192 -0.184 0"></a-entity>
</a-entity>

6
src/utils.js Normal file
View File

@@ -0,0 +1,6 @@
var BASE_URL = 'https://s3-us-west-2.amazonaws.com/supersaber';
function getS3FileUrl (id, name) {
return `${BASE_URL}/${id}-${name}`;
}
module.exports.getS3FileUrl = getS3FileUrl;