var _this = this; var ticking = false; window.addEventListener('scroll', function(e) { _this._x = window.scrollX; _this._y = window.scrollY; // console.log('scroll', _this._x, _this._y) if (!ticking) { window.requestAnimationFrame(function() { var body = document.body, html = document.documentElement; var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); _this._atbottom = (_this._y + window.innerHeight) >= height; if (_this._atbottom !== _this.atbottom) _this.setAttribute('atbottom', _this._atbottom); if (_this._x !== _this.x) _this.setAttribute('x', _this._x); if (_this._y !== _this.y) _this.setAttribute('y', _this._y); ticking = false; }); } ticking = true; }); 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 = {}; var parts = duration.split(':'); var secs = 0; if (parts.length === 1) { secs = parts[0] * 1; } else if (parts.length === 2) { secs = (parts[0] * 60) + (parts[1] * 1) } // console.log('secs', secs) return humanized_duration(secs * 1000) 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) this.firstload = true } // 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, pid: pid} this.setAttributes(args); // trackEvent('player', 'loading', this.pid) } 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); } if (data && data.tracks) { data.tracks.map(function(track) { if (! track.tracks) { track.tracks = [JSON.parse(JSON.stringify(track))] } }); } return data; // 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.trackoffset = trackoffset || 0; this.album.setAttribute('data', product) this.setAttribute('trackoffset', this.trackoffset) // skip if the first track wasn't a match var firsttrack = this.album.data.tracks[0]; if (firsttrack && firsttrack.found === false) { // console.log('play next', firsttrack) this.next(); } // console.log('product', this.album.data, this.playlist.data) var tracks = [] if (this.album.data) { tracks = this.album.data.tracks; } if (tracks.length > 1 && this.trackoffset + 1 < tracks.length && ((! this.currenttrackonly) || (playerui.drawer.open))) { this.currenttrackonly = false; // store history var track = tracks[this.trackoffset]; track.trackoffset = this.trackoffset; this._history.push(track); if ('found' in track) { var foundoffset = 1; // marked to only play some tracks, find the offset of the one to be played while ((this.trackoffset + foundoffset) < tracks.length) { track = tracks[this.trackoffset + foundoffset] if (track.found) { // console.info('found next track', track, track.keywords) this.setAttribute('trackoffset', this.trackoffset + foundoffset) return; } foundoffset++; } // console.info('next next', track) queues.next(); return; } // play next track in album this.setAttribute('trackoffset', this.trackoffset + 1) } else { // console.info('exception next', track) this.currenttrackonly = false; queues.next(); } // 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 this.setAttribute('trackoffset', track.trackoffset) songredirect.getURL(pid, function(url) { audio.playTrack(url, pid); }); } // don't add the currently playing product if (product.id == this.productid) return; // don't add the track that's playing to the list for (var i = 0, l = upnext.tracks.length; i < l; i++) { var track = upnext.tracks[i]; if (product.id == track.id) { return; } } var tracks = queues.queue.repl.children; // console.log('add', tracks, this.playlist) for (var i = 0, l = tracks.length; i < l; i++) { var child = tracks[i]; if (product.id == child.data.id) { // move to up next child.upnext(); return; } } // add to the end of the playlist upnext.add(product); // this.playlist.setAttribute('data', this.playlist.data); // if (! this.productid) { // this.setAttribute('playlistoffset', 0); // } buy.show(product); if (! persist.format) { persist.set('format', '320MP3') } var url = EMT + '/product/download/' + product.id + '?type=' + persist.format; trackEvent('product', 'download', product.id, persist.format) //console.log('download', url, product) buy.buywindow.setAttribute('src', url); //this.downloadwindow.setAttribute('src', url) if (persist.paused) { audio.setAttribute('playing', true) audio.setAttribute('paused', true) } if (err.msg === 4) { // aws timeout, force reload songredirect.cache = null songredirect.getURL(audio.pid, function(url) { // console.log('forcing reload', audio.audio, audio.pid) audio.setAttributes({url: url, 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 this.setAttribute('audio', track.audio) songredirect.getURL(pid, function(url) { audio.playTrack(url, pid); }); var nexttrack = tracks[trackoffset + 1]; if (nexttrack) { // prefetch URL for next track setTimeout(function() { songredirect.getURL(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 + '/product/stream/' + 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] } if (text === 'Dope') text = 'Recommended' return text.toUpperCase() search.keywords = {}; search.keywords[this.text] = true; taglist.reset(); search.doSearch(); var data = this.features && this.features.data; if (! data) return offset; if (offset >= this.features.data.tracks.length) offset = 0; return offset; if (pid > 0) this.color.setAttribute('url', '/product/colors/' + pid) // console.log('data', data) var color = data[0] this.colorbanner.setAttribute('bgcolor', color.color) this.bg.setAttributes({color: color.dark ? 'white' : 'black', bgcolor: color.color}) var _this = this; setInterval(function() { if (! _this.bg.active) _this.setAttribute('offset', _this.offset + 1) }, 10000) this.active = false; if (view && (view === this || view.parent === this || view.parent.parent === this)) { this.active = true; } this.parent.setAttribute('offset', this.parent.offset + 1) var data = this.parent.features.data if (! data) return; this.setAttribute('visible', true) // console.log('update', data) var feature = data.tracks[this.parent.offset]; this.setAttribute('feature', feature); this.parent.setAttribute('pid', feature.id) this.cover.setAttribute('url', feature.imageurl); this.artist.setAttribute('text', feature.artist); this.release.setAttribute('text', feature.release); var tracks = (feature.tracks && feature.tracks.length) || 1; this.labeldate.tracks.setAttribute('text', tracks + ' track' + (tracks > 1 ? 's' : '')); this.labeldate.label.setAttribute('text', feature.label); this.labeldate.released.setAttribute('text', feature.released); this.description.setAttributes({text: feature.description || '', scrolly: 0}); this.rule.setAttribute('visible', feature.description && feature.description.length) this.tags.setAttribute('data', feature.keywords) var product = this.feature; trackEvent('product', 'playingfeature', product.id) // always start at first track when playing an album player.setAttribute('trackoffset', 0) if (! product.tracks) product.tracks = [product] player.play(product); this.setAttribute('y', 160 - y) // this.repl.setAttribute('datapath', this.repl.datapath) {"tags": [ {"name":"Ambient"}, {"name":"Beats"}, {"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":"Halftime"}, {"name":"Heavy"}, {"name":"Hip Hop"}, {"name":"House"}, {"name":"Idm"}, {"name":"Midtempo"}, {"name":"Organic"}, {"name":"Progressive"}, {"name":"Ragga"}, {"name":"Techfunk"}, {"name":"Techno"}, {"name":"Trap"}, {"name":"Tribal"}, {"name":"Vocal"} ] } if (data && data.tracks) { data.tracks.map(function(track) { if (! track.tracks) { track.tracks = [JSON.parse(JSON.stringify(track))] } }); } return data; if (! this.url) return; // console.warn('init playlist', window.location.hash, this.url, window.location.hash.indexOf(this.url) != -1) if (window.location.hash.indexOf(this.url) != -1) { this.play(); } if (! this.url) return; // console.warn('updateref', window.location.hash, this.url, window.location.hash.indexOf(this.url) != -1) if (window.location.hash.indexOf(this.url) != -1) { queues.setAttribute('playlist', this); } // console.log('playlist.play', this.url) if (this.playlist.data) queues.play(this.playlist.data) queues.setAttribute('playlist', this); this.start = 0; window.location.hash = '/playlist' + this.url; var size = this.playlist.data.meta.size; // console.log('nextpage', this.start + 25, size) if (this.start + 25 < size){ this.start += 5; window.location.hash = '/playlist' + this.url + '?start=' + this.start } trackEvent('playlist', 'play', this.parent.playlist.data.title) this.parent.play(); this.playlisttitle.setAttribute('data', data.title) this.container.repl.setAttribute('data', data.tracks) this.playbutton.setAttribute('visible', true) queues.play(search.searchresult.data) queues.setAttribute('playlist', this); this.start = 0; window.location.hash = search.searchresult.url; this.url = search.searchresult.url; queues.setAttribute('playlist', this); this.playlist.setAttributes({data: data, visible: true}) this.setAttribute('size', data.meta.size); queues.play(this.playlist.data) queues.setAttribute('playlist', this); window.location.hash = '/playlist/product/purchased/details'; this.refresh(); if (loggedin) { this.refresh(); } this.setAttribute('url', EMT + '/product/purchased/details') if (! data) return; // console.log('ondata', data) this.left.title.setAttribute('text', data.title) if (this.left.artist) this.left.artist.setAttribute('text', data.artist) if (this.left.label) this.left.label.setAttribute('text', data.label) this.left.tags.setAttribute('data', data.keywords) if (this.released) this.released.setAttribute('text', data.released) this.duration.setAttribute('text', data.duration) if (this.cover) this.cover.setAttribute('url', data.imageurl) var owned = player.purchased && player.purchased[this.data && this.data.id] // console.log('onpurchased', owned, purchased) if (owned !== this.owned) this.setAttribute('owned', owned) return humanizer.getDuration(text); trackEvent('product', 'buyitbutton', this.parent.data.id) buy.show(this.parent.data); // console.log('play', this.data) trackEvent('product', 'playingsearchresultitem', this.data.id) player.play(this.data); var product = searchresultpage.data.tracks[0]; // console.log('play', product, this.index) trackEvent('product', 'playingsearchresulttrack', product.tracks[this.index].id) player.play(product); player.setAttribute('trackoffset', this.index) if (! data) return; data = JSON.parse(JSON.stringify(data)); var firsttrack = data.tracks[0]; if (! firsttrack) return; this.header.setAttribute('url', firsttrack.imageurl) this.colorz.setAttribute('url', '/product/colors/' + firsttrack.id) this.first.setAttribute('data', firsttrack) var therest = data.tracks.slice(1); this.therest.items.setAttribute('data', therest) var showtracks = therest.length === 0; this.therest.tracks.setAttribute('data', showtracks ? firsttrack.tracks : []) this.therest.label.setAttribute('visible', ! showtracks) this.therest.playbutton.setAttribute('visible', ! showtracks) // console.log('searchresult', data) this.start = data.tracks.length; // console.log('colorz', data) var color = data[0] this.first.setAttributes({color: color.dark ? 'white' : 'black'}) this.first.bg.setAttributes({bgcolor: color.color}); this.colorbanner.setAttribute('bgcolor', color.color) var url = search.searchresult.url; if (this.start) url += '?start=' + this.start || 0; // console.log('atbottom', atbottom, url) if (! atbottom) return; this.additionalresults.setAttribute('url', url) this.data.tracks = this.data.tracks.concat(data.tracks); this.start = this.data.tracks.length; // console.log('ondata', data, this.start) this.updateResults(this.data); var text = ''; var type = search.type; if (type === 'artist') { text = 'Discography for ' + search.term; } else if (type === 'label') { text = 'Catalog for ' + search.term; } this.setAttribute('text', text) trackEvent('product', 'playingsearchresult', playlists.searchresult.playlisttitle.text) queues.setAttribute('playlist', playlists.searchresult); playlists.searchresult.play(); // console.log('paused', audio); if (audio.paused) { audio.togglePaused(); } var pos = Math.max(-4, 58 - scroll.y) if (pos !== this.pos) this.setAttribute('pos', pos) var max = 870; var min = this.width - 560; var delta = max - min; var searchwidth = min + ((pos / 58) * delta) // console.log('pos', pos, searchwidth) // searchwidth = Math.max(searchwidth, 875) if (searchwidth !== this.searchwidth) this.setAttribute('searchwidth', searchwidth) if (login.loggedin) { playlists.downloads.play() } else { login.toggleLogin() } this.keywords = {} this.doSearch(); var _this = this; var readHash = function() { var hash = decodeURI(window.location.hash).substring(1) _this.setAttribute('hash', hash) searchresultpage.setAttribute('visible', false) if (hash.indexOf('/search/') === 0) { _this.searchresult.setAttribute('url', hash); searchresultpage.setAttribute('visible', true) // 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) { // console.log('terms', terms) var parts = terms.split('/') search.setAttributes({type: parts[0], term: parts[1]}) searchpopover.setAttribute('enabled', false) searchinput.setAttribute('text', parts[1]) searchpopover.setAttribute('enabled', true) } } return; } else if (hash.indexOf('/playlist/') === 0) { // load playlist var playlisturl = hash.substring(10, hash.length); if (playlisturl === 'product/purchased/details') { playlisturl = EMT + '/product/purchased/details' } // console.log('loading playlist from url', playlisturl) return playlist.setAttribute('url', playlisturl) } else if (hash.indexOf('/account/') === 0) { login.container.loginwindow.setAttributes({src: EMT + hash}) } // load features playlist by default window.location.hash = '/playlist/recommended' } $(window).on('hashchange',readHash); readHash(); if ((! this.term) && (Object.keys(this.keywords).length) == 0) return; var url = '' var keywords = []; for (var key in this.keywords) { if (this.keywords[key]) { keywords.push(key) } } if (keywords.length) { var url = '/search/keywords/' + keywords.join(','); } else { if (this.term.length < 2) return; if (this.type) { var url = '/search/' + this.type + '/' + this.term; } else { var url = '/search/' + this.term; } } this.searchresult.setAttribute('url', url) if (data && data.tracks) { data.tracks.map(function(track) { if (! track.tracks) { track.tracks = [JSON.parse(JSON.stringify(track))] } }); } return data; if (! data) return window.location.hash = this.searchresult.url; if (text) { var words = text.split(' '); text = words[words.length - 1]; var url = '/search/suggest/' + text.toLowerCase(); if (url !== this.suggestionds.url) this.suggestionds.setAttribute('url', url) } out = data.map(function(suggestion) { return suggestion[0]; }) return out; // console.log('suggestionds data', data) this.repl.setAttribute('data', data) this.data = data; trackEvent('search', 'suggestion', this.text) // replace last word var words = searchinput.text.split(' '); words[words.length - 1] = this.text; var newtext = words.join(' ') + ' ' searchinput.setAttributes({text: newtext, value: newtext}) return text.toUpperCase(); // console.log('term', term.length, term) if (term.length < 2) return; var url = '/search/' + term.toLowerCase(); if (url !== this.searchpopoverds.url) { this.searchpopoverds.setAttribute('url', url) } this.setAttribute('visible', true) if (! this.enabled) return var text = searchinput.text; if (! text) { this.setAttribute('visible', false) } else { this.setAttribute('term', text); suggestions.setAttribute('text', text) } if (error.readyState !== 4) return; // console.log('onerror', error) // find first suggestion that doesn't match the most recent var terms = suggestionds.data; if (! terms) return; for (var i = 0; i < terms.length; i++) { var term = terms[i].toLowerCase(); if (term != this.term.toLowerCase() && term.indexOf(searchinput.text.toLowerCase()) != -1) { // console.log('new suggestion', term) this.setAttribute('term', term); return; } } // console.log('ondata', data) // console.log('data', data.meta) var freq = data.meta.freq var tracks = data.tracks var buckets = data.meta.buckets for (key in buckets) { var val = buckets[key].splice(0,2) val.key = key; // console.log('buckets', key, val, this[key + 's']) this[key + 's'].repl.setAttribute('data', val) } this.term = search.term; this.setAttribute('visible', true) // hide if clicked outside if ((! view) || (view !== this && view.parent !== this && view.parent.parent !== this && view.parent.parent.parent !== this && view !== searchinput)) { this.setAttribute('visible', false) } var val = this.labels.label.text; trackEvent('search', 'result', val) search.setAttributes({type: this.type, term: val}) searchinput.setAttributes({text: val, value: val}) searchpopover.setAttribute('visible', false) var product = this.parent.data.product; trackEvent('product', 'playingsearchpopup', product.id) // always start at first track when playing an album player.setAttribute('trackoffset', 0) if (! product.tracks) product.tracks = [product] player.play(product); var type = this.replicator.data.key this.type = type; var color = this.stripcolors[type] // console.log('ondata', data, type) this.cover.setAttribute('url', data.product.imageurl) this.labels.label.setAttribute('text', data.name) this.labels.kind.setAttributes({text: type, color: color}) return text.toUpperCase(); search if (this._tid !== null) { clearTimeout(this._tid); } var keyCode = key.keyCode if (keyCode === 27) { return searchpopover.setAttribute('visible', false) } this._tid = setTimeout(this._update, this.delay); this.setAttribute('value', this.text) if (text === 'undefined') return ''; // console.log('format', text) return accounting.formatMoney(text) + ' earned'; if (login.loggedin) { trackEvent('user', 'logout') } else { trackEvent('user', 'login') } this.parent.toggleLogin(); this.loggedinds.setAttribute('url', EMT + '/account/loggedIn') var loggedin = data.loggedIn; if (loggedin != this.loggedin) this.setAttribute('loggedin', loggedin) if (data.totalEarned) this.setAttribute('totalEarned', data.totalEarned) if (loggedin) { // trackEvent('user', 'loggedin') this.container.setAttribute('visible', false) songredirect.cache = null } // console.log('toggleLogin', this.loggedin) if (this.loggedin) { window.location = EMT + '/account/logout' } else { this.container.setAttributes({visible: true}) this.container.loginwindow.setAttributes({src: EMT + '/account/login'}) // console.log('loginwindow', this.loginwindow.visible, this.loginwindow.src, this.loginwindow.sprite) } if (loggedin) { // load purchases this.purchased_ds.setAttribute('url', EMT + '/product/purchased') // refresh login details this.refreshLogin(); } // 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, player.purchased) player.setAttribute('purchased', ids) 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 + '/product/checkout/' + 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 + '/product/purchased') trackEvent('product', 'bought', pid) this.buywindow.setAttributes({visible: true, clickable: true, opacity: 1, src: EMT + '/product/download/menu/' + this.data.id}); // this.downloads.setAttribute('visible', true); this.failed.setAttribute('visible', false); login.refreshLogin(); dr.datasets.purchased_ds.setAttribute('url', EMT + '/product/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:'}); this.setAttribute('open', false) player.download(product) if (! this.data) return; if (! open) { trackEvent('product', 'closed', this.data.id) this.buywindow.setAttribute('visible', false) } if (! this.open) return; if (loggingin == false) { this.show(this.data) } var owned = player.purchased && player.purchased[this.data && this.data.id] // console.log('buywindow', owned) this.labels.action.setAttribute('text', owned ? 'You are downloading' : 'You are buying') this.labels.price.setAttribute('visible', ! owned) this.labels.pricelabel.setAttribute('visible', ! owned) this.labels.border.setAttribute('visible', ! owned) this.labels.includes.setAttribute('visible', ! owned) You are buying Price Includes unlimited streaming and MP3, FLAC, and WAV downloads Purchase failed. Please try another payment method: 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}); } if (player.album.data) { var track = player.album.data.tracks[player.trackoffset] this.parent.parent.playerui.setAttribute('artisttitle', track.artist) var taglist = track.keywords.sort(); this.tags.repl.setAttribute('data', taglist) } // 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.play(data, trackoffset); player.setAttributes({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; } var track = player.album.data.tracks[player.trackoffset] this.parent.parent.playerui.setAttribute('artisttitle', track.artist) var taglist = track.keywords.sort(); this.tags.repl.setAttribute('data', taglist) 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(); } var text = this.text//.toLowerCase(); trackEvent('search', 'label', this.text) searchinput.setAttributes({text: text, value: text}) 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) 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 track = this.data.tracks[player.trackoffset]; this.setAttribute('tracktitle', track.title) this.setAttribute('artisttitle', track.artist) this.readout.setAttribute('state', 'label'); this.readout.update(); } this.queue.locked = false; this.queue.updateQueue(tracks) setTimeout(function() {queues.next()}, 100); if (upnext.tracks.length){ var q = upnext; } else { var q = this.queue; } var children = q.repl.children; var lastchild = children[children.length - 1]; // console.info('next', next, q, q.tracks) if (lastchild && lastchild.inited && lastchild.visible) { children.pop(); // console.log('lastchild', lastchild) lastchild.play(); } else { var next = q.tracks.pop(); // console.info('play', next) player.play(next) } if (this.playlist && this.playlist.nextpage && children.length < 21 && children.length > 0) { // console.warn('length', children.length, this.playlist) this.playlist.nextpage(); } // lock to prevent updates except when queues.play() is called (from a user) if (this.locked) return; this.locked = true; // console.log('updateQueue', data) // make a copy of the data to mutate var data = JSON.parse(JSON.stringify(data)); var tracks = data.tracks.reverse() if (tracks) { this.tracks = tracks; if (! (audio.playing && audio.url)) { // play first track of first result, but don't interrupt current audio playback this.parent.next(); } // console.info('data', audio.playing, audio.url, tracks) this.setAttribute('tracks', 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);