summaryrefslogtreecommitdiff
path: root/frontend/site/audio/audio.player.js
diff options
context:
space:
mode:
authorlens <lens@neural.garden>2021-03-23 21:10:11 +0000
committerlens <lens@neural.garden>2021-03-23 21:10:11 +0000
commitcc1d0c52e104245f9f1c0d77eb24a5a33800be38 (patch)
tree02d8483dfe47803525b926a43c582dcfbf61c5db /frontend/site/audio/audio.player.js
parent81c673f058fda04b96baae7b2302f876479bc0a9 (diff)
parent7a3ec205e001e4c071a67ecc5c375612fa72afdc (diff)
Merge branch 'master' of asdf.us:swimmer
Diffstat (limited to 'frontend/site/audio/audio.player.js')
-rw-r--r--frontend/site/audio/audio.player.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/frontend/site/audio/audio.player.js b/frontend/site/audio/audio.player.js
new file mode 100644
index 0000000..17edeee
--- /dev/null
+++ b/frontend/site/audio/audio.player.js
@@ -0,0 +1,141 @@
+import { history } from 'site/store'
+
+export default class AudioPlayer {
+ files = {}
+ players = {}
+ current_background_id = 0
+
+ constructor() {
+ this.done = this.done.bind(this)
+ }
+
+ load(graph) {
+ this.files = graph.uploads
+ .filter(upload => upload.tag === 'audio')
+ .reduce((accumulator, item) => {
+ accumulator[item.id] = item
+ return accumulator
+ }, {})
+ }
+
+ has(id) {
+ return (
+ (id > 0) &&
+ (id in this.files)
+ )
+ }
+
+ done(id) {
+ // console.log('remove', id)
+ delete this.players[id]
+ }
+
+ playPage(page) {
+ const { background_audio_id, restart_audio } = page.settings
+ // console.log('playPage', page)
+ if (
+ this.current_background_id
+ && this.current_background_id !== background_audio_id
+ && this.current_background_id in this.players
+ ) {
+ this.players[this.current_background_id].stop()
+ }
+ if (this.has(background_audio_id)) {
+ this.current_background_id = background_audio_id
+ this.playFile({
+ id: background_audio_id,
+ type: 'background',
+ restart: !!restart_audio,
+ })
+ }
+ }
+
+ playTile({ tile, type }) {
+ let id = type === 'click'
+ ? tile.settings.audio_on_click_id
+ : type === 'hover'
+ ? tile.settings.audio_on_hover_id
+ : null
+ if (this.has(id)) {
+ this.playFile({ id, tile, type })
+ }
+ }
+
+ playFile({ id, tile, type, restart, loop }) {
+ const item = this.files[id]
+ if (id in this.players) {
+ if (restart) {
+ this.players[id].restart()
+ }
+ if (tile && !this.players[id].tile) {
+ this.players[id].tile = tile
+ this.players[id].type = type
+ }
+ return this.players[id]
+ } else {
+ this.players[id] = new Player({
+ item,
+ tile,
+ type,
+ done: this.done
+ })
+ this.players[id].play()
+ return this.players[id]
+ }
+ }
+}
+
+class Player {
+ constructor({ item, tile, type, done }) {
+ this.item = item
+ this.tile = tile
+ this.type = type
+ this.done = done
+ this.audio = document.createElement('audio')
+ this.handleEnded = this.handleEnded.bind(this)
+ this.handleError = this.handleError.bind(this)
+ this.release = this.release.bind(this)
+ this.audio.addEventListener('ended', this.handleEnded)
+ this.audio.addEventListener('error', this.handleError)
+ this.audio.src = item.url
+ }
+
+ release() {
+ if (this.type === 'click' && this.tile && this.tile.settings.navigate_when_audio_finishes) {
+ history.push(this.tile.href)
+ }
+ this.audio.removeEventListener('ended', this.handleEnded)
+ this.audio.removeEventListener('error', this.handleError)
+ this.done(this.item.id)
+ this.item = null
+ this.done = null
+ this.audio = null
+ }
+
+ handleError(error) {
+ console.error(error)
+ this.release()
+ }
+
+ handleEnded() {
+ if (this.type === 'background') {
+ this.restart()
+ } else {
+ this.release()
+ }
+ }
+
+ play() {
+ this.audio.play()
+ }
+
+ restart() {
+ this.audio.currentTime = 0
+ this.audio.play()
+ }
+
+ stop() {
+ this.audio.pause()
+ this.release()
+ }
+}