Files
MarietjeDjango/marietje/marietje/static/js/queue.js
2018-11-23 15:58:42 +01:00

365 lines
12 KiB
JavaScript

var currentDuration = 0;
var timeOffset = 0;
var timeStarted = 0;
var currentSong = null;
var queue = null;
var songs = [];
var refreshing = false;
var iteration = 0;
var requestViewOpen = false;
var showTimeToPlay = true;
var noRemove = false;
$(function () {
$('.pagesize').val(Cookies.get('pagesize'));
showTimeToPlay = (Cookies.get('showtimetoplay') || '1') === '1' ? true : false;
$('#queue-time-header').text(showTimeToPlay ? 'Plays In' : 'Plays At');
refreshQueue();
setInterval(updateTime, 1000);
$('#skip').click(function () {
$.post('/api/skip', {csrfmiddlewaretoken: csrf_token}, function () {
refreshQueue();
});
return false;
});
$('#request-button').click(function () {
requestViewOpen ? hideRequestTable() : showRequestTable();
});
$(document).on('click', '[data-song-id]', function () {
var songId = $(this).data('song-id');
$.post('/api/request', {id: songId, csrfmiddlewaretoken: csrf_token}, function (result) {
if(result.success) {
refreshQueue();
} else {
// Close request table and show message.
hideRequestTable();
createAlert('danger', result.message);
}
});
$(this).parent().text($(this).text());
return false;
});
$('#cancel-request').click(function () {
hideRequestTable();
});
$('.pagenum').change(function(){
getSongs();
});
$('#search-all, #search-uploader').change(function(){
$('.pagenum').val(1);
getSongs();
});
$('.pagesize').change(function(){
Cookies.set('pagesize', $(this).val(), { expires: 365 });
$('.pagenum').val(1);
getSongs();
});
$('button.prev').click(function(){
var pageNumSelect = $('.pagenum');
pageNumSelect.val(Math.max(parseInt(pageNumSelect.val()) - 1, 1));
getSongs();
});
$('button.next').click(function(){
var pageNumSelect = $('.pagenum');
pageNumSelect.val(Math.min(parseInt(pageNumSelect.val()) + 1, pageNumSelect.children('option:last-child').val()));
getSongs();
});
$('button.first').click(function(){
$('.pagenum').val(1);
getSongs();
});
$('button.last').click(function(){
var pageNumSelect = $('.pagenum');
pageNumSelect.val(pageNumSelect.children('option:last-child').val());
getSongs();
});
$('#volume-down').click(function(e){
e.preventDefault();
$.post('/api/volumedown', {csrfmiddlewaretoken: csrf_token});
});
$('#volume-up').click(function(e){
e.preventDefault();
$.post('/api/volumeup', {csrfmiddlewaretoken: csrf_token});
});
$('#mute').click(function(e){
e.preventDefault();
$.post('/api/mute', {csrfmiddlewaretoken: csrf_token});
});
$(document).on('touchstart', '.artist, .title', function(){
noRemove = true;
setTimeout(function(){ noRemove = false; }, 500);
$('.song-info').remove();
var row = $(this).parent();
var timeLeft = row.find('.time-left');
var playsAt = row.find('.plays-at');
var text = timeLeft[0] ? 'Time Left: ' + timeLeft.text() : 'Plays At: ' + playsAt.text();
$('body').append('<span class="song-info">Requested By: ' + row.find('.requested-by').text() + '<br>' + text
+ '</span>');
var offset = row.offset();
$('.song-info').css('top', offset.top + row.height())
.css('left', offset.left).css('backgroundColor', '#EEEEEE').width(row.width() - 16);
});
$(document).on('click', function(){
if(!noRemove) {
$('.song-info').remove();
}
});
$('#queue-time-header').click(function(){
showTimeToPlay = !showTimeToPlay;
$('#queue-time-header').text(showTimeToPlay ? 'Plays In' : 'Plays At');
Cookies.set('showtimetoplay', showTimeToPlay ? '1' : '0', { expires: 365 });
});
getSongs();
});
function cancelSong(id)
{
$.post('/api/cancel', {id: id, csrfmiddlewaretoken: csrf_token}, function () {
refreshQueue();
});
return false;
}
function moveUp(id)
{
$.post('/api/moveup', {id: id, csrfmiddlewaretoken: csrf_token}, function () {
refreshQueue();
});
return false;
}
function moveDown(id)
{
$.post('/api/movedown', {id: id, csrfmiddlewaretoken: csrf_token}, function () {
refreshQueue();
});
return false;
}
function updateTime()
{
var timestamp = Date.now() / 1000 | 0;
var secondsLeft = currentSong.song.duration - (timestamp - timeStarted) + timeOffset;
iteration = (iteration + 1) % 10;
if (secondsLeft >= 0)
{
$('.currentsong .time-left').text(secondsLeft.secondsToMMSS());
refreshSeconds(secondsLeft + timestamp, timestamp);
}
// Refresh every ten seconds, or if the song has ended in the last ten
// seconds. Only if it is not refreshing already.
if ((iteration === 0 || secondsLeft <= 0 && secondsLeft > -10) && !refreshing)
{
refreshQueue();
}
}
function renderQueue(playNextAt, now)
{
$('.queuebody').empty();
var timeToPlay = playNextAt - now;
$.each(queue, function (id, song) {
var requestedBy = song.requested_by;
var canDelete = song.can_move_down || canMoveSongs;
var canMoveDown = canDelete && id < queue.length - 1;
var artist = song.song.artist.trim() === '' ? '?' : song.song.artist;
var title = song.song.title.trim() === '' ? '?' : song.song.title;
showTime = showTimeToPlay ? (timeToPlay < 0 ? '' : timeToPlay.secondsToMMSS()) : (playNextAt < now ? '' : playNextAt.timestampToHHMMSS())
$('.queuebody:last-child').append('<tr><td class="artist">' + artist
+ '</td><td class="title">' + title + '</td><td class="hidden-xs requested-by">' + requestedBy
+ '</td><td class="hidden-xs plays-at" style="text-align: right;">' + showTime
+ '</td><td>' + '<a href="#" class="glyphicon glyphicon-arrow-up'
+ (canMoveSongs && id !== 0 ? '' : ' invisible')
+ '" onclick="return moveUp(' + song.id
+ ')"></a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" class="glyphicon glyphicon-arrow-down'
+ (canMoveDown ? '' : ' invisible') + '" onclick="return moveDown('
+ song.id + ')"></a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" class="glyphicon glyphicon-trash'
+ (canDelete ? '' : ' invisible') + '" onclick="return cancelSong('
+ song.id + ')"></a></td></tr>');
timeToPlay += parseInt(song.song.duration);
if(playNextAt >= now)
{
playNextAt += parseInt(song.song.duration);
}
});
}
function refreshQueue()
{
refreshing = true;
$.get('/api/queue', function (result) {
var now = Date.now() / 1000 | 0;
if (timeOffset === 0)
{
// Calculate time offset with the server.
timeOffset = now - result.current_time;
}
timeStarted = result.started_at;
currentSong = result.current_song;
queue = result.queue;
var playNextAt = timeStarted + timeOffset + parseInt(currentSong.song.duration);
var requestedBy = currentSong.requested_by;
$('.currentsong .artist').text(currentSong.song.artist);
$('.currentsong .title').text(currentSong.song.title);
$('.currentsong .requested-by').text(requestedBy);
if (currentSong.can_skip || canSkip)
{
$('#skip').addClass('glyphicon glyphicon-fast-forward');
}
else
{
$('#skip').removeClass('glyphicon glyphicon-fast-forward');
}
renderQueue(playNextAt, now);
updateTime();
refreshing = false;
});
}
function refreshSeconds(playNextAt, now)
{
if(!showTimeToPlay) {
return;
}
var timeToPlay = playNextAt - now;
times = $('.plays-at');
$.each(queue, function (id, song) {
$(times[id]).text(timeToPlay < 0 ? '' : timeToPlay.secondsToMMSS());
timeToPlay += parseInt(song.song.duration);
});
}
function getSongs()
{
var all = $('#search-all').val();
var uploader = $('#search-uploader').val();
var page = $('.pagenum').val();
var pagesize = $('.pagesize').val();
$.post('/api/songs', {all: all, uploader: uploader, page: page, pagesize: pagesize, csrfmiddlewaretoken: csrf_token}, function (result) {
$('#request-table tbody').empty();
songs = result.data;
$.each(songs, function (id, song) {
var artist = song.artist.trim() === '' ? '?' : song.artist;
var title = song.title.trim() === '' ? '?' : song.title;
$('#request-table tbody:last-child').append('<tr><td>' + artist + '</td><td><a href="#" data-song-id="' + song.id + '">' + title + '</a></td><td>' + (song.uploader_name ? song.uploader_name : 'Marietje') + '</td><td>' + song.duration.secondsToMMSS() + '</td></tr>');
});
var pageNumSelect = $('.pagenum');
pageNumSelect.empty();
for(var i = 1; i < result.last_page + 1; i++)
{
pageNumSelect.append($("<option></option>")
.attr("value", i)
.text(i));
}
pageNumSelect.val(result.current_page);
$('.pagesize').val(result.per_page);
$('button.first').prop('disabled', result.current_page == 1);
$('button.prev').prop('disabled', result.current_page == 1);
$('button.next').prop('disabled', result.current_page == result.last_page);
$('button.last').prop('disabled', result.current_page == result.last_page);
refreshingSongs = false;
if(requestViewOpen) {
window.scrollTo(0, 0);
}
});
}
function showRequestTable()
{
$('#request-button').text('Close');
$('#queue-container').hide();
$('#request-container').removeClass('hidden');
$('#request-container').show();
$('#search-all').focus().select();
requestViewOpen = true;
}
function hideRequestTable()
{
$('#request-button').text('Request');
$('#request-container').hide();
$('#queue-container').show();
requestViewOpen = false;
}
// For IE8 and earlier.
if (!Date.now) {
Date.now = function () {
return new Date().getTime();
}
}
// Edited from https://stackoverflow.com/a/6313008.
Number.prototype.secondsToMMSS = function () {
var hours = Math.floor(this / 3600);
var minutes = Math.floor((this - (hours * 3600)) / 60);
var seconds = this - (hours * 3600) - (minutes * 60);
var sep1 = ''
if (hours > 0) {
hours = hours;
sep1 = ':';
} else {
hours = '';
}
if (hours > 0 && minutes < 10) minutes = '0' + minutes;
if (seconds < 10) seconds = '0' + seconds;
return hours + sep1 + minutes + ':' + seconds;
}
Number.prototype.timestampToHHMMSS = function () {
var date = new Date(this * 1000);
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
if (hours < 10) {
hours = '0' + hours;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds < 10) {
seconds = '0' + seconds;
}
return hours + ':' + minutes + ':' + seconds;
}
function createAlert(type, message) {
alertText = '<div class="alert alert-' + type + ' alert-dismissable">'+
'<button type="button" class="close" ' +
'data-dismiss="alert" aria-hidden="true">' +
'&times;' +
'</button>' +
message +
'</div>';
$('body > div.container').prepend(alertText);
}