forked from platypush/platypush
UI improvements + support for MPD playlists and folders
This commit is contained in:
parent
fc608317fd
commit
28bc4c748e
6 changed files with 199 additions and 10 deletions
|
@ -1,14 +1,13 @@
|
|||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
background: #f4f5f6;
|
||||
padding: 25px;
|
||||
margin: -10px 10px 35px -10px;
|
||||
margin: 0px 10px 35px -10px;
|
||||
border-bottom: 1px solid #e1e4e8;
|
||||
}
|
||||
|
||||
|
@ -20,8 +19,21 @@ header {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#date-time {
|
||||
text-align: right;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
#date-time > .date {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#date-time > .time {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
main {
|
||||
width: 80%;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
|
@ -34,10 +46,13 @@ main {
|
|||
border-top: 0;
|
||||
padding: 20px;
|
||||
margin-top: -25px;
|
||||
border-radius: 0 0 7.5px 7.5px;
|
||||
}
|
||||
|
||||
.playback-controls {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e8eaf0;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
|
@ -46,7 +61,7 @@ main {
|
|||
|
||||
.track-info {
|
||||
text-align: center;
|
||||
margin: -20px -20px 15px -20px;
|
||||
margin: -20px -20px 0 -20px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
|
@ -55,3 +70,28 @@ main {
|
|||
display: block;
|
||||
}
|
||||
|
||||
#playlist-content {
|
||||
margin-left: 0;
|
||||
width: 78%;
|
||||
}
|
||||
|
||||
.music-pane {
|
||||
height: 360px;
|
||||
overflow-y: scroll;
|
||||
padding: 15px 15px 0 5px;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.music-item {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.music-item:nth-child(odd) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.playlist-track > .track-time {
|
||||
text-align: right;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
$(document).ready(function() {
|
||||
var websocket;
|
||||
var dateTimeInterval;
|
||||
var eventListeners = [];
|
||||
|
||||
var initWebsocket = function() {
|
||||
|
@ -16,12 +17,53 @@ $(document).ready(function() {
|
|||
};
|
||||
};
|
||||
|
||||
var initDateTime = function() {
|
||||
var getDateString = function(t) {
|
||||
var s = '';
|
||||
switch (t.getDay()) {
|
||||
case 1: s += 'Mon '; break; case 2: s += 'Tue '; break; case 3: s += 'Wed '; break;
|
||||
case 4: s += 'Thu '; break; case 5: s += 'Fri '; break; case 6: s += 'Sat '; break;
|
||||
case 7: s += 'Sun '; break;
|
||||
}
|
||||
|
||||
s += (t.getDate() < 10 ? '0' : '') + t.getDate() + ' ';
|
||||
switch (t.getMonth()) {
|
||||
case 0: s += 'Jan '; break; case 1: s += 'Feb '; break; case 2: s += 'Mar '; break;
|
||||
case 3: s += 'Apr '; break; case 4: s += 'May '; break; case 5: s += 'Jun '; break;
|
||||
case 6: s += 'Jul '; break; case 7: s += 'Ago '; break; case 8: s += 'Sep '; break;
|
||||
case 9: s += 'Oct '; break; case 10: s += 'Nov '; break; case 11: s += 'Dec '; break;
|
||||
}
|
||||
|
||||
s += t.getFullYear();
|
||||
return s;
|
||||
};
|
||||
|
||||
var setDateTime = function() {
|
||||
var $dateTime = $('#date-time');
|
||||
var $date = $dateTime.find('.date');
|
||||
var $time = $dateTime.find('.time');
|
||||
var now = new Date();
|
||||
|
||||
$date.text(getDateString(now));
|
||||
$time.text((now.getHours() < 10 ? '0' : '') + now.getHours() + ':' +
|
||||
(now.getMinutes() < 10 ? '0' : '') + now.getMinutes());
|
||||
};
|
||||
|
||||
if (dateTimeInterval) {
|
||||
clearInterval(dateTimeInterval);
|
||||
}
|
||||
|
||||
setDateTime();
|
||||
dateTimeInterval = setInterval(setDateTime, 1000);
|
||||
};
|
||||
|
||||
var registerEventListener = function(listener) {
|
||||
eventListeners.push(listener);
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
initWebsocket();
|
||||
initDateTime();
|
||||
};
|
||||
|
||||
window.registerEventListener = registerEventListener;
|
||||
|
|
|
@ -97,6 +97,89 @@ $(document).ready(function() {
|
|||
);
|
||||
};
|
||||
|
||||
var initPlaylist = function() {
|
||||
execute(
|
||||
{
|
||||
type: 'request',
|
||||
action: 'music.mpd.playlistinfo',
|
||||
},
|
||||
|
||||
onSuccess = function(response) {
|
||||
var $playlistContent = $('#playlist-content');
|
||||
var tracks = response.response.output;
|
||||
|
||||
for (var track of tracks) {
|
||||
var $element = $('<div></div>')
|
||||
.addClass('playlist-track')
|
||||
.addClass('row').addClass('music-item')
|
||||
.data('file', track.file);
|
||||
|
||||
var $artist = $('<div></div>')
|
||||
.addClass('four').addClass('columns')
|
||||
.addClass('track-artist').text(track.artist);
|
||||
|
||||
var $title = $('<div></div>')
|
||||
.addClass('six').addClass('columns')
|
||||
.addClass('track-title').text(track.title);
|
||||
|
||||
var $time = $('<div></div>')
|
||||
.addClass('two').addClass('columns')
|
||||
.addClass('track-time').text(
|
||||
'' + parseInt(parseInt(track.time)/60) +
|
||||
':' + (parseInt(track.time)%60 < 10 ? '0' : '') +
|
||||
parseInt(track.time)%60);
|
||||
|
||||
$artist.appendTo($element);
|
||||
$title.appendTo($element);
|
||||
$time.appendTo($element);
|
||||
$element.appendTo($playlistContent);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var initBrowser = function() {
|
||||
execute(
|
||||
{
|
||||
type: 'request',
|
||||
action: 'music.mpd.lsinfo',
|
||||
},
|
||||
|
||||
onSuccess = function(response) {
|
||||
var $browserContent = $('#music-browser');
|
||||
var items = response.response.output;
|
||||
var directories = [];
|
||||
var playlists = [];
|
||||
|
||||
for (var item of items) {
|
||||
if ('directory' in item) {
|
||||
directories.push(item.directory);
|
||||
} else if ('playlist' in item) {
|
||||
playlists.push(item.playlist);
|
||||
}
|
||||
}
|
||||
|
||||
for (var directory of directories.sort()) {
|
||||
var $element = $('<div></div>')
|
||||
.addClass('browser-directory').addClass('music-item')
|
||||
.addClass('browser-item').addClass('row')
|
||||
.html('<i class="fa fa-folder-open-o"></i> ' + directory);
|
||||
|
||||
$element.appendTo($browserContent);
|
||||
}
|
||||
|
||||
for (var playlist of playlists.sort()) {
|
||||
var $element = $('<div></div>')
|
||||
.addClass('browser-playlist').addClass('music-item')
|
||||
.addClass('browser-item').addClass('row')
|
||||
.html('<i class="fa fa-music"></i> ' + playlist);
|
||||
|
||||
$element.appendTo($browserContent);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var initBindings = function() {
|
||||
window.registerEventListener(onEvent);
|
||||
var $playbackControls = $('.playback-controls').find('button');
|
||||
|
@ -122,6 +205,8 @@ $(document).ready(function() {
|
|||
|
||||
var init = function() {
|
||||
initStatus();
|
||||
initPlaylist();
|
||||
initBrowser();
|
||||
initBindings();
|
||||
};
|
||||
|
||||
|
|
|
@ -24,9 +24,16 @@
|
|||
|
||||
<body>
|
||||
<header>
|
||||
<div class="logo">
|
||||
<span class="logo-1">Platypush</span>
|
||||
<span class="logo-2">Web Panel</span>
|
||||
<div class="row">
|
||||
<div class="logo nine columns">
|
||||
<span class="logo-1">Platypush</span>
|
||||
<span class="logo-2">Web Panel</span>
|
||||
</div>
|
||||
|
||||
<div id="date-time" class="three columns">
|
||||
<div class="date"></div>
|
||||
<div class="time"></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<span class="track"></span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="eight columns offset-by-two playback-controls">
|
||||
<div class="row playback-controls">
|
||||
<div class="eight columns offset-by-two">
|
||||
<button data-action="previous">
|
||||
<i class="fa fa-step-backward"></i>
|
||||
</button>
|
||||
|
@ -30,3 +30,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div id="music-browser" class="three columns music-pane"></div>
|
||||
<div id="playlist-content" class="nine columns music-pane"></div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -86,6 +86,16 @@ class MusicMpdPlugin(MusicPlugin):
|
|||
def currentsong(self):
|
||||
return Response(output=self.client.currentsong())
|
||||
|
||||
def playlistinfo(self):
|
||||
return Response(output=self.client.playlistinfo())
|
||||
|
||||
def listplaylists(self):
|
||||
return Response(output=sorted(self.client.listplaylists(),
|
||||
key=lambda p: p['playlist']))
|
||||
|
||||
def lsinfo(self):
|
||||
return Response(output=self.client.lsinfo())
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
Loading…
Reference in a new issue