diff --git a/marietje/api/views.py b/marietje/api/views.py index 5dc453e..9df9c58 100644 --- a/marietje/api/views.py +++ b/marietje/api/views.py @@ -168,12 +168,25 @@ def managesongs(request): @api_auth_required def queue(request): queue = request.user.queue - return JsonResponse({ + infobar = {"start_personal_queue": 0, "length_personal_queue": 0, "length_total_queue": 0, "end_personal_queue": 0} + for song in queue.queue(): + infobar["length_total_queue"] += song.song.duration + if song.user == request.user: + infobar["length_personal_queue"] += song.song.duration + infobar["end_personal_queue"] = infobar["length_total_queue"] + if infobar["start_personal_queue"] == 0: + infobar["start_personal_queue"] = infobar["length_total_queue"] - song.song.duration + + + json = { 'current_song': playlist_song_to_dict(queue.current_song()), 'queue': [playlist_song_to_dict(playlist_song, user=request.user) for playlist_song in queue.queue()], 'started_at': 0 if queue.started_at is None else int(queue.started_at.timestamp()), - 'current_time': int(time.time()) - }) + 'current_time': int(time.time()), + 'user_name': request.user.name, + 'infobar': infobar, + } + return JsonResponse(json) @api_auth_required @@ -216,10 +229,10 @@ def request(request): err = queue.request(song, request.user) if err != None: - return JsonResponse({ 'success': False, 'message': err }) + return JsonResponse({'success': False, 'message': err}) request_counter.labels(queue=queue.name).inc() - return JsonResponse({ 'success': True }) + return JsonResponse({'success': True}) @require_http_methods(["POST"]) @@ -230,7 +243,8 @@ def report(request): msg = request.POST.get('msg') err = song.report(request.user, msg) - return JsonResponse({ 'success': True }) + + return JsonResponse({'success': True}) @require_http_methods(["POST"]) diff --git a/marietje/marietje/static/css/custom.css b/marietje/marietje/static/css/custom.css index c9e8d79..a542c6f 100644 --- a/marietje/marietje/static/css/custom.css +++ b/marietje/marietje/static/css/custom.css @@ -11,7 +11,7 @@ padding: 8px; background: silver; white-space: nowrap; - z-index: 9999; + z-index: 1; } #queue-time-header { @@ -26,6 +26,26 @@ footer { color: #777777; } -.marietjequeue-start { - border-top: 4px double #777777; -} \ No newline at end of file +.marietjequeue-pre-start td { + border-bottom: 3px double #777777; +} + +.block-button { + border-color: #cccccc; + color: #337ab7; + transition: 1s transform ease-in-out; +} + +.currentsong{ + border-bottom: 1px solid #DDDDDD; +} + +.requested_song .plays-at, .requested_song .requested-by { + font-weight: bold; +} + +.table-header-style td, .table-header-style{ + border-top: 3px solid #FFFFFF; + background-color: #f9f9f9; + border-bottom: 2px solid #777777; +} diff --git a/marietje/marietje/static/js/queue.js b/marietje/marietje/static/js/queue.js index 7fc0758..79df584 100644 --- a/marietje/marietje/static/js/queue.js +++ b/marietje/marietje/static/js/queue.js @@ -3,18 +3,19 @@ var timeOffset = 0; var timeStarted = 0; var currentSong = null; var queue = null; +var infobar = null; var songs = []; - var refreshing = false; var iteration = 0; var requestViewOpen = false; var showTimeToPlay = true; var noRemove = false; - +var user_name; +var playNextAt = 0; $(function () { $('.pagesize').val(Cookies.get('pagesize')); - showTimeToPlay = (Cookies.get('showtimetoplay') || '1') === '1' ? true : false; + showTimeToPlay = ((Cookies.get('showtimetoplay') || '1') === '1' ? true : false); $('#queue-time-header').text(showTimeToPlay ? 'Plays In' : 'Plays At'); refreshQueue(); setInterval(updateTime, 1000); @@ -48,12 +49,12 @@ $(function () { $(document).on('click', '[data-report-song-id]', function () { var songId = $(this).data('report-song-id'); var message = prompt("What is wrong with the song?"); - if (message == "") { + if (message === "") { createAlert('danger', 'Please enter a message.'); - return false + return false; } - if (message == null) { - return false + if (message === null) { + return false; } $.post('/api/report', {id: songId, msg: message, csrfmiddlewaretoken: csrf_token}, function (result) { if (result.success) { @@ -105,12 +106,12 @@ $(function () { getSongs(); }); - $('#volume-down').click(function(e){ + $('#volume_down').click(function(e){ e.preventDefault(); $.post('/api/volumedown', {csrfmiddlewaretoken: csrf_token}); }); - $('#volume-up').click(function(e){ + $('#volume_up').click(function(e){ e.preventDefault(); $.post('/api/volumeup', {csrfmiddlewaretoken: csrf_token}); }); @@ -127,7 +128,7 @@ $(function () { 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(); + var text = (timeLeft[0] ? 'Time Left: ' + timeLeft.text() : 'Plays At: ' + playsAt.text()); $('body').append('Requested By: ' + row.find('.requested-by').text() + '
' + text + '
'); var offset = row.offset(); @@ -141,104 +142,107 @@ $(function () { } }); - $('#queue-time-header').click(function(){ + $('#timeswitch').click(function(){ showTimeToPlay = !showTimeToPlay; - $('#queue-time-header').text(showTimeToPlay ? 'Plays In' : 'Plays At'); - Cookies.set('showtimetoplay', showTimeToPlay ? '1' : '0', { expires: 365 }); + $('.timeswitcher').toggleClass('active'); + $('#timeswitch').text(showTimeToPlay ? 'Plays In' : 'Plays At'); + Cookies.set('showtimetoplay', (showTimeToPlay ? '1' : '0'), { expires: 365 }); + refreshQueue(); }); getSongs(); }); -function cancelSong(id) -{ +function cancelSong(id) { $.post('/api/cancel', {id: id, csrfmiddlewaretoken: csrf_token}, function () { refreshQueue(); }); return false; } -function moveUp(id) -{ +function moveUp(id) { $.post('/api/moveup', {id: id, csrfmiddlewaretoken: csrf_token}, function () { refreshQueue(); }); return false; } -function moveDown(id) -{ +function moveDown(id) { $.post('/api/movedown', {id: id, csrfmiddlewaretoken: csrf_token}, function () { refreshQueue(); }); return false; } -function updateTime() -{ +function updateTime() { var timestamp = Date.now() / 1000 | 0; var secondsLeft = currentSong.song.duration - (timestamp - timeStarted) + timeOffset; iteration = (iteration + 1) % 10; - if (secondsLeft >= 0) - { + function showExactOrRelative(time) { + return (!showTimeToPlay) ? "at: " + (secondsLeft + timestamp + time).timestampToHHMMSS() : "in: " + (secondsLeft + time).secondsToMMSS(); + + } + if (infobar['end_personal_queue'] !== 0){ + $('.start-queue').text("First song starts " + showExactOrRelative(infobar['start_personal_queue'])); + $('.duration-queue').text( " (" + (infobar['length_personal_queue']).secondsToMMSS() + ")"); + $('.end-queue').text("Last song ends " + showExactOrRelative(infobar['end_personal_queue'])); + } + 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) - { + if ((iteration === 0 || (secondsLeft <= 0 && secondsLeft > -10)) && !refreshing){ refreshQueue(); } } -function renderQueue(playNextAt, now) -{ +function renderQueue(playNextAt, now) { $('.queuebody').empty(); var timeToPlay = playNextAt - now; var canDeletePrevious = false; $.each(queue, function (id, song) { + var userRequested = user_name; var requestedBy = song.requested_by; - var reqMarietje = requestedBy != 'Marietje'; - var startMarietje = false - + var reqMarietje = requestedBy !== 'Marietje'; + var startMarietje = false; + var requestNext = false; + var requestPrev = false; //checks if id is the last item and returns false if the next song is Marietje, while the current song is not. - if(id === queue.length-1){ - var requestNext = false - } else { - var requestNext = !((queue[id+1].requested_by === 'Marietje') && (requestedBy !== 'Marietje')) + if(id !== queue.length - 1) { + requestNext = !((queue[id + 1].requested_by === 'Marietje') && (requestedBy !== 'Marietje')); } - //checks if id is the first item and returns false if the previous song is not Marietje, while the current song is. - if(id === 0){ - var requestPrev = false - } else { - var prevItem = queue[id-1].id - if(queue[id-1].requested_by !== 'Marietje'){ - var requestPrev = false - if (requestedBy == 'Marietje'){ - var startMarietje = true + if(id !== 0){ + var prevItem = queue[id - 1].id; + if(queue[id-1].requested_by !== 'Marietje') { + requestPrev = false; + if (requestedBy === 'Marietje') { + startMarietje = true; } else { - var requestPrev = true + requestPrev = true; } - } else {var requestPrev = true} + } else { + requestPrev = true; + } } - var canDelete = song.can_move_down || canMoveSongs; - var canMoveUp = canMoveSongs && requestPrev || canDeletePrevious && reqMarietje && requestPrev; - var canMoveDown = canMoveSongs && requestNext || canDelete && reqMarietje && requestNext; - var artist = song.song.artist.trim() === '' ? '?' : song.song.artist; - var title = song.song.title.trim() === '' ? '?' : song.song.title; - var marietjeclass = reqMarietje ? '' : ' class="marietjequeue"'; - var marietjestartclass = startMarietje ? ' class="marietjequeue marietjequeue-start"' : ''; + var canMoveUp = canMoveSongs && requestPrev || (canDeletePrevious && reqMarietje && requestPrev); + var canMoveDown = canMoveSongs && requestNext || (canDelete && reqMarietje && requestNext); + var artist = (song.song.artist.trim() === '' ? '?' : song.song.artist); + var title = (song.song.title.trim() === '' ? '?' : song.song.title); + var songclass = ' class="normal_song' + (reqMarietje ? '' : ' marietjequeue') + + (!requestNext ? ' marietjequeue-pre-start' : '') + + (startMarietje ? ' marietjequeue-post-start':'') + + (userRequested === requestedBy ? ' requested_song':''); - showTime = showTimeToPlay ? (timeToPlay < 0 ? '' : timeToPlay.secondsToMMSS()) : (playNextAt < now ? '' : playNextAt.timestampToHHMMSS()) + var showTime = (showTimeToPlay ? (timeToPlay < 0 ? '' : timeToPlay.secondsToMMSS()) : (playNextAt < now ? '' : playNextAt.timestampToHHMMSS())); - $('.queuebody:last-child').append('' + '' + artist + $('.queuebody:last-child').append('' + '' + artist + '' + title + '' + requestedBy + '' + showTime + '' + '    '); timeToPlay += parseInt(song.song.duration); - canDeletePrevious = canDelete + canDeletePrevious = canDelete; if(playNextAt >= now) { playNextAt += parseInt(song.song.duration); } - }); -} - -function refreshQueue() -{ + } +);} +function refreshQueue() { refreshing = true; $.get('/api/queue', function (result) { var now = Date.now() / 1000 | 0; - if (timeOffset === 0) - { + if (timeOffset === 0) { // Calculate time offset with the server. timeOffset = now - result.current_time; } @@ -268,19 +269,19 @@ function refreshQueue() timeStarted = result.started_at; currentSong = result.current_song; queue = result.queue; - var playNextAt = timeStarted + timeOffset + parseInt(currentSong.song.duration); + infobar = result.infobar; + user_name = result.user_name; + 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'); + if (currentSong.can_skip || canSkip) { + $('#skip').removeClass('hidden'); } - else - { - $('#skip').removeClass('glyphicon glyphicon-fast-forward'); + else { + $('#skip').addClass('hidden'); } renderQueue(playNextAt, now); @@ -290,21 +291,19 @@ function refreshQueue() }); } -function refreshSeconds(playNextAt, now) -{ +function refreshSeconds(playNextAt, now) { if(!showTimeToPlay) { return; } var timeToPlay = playNextAt - now; - times = $('.plays-at'); + var times = $('.plays-at'); $.each(queue, function (id, song) { $(times[id]).text(timeToPlay < 0 ? '' : timeToPlay.secondsToMMSS()); timeToPlay += parseInt(song.song.duration); }); } -function getSongs() -{ +function getSongs() { var all = $('#search-all').val(); var uploader = $('#search-uploader').val(); var page = $('.pagenum').val(); @@ -313,38 +312,34 @@ function getSongs() $('#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('' + artist + - '' + title + - '' + (song.uploader_name ? song.uploader_name : 'Marietje') + - '' + song.duration.secondsToMMSS() + + var artist = (song.artist.trim() === '' ? '?' : song.artist); + var title = (song.title.trim() === '' ? '?' : song.title); + $('#request-table tbody:last-child').append('' + artist + + '' + title + + '' + ((song.uploader_name) ? song.uploader_name : 'Marietje') + + '' + song.duration.secondsToMMSS() + ''); }); var pageNumSelect = $('.pagenum'); pageNumSelect.empty(); - for(var i = 1; i < result.last_page + 1; i++) - { + for (var i = 1; i < result.last_page + 1; i++) { pageNumSelect.append($("") .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); + $('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() -{ +function showRequestTable() { $('#request-button').text('Close'); $('#queue-container').hide(); $('#request-container').removeClass('hidden'); @@ -353,8 +348,7 @@ function showRequestTable() requestViewOpen = true; } -function hideRequestTable() -{ +function hideRequestTable() { $('#request-button').text('Request'); $('#request-container').hide(); $('#queue-container').show(); @@ -366,7 +360,7 @@ function hideRequestTable() if (!Date.now) { Date.now = function () { return new Date().getTime(); - } + }; } // Edited from https://stackoverflow.com/a/6313008. @@ -375,17 +369,17 @@ Number.prototype.secondsToMMSS = function () { var minutes = Math.floor((this - (hours * 3600)) / 60); var seconds = this - (hours * 3600) - (minutes * 60); - var sep1 = '' + var sep1 = ''; if (hours > 0) { hours = hours; sep1 = ':'; } else { hours = ''; } - if (hours > 0 && minutes < 10) minutes = '0' + minutes; - if (seconds < 10) seconds = '0' + seconds; + 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); @@ -403,7 +397,7 @@ Number.prototype.timestampToHHMMSS = function () { seconds = '0' + seconds; } return hours + ':' + minutes + ':' + seconds; -} +}; function createAlert(type, message) { alertText = '
'+ @@ -413,5 +407,5 @@ function createAlert(type, message) { '' + message + '
'; - $('body > div.container').prepend(alertText); -} + $('body > div.container > div.alert-location').prepend(alertText); +} \ No newline at end of file diff --git a/marietje/queues/models.py b/marietje/queues/models.py index ca07298..962512b 100644 --- a/marietje/queues/models.py +++ b/marietje/queues/models.py @@ -5,7 +5,6 @@ from django.utils import timezone from songs.models import Song - class Playlist(models.Model): def __str__(self): return 'Playlist #' + str(self.id) diff --git a/marietje/queues/templates/queues/queue.html b/marietje/queues/templates/queues/queue.html index a9475c5..0eb0ef6 100644 --- a/marietje/queues/templates/queues/queue.html +++ b/marietje/queues/templates/queues/queue.html @@ -4,9 +4,47 @@ {% block title %}Queue{% endblock %} {% block content %} -

Request

- + + +

+
+
-
-

- Now Playing{% if perms.queues.can_control_volume %} - {% endif %} -

- - - - - - + + + + + + - - - + - - - - -
ArtistTitleControl
ArtistTitleControl
- {% if perms.queues.can_control_volume %}        {% endif %} -
-

Queue

- - - - - - - - +
ArtistTitleControl