var current_id = ''; var player; var litColor = '#eee'; var dimmedColor = '#555'; var interval; var timestamp = '-1'; $(document).ready(function () { $('body').click(function (e) { if (e.target.id !== 'results') { $('#results').slideUp(100); } }); var userElem = $('#user'); if (localStorage['user'] && localStorage['user'].length > 0) userElem.val(localStorage['user']); userElem.change(function () { localStorage['user'] = userElem.val(); }); getUpdates(); }); function getUpdates() { $.ajax({ url: '/poll/', dataType: 'json', data: {pid: pid, timestamp: timestamp}, success: handleUpdates, error: function (_, textStatus) { switch (textStatus) { case 'abort': return; case 'error': case 'parsererror': setTimeout(getUpdates, 1000); return; default: getUpdates(); } } }); } function handleUpdates(data) { var updates = []; for (var i = 0; i < data.length; i++) { timestamp = data[i].Timestamp; var update = { 'action': data[i].Action, 'yid': data[i].Song.Yid, 'title': data[i].Song.Title, 'user': data[i].Song.User } switch (update.action) { case 0: // see updates.go:addAction drawAdd(update); break; case 1: drawRemove(update.yid); break; case 2: case 3: drawMove(update.yid, update.action); break; } } if (timestamp == '-1') timestamp = '0'; getUpdates(); } function drawBar(id) { var canvas = document.getElementById('c_' + id); if (!canvas) return; canvas.height = canvas.height; //clear if (current_id == id && player) { var context = canvas.getContext("2d"); context.fillStyle = dimmedColor; context.fillRect(0, 9, 700, 2); var loaded_start = player.getVideoStartBytes() / player.getVideoBytesTotal() * 700, loaded_length = player.getVideoBytesLoaded() / player.getVideoBytesTotal() * 700; context.fillStyle = litColor; context.fillRect(loaded_start, 9, loaded_length, 2); var current_time = player.getVideoStartBytes() + player.getCurrentTime(), current_pos = current_time / player.getDuration() * 690 + 5; context.beginPath(); context.arc(current_pos, 10, 5, 0, Math.PI * 2, false); context.closePath(); context.fill(); } } // function name is defined by youtube player api function onYouTubePlayerReady(playerId) { player = document.getElementById('player'); player.addEventListener('onStateChange', 'onStateChange'); } function onStateChange(state) { switch (state) { case 1: //playing interval = setInterval(drawBar, 100, current_id); break; case 0: //ended clearInterval(interval); showPlay(current_id); var songs = $('article section.song'); for (var i = 0; i < songs.length - 1; i++) { if (songs[i].id == current_id) { play(songs[i+1].id); break; } } case -1: //unstarted case 2: //paused case 3: //buffering case 5: //cued clearInterval(interval); } } function play(yid) { if (current_id != yid) { player.loadVideoById(yid, 0, 'hd720'); var previous_id = current_id; current_id = yid; drawBar(previous_id); } if (player.getPlayerState() in {'-1':1, '0':1, '5':1}) { // unstarted, ended, cued player.seekTo(0, true); } player.playVideo(); var songs = $('article section.song'); for (var i = 0; i < songs.length; i++) { if (songs[i].id == yid) showPause(songs[i].id); else showPlay(songs[i].id); } } function pause(yid) { if (current_id != yid) return player.pauseVideo(); showPlay(yid); } function stop(yid) { if (current_id != yid) return player.stopVideo(); showPlay(yid); drawBar(yid); } function showPlay(yid) { var play = document.getElementById('play_' + yid); var pause = document.getElementById('pause_' + yid); if (play) play.style.display = 'inline'; if (pause) pause.style.display = 'none'; } function showPause(yid) { var pause = document.getElementById('pause_' + yid); var play = document.getElementById('play_' + yid); if (pause) pause.style.display = 'inline'; if (play) play.style.display = 'none'; } function search(query) { params = { q: query, 'max-results': 10, v: 2, strict: true, alt: 'json', fields: 'entry(title,media:group(yt:videoid))', safeSearch: 'none', key: 'AI39si7SaaRqtvAZTa8lePOq6XC5r7S5Xzp3AB6oYPfeCArPbA4dIq7tSVeuIDwAkcFFDeI3rzNmYxkyN_fg8X_7w800pIvVOA' } $.getJSON('https://gdata.youtube.com/feeds/api/videos', params, function (data) { $('#results ul li').remove(); var results = $('#results ul'); var entries = data.feed.entry; for (var i = 0; i < entries.length; i++) { var title = entries[i].title.$t; var escapedTitle = title.replace(/'/g, "\\'").replace(/"/g, '\\"'); var id = entries[i].media$group.yt$videoid.$t; var li = $(document.createElement('li')) .attr('id', 'r_' + id) .append($(document.createElement('a')) .attr('href', "javascript:add('" + id + "', '" + escapedTitle + "')") .append($(document.createElement('img')) .attr('src', 'http://i.ytimg.com/vi/' + id + '/1.jpg') .attr('alt', id)) .append(title)); results.append(li); } $('#results').slideDown(100); } ); return false; } function userKeyPress(e) { if (e.keyCode == 13) {// enter $('#song').focus(); return false; } } function add(id, title) { params = { pid: pid, yid: id, title: title, user: $('#user').val() } $.getJSON('/add/', params); } function drawAdd(s) { $('article').append($(document.createElement('section')) .addClass('song').attr('id', s.yid) .append($(document.createElement('div')) .addClass('thumb') .append($(document.createElement('img')) .attr('src', 'http://i.ytimg.com/vi/' + s.yid + '/1.jpg') .attr('alt', s.yid) ) ) .append($(document.createElement('div')) .addClass('info') .append($(document.createElement('a')) .attr('href', 'http://www.youtube.com/watch?v=' + s.yid) .append(s.title) ) ) .append($(document.createElement('div')) .addClass('user') .append(s.user) ) .append($(document.createElement('div')) .addClass('remove') .append($(document.createElement('a')) .attr('href', 'javascript:remove("' + s.yid + '")') .append($(document.createElement('img')) .attr('src', '/static/remove.png') .attr('alt', 'remove') ) ) ) .append($(document.createElement('div')) .addClass('reorder') .append($(document.createElement('a')) .attr('href', 'javascript:move("' + s.yid + '", 2)') .append($(document.createElement('img')) .attr('src', '/static/up-arrow.png') .attr('alt', 'up') ) ) .append($(document.createElement('a')) .attr('href', 'javascript:move("' + s.yid + '", 3)') .append($(document.createElement('img')) .attr('src', '/static/down-arrow.png') .attr('alt', 'down') ) ) ) .append($(document.createElement('br'))) .append($(document.createElement('img')) .attr('src', '/static/player_play.png') .attr('alt', 'play') .attr('id', 'play_' + s.yid) .click(function() {play(s.yid)}) ) .append($(document.createElement('img')) .attr('src', '/static/player_pause.png') .attr('alt', 'pause') .attr('id', 'pause_' + s.yid) .click(function() {pause(s.yid)}) ) .append($(document.createElement('img')) .attr('src', '/static/player_stop.png') .attr('alt', 'stop') .click(function() {stop(s.yid)}) ) .append($(document.createElement('canvas')) .attr('id', 'c_' + s.yid) .attr('width', 700) .attr('height', 20) ) .append($(document.createElement('br')) .addClass('clear') ) ); } function remove(id) { params = { pid: pid, yid: id, } $.getJSON('/remove/', params); } function drawRemove(id) { var element = $('#' + id); stop(id); element.slideUp(100, function () { element.remove(); }); } function move(id, dir) { params = { pid: pid, yid: id, direction: dir // see updates.go:moveUpAction } $.getJSON('/move/', params); } function drawMove(id, dir) { var element1 = document.getElementById(id); if (dir == 2) { //up var element2 = element1.previousElementSibling; if (!element2) return; element1 = $('#' + id); element2 = $('#' + element2.id); element1.fadeOut(200, function () { element2.before(element1); element1.fadeIn(200); }); } else if (dir == 3) { //down var element2 = element1.nextElementSibling; if (!element2) return; element1 = $('#' + id); element2 = $('#' + element2.id); element1.fadeOut(200, function () { element2.after(element1); element1.fadeIn(200); }); } }