if (! localStorage.emtdata) { localStorage.emtdata = JSON.stringify(this._data); } else { this._data = JSON.parse(localStorage.emtdata); } for (key in this._data) { var val = this._data[key]; // console.log('restored', key, val) this.setAttribute(key, val); } var _this = this; window.addEventListener('unload', function() { localStorage.emtdata = JSON.stringify(_this._data); }); this._data[name] = value; this.setAttribute(name, value); // console.log('persisted', name, value, this._data) this._data = localStorage.emtdata = {}; this.setAttribute('volume', persist.volume) persist.set('volume', volume); if (loadprogress == 1) trackEvent('player', 'loadfinished', this.pid) if (this.pid) trackEvent('player', 'playing', this.pid, this.time) if (this.pid) trackEvent('player', 'loaded', this.pid) // console.log('paused', this, this.paused, this.playing) if (this.playing) { this.setAttribute('paused', ! this.paused); persist.set('paused', this.paused); } else { // console.log('play', true) this.setAttribute('playing', true); persist.set('paused', false); } if (url !== this.url) { var args = {url: url, audio: audio, pid: pid} this.setAttributes(args); trackEvent('player', 'loading', this.pid) } minutes = Math.floor(time / 60) seconds = Math.floor(time) - minutes * 60 if (seconds < 10) seconds = '0' + seconds return minutes + ':' + seconds if (url) { url = url.substring(0, url.lastIndexOf('.')); if (url) { console.log('loading waveform url', url) var waveform = 'https://s3.amazonaws.com/assets.musicwindow.com/public/album_waveform/' + encodeURIComponent(url) + '.svg' this.setAttribute('src', waveform) } } var x = dr.mouse.x - this.getAbsolute().x; // limit to load percentage instead of seeking ahead and waiting for the load var perc = Math.min(x / this.width, audio.loadprogress); var time = perc * audio.duration; trackEvent('player', 'seek', player.productid, time) audio.seek(time); this.rect.attr('width', 100) if (! loadprogress || ! this.rect) return; if (loadprogress > 1) loadprogress = 1; this.rect.attr('width', loadprogress * 100) if (! time || ! this.rect) return; var played = (time / audio.duration); this.rect.attr('width', played * 100) if (audio.playing) { // console.log('playing', ! audio.paused) var eventname = ! audio.paused ? 'pause' : 'play'; trackEvent('player', eventname, audio.pid, audio.time) } else { trackEvent('player', 'play', audio.pid) } audio.togglePaused(); var char = 'fa fa-spin fa-spinner'; var x = 5; if (audio.loaded) { if (audio.playing && ! audio.paused) { char = 'fa fa-pause'; } else { char = 'fa fa-play'; } } else { x = 2; } this.txt.setAttributes({class: char, x: x}); trackEvent('player', 'prev', player.productid) if (audio.time < .5 && player._history.length) { player.prev(); } else { audio.seek(0); } / trackEvent('player', 'next', player.productid) player.next(); this.setAttribute('muted', audio.volume === 0) this.popup.setAttribute('show', true) this.setAttribute('active', true) this.setAttribute('active', false) // hide if clicked outside if (view !== this.parent.parent && view !== this && view !== this.parent.sliderbutton) { this.parent.setAttributes({show: false}); this.parent.parent.setAttributes({active: false}); } var y = dr.mouse.y - this.getAbsolute().y; if (y < 150) { this.parent.sliderbutton.animate({'y': y}, 200); } else { this.parent.setAttribute('show', ! this.parent.show); } this.parent.parent.setAttribute('active', true) this.parent.parent.setAttribute('active', this.parent.show ? true : false) // set position based on volume var min = this.parent.track.y; var max = this.parent.track.height - min; var pos = max - (audio.volume * (max - min)); this.setAttribute('y', pos); // set volume based on position var min = this.parent.track.y; var max = this.parent.track.height - min; if (y < min) { y = min; } else if (y > max) { y = max; } var perc = 1 - ((y - min) / (max - min)); this.setAttribute('y', y); audio.setAttribute('volume', perc); this.setAttribute('mouseIsDown', true); this.setAttribute('mouseIsDown', false); if (search.keywords[this.text]) this.setAttribute('color', 'white') if (this.color === 'black') { trackEvent('search', 'keywordon', this.text) this.setAttribute('color', 'white'); search.keywords[this.text] = true; //} else if (this.color === 'green') { // this.setAttribute('color', 'red'); } else { trackEvent('search', 'keywordoff', this.text) this.setAttribute('color', 'black'); search.keywords[this.text] = null; } search.setAttribute('keywords', search.keywords); var text = this.text.toLowerCase(); trackEvent('search', 'label', this.text) searchinput.setAttributes({text: text, value: text}) if (url) { if (! audio.loaded) { this._loadafteraudio = url; return; } var coverurl = 'https://s3.amazonaws.com/assets.musicwindow.com/public/album_images_' + (login.loggedin ? 500 : 200) + '/' + encodeURIComponent(url) this.setAttribute('src', coverurl) } // console.log('onloaded', loaded, this._loadafteraudio) if (loaded && this._loadafteraudio) { this.setAttribute('url', this._loadafteraudio) this._loadafteraudio = null; } if (loggedin) this.setAttribute('url', this.url) this.cover.setAttribute('url', data.imageurl) this.labels.title.setAttribute('text', data.title) var release = data.release; var tracks = 0; if (data.tracks) tracks = data.tracks.length // console.log('data.tracks', data.tracks, tracks, data.release) var track = tracks[player.trackoffset] if (tracks > 1) { // this is an album if (track && player.productid != track.id) { // we are playing the album, show the track offset and count in the title var offset = ' (' + (player.trackoffset + 1) + '/' + tracks + ')'; this.labels.title.setAttribute('text', track.title + offset) this.labels.artist.setAttribute('text', track.artist) } else { // append track count to release release += ' (' + tracks + ' tracks)'; this.labels.title.setAttribute('text', data.title) this.labels.artist.setAttribute('text', data.artist) } } else { this.labels.title.setAttribute('text', data.title) this.labels.artist.setAttribute('text', data.artist) } this.setAttribute('owned', player.isOwned(data)); this.labels.release.setAttribute('text', release) this.labels.label.setAttribute('text', data.label) this.labels.released.setAttribute('text', data.released) if (data.keywords) { this.labels.keywords.setAttribute('text', data.keywords.join(',').toLowerCase()) } if (purchased) this.setAttribute('owned', player.isOwned(this.data)); this.labels.actions.buyordownload.setAttribute('class', owned ? 'fa fa-download' : 'fa fa-cart-plus') var product = this.parent.data; trackEvent('product', 'playingcover', product.id) // always start at first track when playing an album player.setAttribute('trackoffset', 0) player.play(product); var product = this.parent.parent.parent.data; trackEvent('product', 'playing', product.id) // always start at first track when playing an album player.setAttribute('trackoffset', 0) player.play(product); var product = this.parent.parent.parent.data; trackEvent('product', 'add', product.id) // TODO: use classroot in dreem2! player.add(product); // TODO: use classroot in dreem2! var parent = this.parent.parent.parent; if (parent.owned) { player.download(parent.data); } else { trackEvent('product', 'buy', parent.data.id) player.buy(parent.data); } var _this = this; var readHash = function() { var hash = decodeURI(window.location.hash).substring(1) if (hash.indexOf('/search/') === 0) { if (hash != _this.searchresult.url) { _this.searchresult.setAttribute('url', hash); console.log('search terms', hash) if (hash.indexOf('keywords') >= 0) { // restore search keywords var keywords = hash.split('=')[1] if (keywords) { var wordlist = keywords.split(',') search.keywords = {}; for (var i = 0; i < wordlist.length; i++) { search.keywords[wordlist[i]] = true; } taglist.reset() } } else { // restore search terms var terms = hash.substring(8); if (terms.indexOf('*?') != 0) { search.setAttributes({text: terms, value: terms}) searchinput.setAttributes({text: terms, value: terms}) } } } return; } else if (hash.indexOf('/playlist/') === 0) { // load playlist var playlisturl = hash.substring(10, hash.length); return playlist.setAttribute('url', EMT + '/' + playlisturl) } else if (hash.indexOf('/signup/') === 0 || hash.indexOf('/password/') === 0) { login.loginwindow.setAttributes({src: EMT + hash, visible: true}) } // load features playlist by default window.location.hash = '/playlist/features' } $(window).on('hashchange',readHash); readHash(); if ((! this.term) && (Object.keys(this.keywords).length) == 0) return; var url = '/search/' + this.term; var keywords = []; for (var key in this.keywords) { if (this.keywords[key]) { keywords.push(key.toLowerCase().split(' ')[0]) } } if (keywords.length) { url = '/search/*?keywords=' + keywords.join(',').toLowerCase(); } if (url !== this.searchresult.url) { this.searchresult.setAttribute('url', url) } if (! data.totalHits) { return; } var out = data.hits.map(function(hit) { var doc = hit.document; if (! doc.tracks) { doc.tracks = [JSON.parse(JSON.stringify(doc))] } return doc; }) if (out.length > 100) { out.length = 100 } return out; if (! data) return window.location.hash = encodeURI(this.searchresult.url); if (!(audio.playing && audio.url)) { // play first track of first result, but don't interrupt current audio playback player.play(data[0]) } taglist.reset() if (text) this.suggestionds.setAttribute('url', '/suggest/' + text) this.suggestionds.setAttribute('data', []) trackEvent('search', 'suggestion', this.text) suggestions.clear(); searchinput.setAttributes({text: this.text, value: this.text}) out = data.map(function(suggestion) { return suggestion[0]; }) return out; // console.log('data', data) this.repl.setAttribute('data', data) this.data = data; search if (this._tid !== null) { clearTimeout(this._tid); } // enter or tab key, set the value immediately and bail var keyCode = key.keyCode if (keyCode === 13 || keyCode === 32) { if (suggestions.data.length) { this.setAttribute('text', suggestionds.data[0]) this.setAttribute('value', suggestionds.data[0]) suggestions.clear() } return; } this._tid = setTimeout(this._update, this.delay); this.parent.measure.setAttribute('text', this.text) this.setAttribute('width', (this.parent.measure.width || 100) + 50) ; this.setAttribute('height', (this.parent.measure.height || 30)) ; this.parent.measure.setAttribute('text', '') if (text !== suggestions.text) suggestions.clear() suggestions.clear() this.setAttribute('value', this.text) if (this.text) { suggestions.setAttribute('text', this.text) } else { suggestions.clear() } if (! value) return this.parent.setAttribute('keywords', {}) taglist.reset(); if (value != this.parent.term) this.parent.setAttribute('term', value) this.repl.setAttribute('datapath', this.repl.datapath) {"tags": [ {"name":"ambient"}, {"name":"breakbeat"}, {"name":"dark"}, {"name":"dope"}, {"name":"downtempo"}, {"name":"drum & bass"}, {"name":"dubstep/grime"}, {"name":"electro"}, {"name":"experimental"}, {"name":"funky"}, {"name":"glitch hop"}, {"name":"glitchy"}, {"name":"heavy"}, {"name":"hip hop"}, {"name":"house"}, {"name":"idm"}, {"name":"midtempo"}, {"name":"organic"}, {"name":"progressive"}, {"name":"ragga"}, {"name":"techfunk"}, {"name":"techno"}, {"name":"vocal"} ] } if (data.length) { this.results.repl.setAttribute('data', data); } if (loggedin) { this.setAttribute('playlistoffset', this.playlistoffset) this.setAttribute('trackoffset', this.trackoffset) } if (! this.playlist.data) return; var tracks = this.playlist.data.tracks; if (! tracks) return; if (playlistoffset >= tracks.length) { // we reached the end, reset to zero to keep playing playlistoffset = 0; } var track = tracks[playlistoffset]; // console.log('onplaylistoffset', playlistoffset, track) if (track && track.id !== this.productid) { this.play(track); } data.tracks = data.tracks.splice(0, 21) return data; if (!(audio.playing && audio.url && this.productid)) { // play first track of first result, but don't interrupt current audio playback // console.log('playlist start', data.tracks) if (data.tracks) player.play(data.tracks[0]) } console.log('onend', audio.paused) if (! audio.paused) { this.next(); } // TODO: figure out why I'm getting called with null if (! product) return var productid = product.id; this.setAttribute('productid', productid) if (this.playlist.data) { var tracks = this.playlist.data.tracks; // look through playlist for matching productid for (var i = 0, l = tracks.length; i < l; i++) { var track = tracks[i]; if (track.id == productid && this.playlistoffset != i) { // console.log('set playlistoffset to match', track.id, i); this.setAttribute('playlistoffset', i); } } } // Not found in playlist, load album instead this.album.setAttribute('data', product) // console.log('product', this.album.data, this.playlist.data) tracks = [] if (this.album.data) { tracks = this.album.data.tracks; } if (tracks.length > 1 && this.trackoffset + 1 < tracks.length && (! this.currenttrackonly)) { var track = tracks[this.trackoffset]; track.trackoffset = this.trackoffset; this._history.push(track); // play next track in album this.setAttribute('trackoffset', this.trackoffset + 1) } else if (this.playlist.data && (this.playlistoffset + 1 < this.playlist.data.tracks.length)) { // play next in playlist if (this.currenttrackonly) this.currenttrackonly = false; var album = this.album.data; album.trackoffset = this.trackoffset; album.playlistoffset = this.playlistoffset; album.isalbum = true; this._history.push(album); this.setAttribute('playlistoffset', this.playlistoffset + 1) } else { // look in search if (! search.searchresult.data) return; tracks = search.searchresult.data; for (var i = 0; i < tracks.length; i++) { var track = tracks[i]; if (track.id == this.productid) { this.play(tracks[i + 1]) return; } } if (tracks[0]) this.play(tracks[0]) } console.log('prev', this._history) if (this._history.length) { var item = this._history.pop(); if (item.isalbum) { player.album.setAttribute('data', item) var track = item.tracks[item.trackoffset] this.setAttribute('playlistoffset', item.playlistoffset); track.trackoffset = item.trackoffset } else { var track = item; } var pid = track.id var audiourl = track.audio; this.setAttribute('trackoffset', track.trackoffset) songredirect.getURL(audiourl, pid, function(url) { audio.playTrack(url, pid, audiourl); }); } // don't add the track that's playing to the list // if (product.id == this.productid) return; var tracks = this.playlist.data && this.playlist.data.tracks; if (! tracks) { this.playlist.data = {tracks: []}; tracks = this.playlist.data.tracks; } // console.log('add', tracks, this.playlist) for (var i = 0, l = tracks.length; i < l; i++) { var track = tracks[i]; if (product.id == track.id) { // don't add the same track more than once return; } } // add to the end of the playlist tracks.push(product); this.playlist.setAttribute('data', this.playlist.data); if (! this.productid) { this.setAttribute('playlistoffset', 0); } buy.show(product); if (product.tracks) { var audio = product.tracks[0].audio; } else { var audio = product.audio; } var url = EMT + '/download/' + audio + '?pid=' + product.id; trackEvent('product', 'download', product.id) //console.log('download', url, product) window.open(url, '_new'); //this.downloadwindow.setAttribute('src', url) if (persist.paused) { audio.setAttribute('playing', true) audio.setAttribute('paused', true) } // console.log('got album data', data) if (data.tracks && data.tracks.length > 0) { this.setAttribute('trackoffset', 0) } if (err.msg === 4) { // aws timeout, force reload songredirect.cache = null songredirect.getURL(audio.audio, audio.pid, function(url) { // console.log('forcing reload', audio.audio, audio.pid) audio.setAttributes({url: url, audio: audio.audio, pid: audio.pid}); }); } else { console.error('audio load error', err, audio); } if (! this.album.data) return; var tracks = this.album.data.tracks; if (trackoffset < tracks.length) { var track = tracks[trackoffset]; // console.log('loading track', track) // get signed streaming URL var pid = track.id var audiourl = track.audio; songredirect.getURL(audiourl, pid, function(url) { audio.playTrack(url, pid, audiourl); }); var nexttrack = tracks[trackoffset + 1]; if (nexttrack) { // prefetch URL for next track setTimeout(function() { songredirect.getURL(nexttrack.audio, nexttrack.id, function() { }) },4000) } } var key = id; if (this.cache && this.cache[key]) { // console.log('cache hit', key, this.cache.expires, Date.now()) if (callback) return callback(this.cache[key]); } if (this.callbacks[id]) return; this.callbacks[id] = callback; var url = EMT + '/stream/' + encodeURIComponent(file) + '?pid=' + id; // console.log('getURL', url, id) this.songredirectds.setAttribute('url', url); // console.log('songredirect', data); var key = data.pid; var callback = this.callbacks[key]; if (data.url) { if (! this.cache || (Date.now() >= this.cache.expires)) { this.cache = {}; this.cache.expires = data.expires // console.log('new cache', data) } this.cache[key] = data.url; if (callback) { callback(data.url); this.callbacks[key] = null; } } if (! (product && this.purchased)) return false; // console.log('product', product) if (this.purchased[product.id]) { return true; } if (product.tracks && product.tracks.length > 1) { var ownall = true; for (var i = 0; i < product.tracks.length; i++) { // console.log('checking for ownership of all tracks', product.tracks[i]) if (! this.purchased[product.tracks[i].id]) { ownall = false break } } return ownall } else { return this.purchased[product.id] } trackEvent('player', 'loadplaylist', this.url) window.location.hash = this.url; charts features purchased this.loggedinds.setAttribute('url', EMT + '/loggedIn') var loggedin = data.loggedIn; if (loggedin != this.loggedin) this.setAttribute('loggedin', loggedin) if (loggedin) { trackEvent('user', 'loggedin') this.loginwindow.setAttribute('visible', false) songredirect.cache = null this.but.setAttribute('visible', true) this.but.setAttribute('class', 'fa fa-sign-out') } else { this.but.setAttribute('class', 'fa fa-sign-in') } //console.log('toggleLogin', this.loggedin) if (this.loggedin) { window.location = EMT + '/logout' } else { this.loginwindow.setAttributes({src: EMT + '/login', visible: true}) // console.log('loginwindow', this.loginwindow.visible, this.loginwindow.src, this.loginwindow.sprite) } if (login.loggedin) { trackEvent('user', 'logout') } else { trackEvent('user', 'login') } this.parent.toggleLogin(); if (loggedin) { // load purchases this.purchased_ds.setAttribute('url', EMT + '/purchased') } // process purchases into a hash for quick lookups var ids = {}; for (var i = 0; i < purchased.length; i++) { var tid = purchased[i] ids[tid] = true; } // console.log('purchased', ids, this.parent.parent.id) this.parent.parent.setAttribute('purchased', ids) var width = width - 30; var maxwidth = this.parent.maxwidth; // console.log('width', this.text, width, maxwidth) if (width > maxwidth) { var newpos = width - maxwidth this.animating = true; this.anim.setAttributes({to: -newpos, paused: false}) } else if (this.animating) { this.animating = false; if (this.anim.animator) this.anim.animator.stop() if (this.animback.animator) this.animback.animator.stop() this.setAttribute('x', 30) } if (this.product) { trackEvent('product', 'buybutton', this.product.id) player.buy(this.product); } this.parent.setAttribute('active', true) this._wasactive = this.active this.setAttribute('active', true) this.parent.setAttribute('active', false) this.setAttribute('active', this._wasactive) var tracks = product.tracks; var price = 1.45; if (tracks && tracks.length > 1) { price = Math.min(1.25 * tracks.length, 13.75); } // console.log('computePrice', price, tracks.length) return price // console.log('show', product) this.setAttribute('data', product); this.cover.setAttribute('url', product.imageurl) this.downloads.setAttribute('visible', false); this.buywindow.setAttributes({src: EMT + '/checkouts/new/' + product.id, visible: true, opacity: 1, clickable: true}) var itemname = ''; if (product.tracks && product.tracks.length > 1) { var tracklabel = ' (' + product.tracks.length + ' tracks)'; itemname = product.release + tracklabel; } else { itemname = product.title + ' (' + product.release + ')'; } this.labels.release.setAttribute('text', itemname) this.labels.price.setAttribute('text', accounting.formatMoney(this.computePrice(product))) this.setAttribute('open', true) this.failed.setAttribute('visible', false); this.buywindow.setAttributes({'clickable': false, 'opacity': .5}); // reload list of purchases dr.datasets.purchased_ds.setAttribute('url', EMT + '/purchased') trackEvent('product', 'bought', pid) this.buywindow.setAttribute('visible', false); this.downloads.setAttribute('visible', true); this.failed.setAttribute('visible', false); dr.datasets.purchased_ds.setAttribute('url', EMT + '/purchased') this.buywindow.setAttribute('visible', false); this.downloads.setAttribute('visible', true); // client error trackEvent('product', 'purchaseerror', pid) this.show(this.data); this.failed.setAttributes({visible: true, text: error}); this.buywindow.setAttributes({'clickable': true, 'opacity': 1, visible: true}); this.downloads.setAttribute('visible', false); // server errpr trackEvent('product', 'purchasefailed', pid) this.show(this.data); this.failed.setAttributes({visible: true, text: error || 'Purchase failed. Please try another payment method:'}); if (! this.data) return; if (! open) trackEvent('product', 'closed', this.data.id) if (! this.open) return; if (loggingin == false) { this.show(this.data) } You are buying Price Purchase failed. Please try another payment method: Download purchase Choose Format Download now X if (! open && buy.open) { // delay closing until buy drawer closes buy.setAttribute('open', false); var _this = this; setTimeout(function() { _this.setAttribute('open', false); }, 310) return true; } persist.set('draweropen', open); return open; if (! this.container && this.container.tracks) return; var subviews = this.container.tracks.subviews; for (var i = 0; i < subviews.length; i++) { var color = player.trackoffset == i ? '#60BAFF' : 'white'; subviews[i].setAttributes({active: player.trackoffset == i, color: color}); } // update tags var taglist = player.album.data.tracks[player.trackoffset].keywords.sort(); this.tags.repl.setAttribute('data', taglist) this.highlightCurrentTrack(); var subviews = this.container.tracks.subviews; if (subviews.length === 1) { // hide second buy button for single tracks subviews[0].but.setAttribute('visible', false) } this.setAttribute('owned', player.isOwned(this.buyalbum.product)); var tracks = data.tracks; this.container.tracks.repl.setAttribute('data', tracks) var id = this.data.id var trackoffset = false; for (var i = 0; i < tracks.length; i++) { if (tracks[i].id == id) { trackoffset = i; break; } } // console.log('parentproduct', data, trackoffset, id) player.album.setAttribute('data', data) player.setAttributes({trackoffset: trackoffset, currenttrackonly: true}) this.highlightCurrentTrack(); this.setAttribute('data', data) if (data.parent) { this.parentproduct.setAttribute('url', '/product/' + data.parent) // console.log('found owner', data.parent) return; } this.container.tracks.repl.setAttribute('data', data.tracks) this.buyalbum.setAttribute('price', buy.computePrice(data)) this.buyalbum.setAttribute('product', data) this.update(); if (! this._initopen) { // wait until data is processed before sliding open on initial load this.setAttribute('open', persist.draweropen) this._initopen = true; } if (purchased && this.buyalbum.product) { this.setAttribute('owned', player.isOwned(this.buyalbum.product)); // console.log('purchased', this.buyalbum.product, this.owned) if (player.album.data) this.container.tracks.repl.setAttribute('data', player.album.data.tracks) this.update(); } this.setAttribute('owned', player.isOwned(data)); // console.log('track owned', this.owned) this.setAttribute('active', true) this.duration.setAttribute('opacity', 1) this.setAttribute('active', false) this.duration.setAttribute('opacity', 0) player.setAttribute('trackoffset', this.index); trackEvent('product', 'playing', this.data.id) this.label.setAttribute('text', data.title) if (data.duration) this.duration.setAttribute('text', data.duration) player.download(this.parent.data) this.parent.setAttribute('active', true) this.parent.setAttribute('active', false) return text.toUpperCase(); search.keywords = {}; search.keywords[this.text.split(' ')[0]] = true; search.doSearch(); X this.setAttribute('opacity', 0); this.animate({opacity: 1}, 10) switch (this.state) { case 'label': this.state = 'track'; break; case 'track': this.state = 'release'; break; case 'release': this.state = 'title'; break; case 'title': this.state = 'artist'; break; case 'artist': this.state = 'label'; break; } this.updateText() if (this.tid) clearTimeout(this.tid); this.tid = setTimeout(this.update, 4000) this.label.setAttribute('text', this.state.toUpperCase()); this.value.setAttribute('text', this.parent[this.state + 'title']); trackEvent('product', 'buyitbutton', this.parent.data.id) this.parent.parent.drawer.setAttribute('open', true); buy.show(this.parent.data); this.parent.parent.drawer.highlightCurrentTrack(); player.download(this.parent.data) this.parent.setAttribute('active', true) this.parent.setAttribute('active', false) this.setAttribute('data', data); // console.log('title', data, player.trackoffset) this.parent.cover.setAttribute('url', data.imageurl) var tracks = data.tracks; var tracklabel = tracks.length + ' track'; if (tracks.length > 1) tracklabel += 's'; this.setAttribute('releasetitle', data.release) this.setAttribute('titletitle', data.title) this.setAttribute('artisttitle', data.artist) this.setAttribute('labeltitle', data.label) this.setAttribute('released', data.released) this.setAttribute('tracks', tracklabel) var track = tracks[player.trackoffset] this.setAttribute('tracktitle', track.title) this.readout.update(); if (this.data) { var tracktitle = this.data.tracks[player.trackoffset].title; this.setAttribute('tracktitle', tracktitle) this.readout.setAttribute('state', 'label'); this.readout.update(); } return text.toUpperCase(); return text.toUpperCase(); this.setAttribute('active', ! this.active) if (! this.inited) return; if (show) { this.animate({height: 250}, 400) } else { this.animate({height: this.restingheight}, 400); this.setAttribute('active', false); } // hide if moused outside if (view && view !== this && view.parent && view.parent !== this.bg) { this.setAttribute('show', false) } this.setAttribute('show', true) this.setAttribute('url', data.imageurl) trackEvent('product', 'queueplay', this.data.id) // console.log('play', this.parent.parent) ghostalbum.show(this) this.setAttributes({visible: false}) var product = this.data; var _this = this; setTimeout(function() { // always start at first track when playing an album player.setAttribute('trackoffset', 0) player.play(product); _this.replicator.delete(product) }, 420) trackEvent('product', 'queueupnext', this.data.id) // console.log('upnext', upnext.subviews.length) upnext.add(this.data) var _this = this; setTimeout(function() { ghostalbum.show(_this, upnext.subviews[upnext.subviews.length - 1]) _this.setAttributes({visible: false}) _this.replicator.delete(_this.data) }, 33); trackEvent('product', 'queuedelete', this.data.id) this.destroy(); this.parent.parent.delete(); this.parent.parent.play(); this.parent.parent.upnext(); this.bg.upnext.setAttribute('visible', false) // var index = this.replicator.data.indexOf(this.data); // this.setAttribute('restingheight', ((77 - 50) * (index / (this.replicator.data.length - 1))) + 50) if (search.searchresult.data) { data = {tracks: search.searchresult.data}; } else if (playlist.data) { data = playlist.data; } // make a copy of the data to mutate this.setAttribute('data', JSON.parse(JSON.stringify(data))) var tracks = this.data.tracks.reverse() tracks.pop() this.repl.setAttribute('data', tracks) // console.log('add', track, arguments) // make a copy of the track to mutate this.tracks.push(JSON.parse(JSON.stringify(track))) this.setAttribute('tracks', this.tracks) var pos = dockalbum.getAbsolute(); console.log('show', dockalbum, pos) this.setAttributes({url: dockalbum.url, opacity: 1, x: pos.x, height: dockalbum.height}) var cover = target || playerui.cover; var coverpos = cover.getAbsolute() this.animate({height: cover.height, x: coverpos.x, opacity: .4}, 400) var _this = this; setTimeout(function() { _this.animate({opacity: 0}, 200) }, 420);