- Implemented support for shuffle, random and set volume on the UI

- Reduced the websocket ping poll frequency to 1 second
This commit is contained in:
Fabio Manganiello 2018-01-31 01:32:07 +01:00
parent 28bc4c748e
commit 968b71e946
5 changed files with 134 additions and 19 deletions

View file

@ -123,7 +123,7 @@ class HttpBackend(Backend):
try: try:
waiter = await websocket.ping() waiter = await websocket.ping()
await asyncio.wait_for(waiter, timeout=5) await asyncio.wait_for(waiter, timeout=5)
time.sleep(0.1) time.sleep(1)
except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed) as e: except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed) as e:
logging.info('Client {} closed connection'.format(websocket.remote_address[0])) logging.info('Client {} closed connection'.format(websocket.remote_address[0]))
self.active_websockets.remove(websocket) self.active_websockets.remove(websocket)

View file

@ -95,3 +95,49 @@ main {
color: #666; color: #666;
} }
#track-seeker-container {
margin-bottom: 15px;
}
#volume-ctrl-container {
margin-top: 15px;
}
.slider {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 15px;
border-radius: 5px;
background: #e4e4e4;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
.slider[disabled]::-webkit-slider-thumb {
display: none;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}

View file

@ -1,5 +1,5 @@
$(document).ready(function() { $(document).ready(function() {
var execute = function(request, onSuccess, onComplete) { var execute = function(request, onSuccess, onError, onComplete) {
request['target'] = 'localhost'; request['target'] = 'localhost';
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
@ -12,6 +12,11 @@ $(document).ready(function() {
onComplete(); onComplete();
} }
}, },
error: function(xhr, status, error) {
if (onError) {
onError(xhr, status, error);
}
},
success: function(response, status, xhr) { success: function(response, status, xhr) {
if (onSuccess) { if (onSuccess) {
onSuccess(response, status, xhr); onSuccess(response, status, xhr);
@ -28,6 +33,7 @@ $(document).ready(function() {
var updateControls = function(status, track) { var updateControls = function(status, track) {
var $playbackControls = $('.playback-controls'); var $playbackControls = $('.playback-controls');
var $curTrack = $('.track-info'); var $curTrack = $('.track-info');
var $volumeCtrl = $('#volume-ctrl');
if (status) { if (status) {
switch (status.state.toLowerCase()) { switch (status.state.toLowerCase()) {
@ -53,6 +59,11 @@ $(document).ready(function() {
$curTrack.find('.no-track').hide(); $curTrack.find('.no-track').hide();
break; break;
} }
if ('volume' in status) {
var volume = parseInt(status.volume);
$volumeCtrl.val(volume);
}
} }
if (track) { if (track) {
@ -183,6 +194,8 @@ $(document).ready(function() {
var initBindings = function() { var initBindings = function() {
window.registerEventListener(onEvent); window.registerEventListener(onEvent);
var $playbackControls = $('.playback-controls').find('button'); var $playbackControls = $('.playback-controls').find('button');
var $volumeCtrl = $('#volume-ctrl');
var prevVolume;
$playbackControls.on('click', function(evt) { $playbackControls.on('click', function(evt) {
var action = $(this).data('action'); var action = $(this).data('action');
@ -196,11 +209,31 @@ $(document).ready(function() {
}, },
onSuccess=undefined, onSuccess=undefined,
onError=undefined,
onComplete = function() { onComplete = function() {
$btn.removeAttr('disabled'); $btn.removeAttr('disabled');
} }
); );
}); });
$volumeCtrl.on('mousedown', function(event) {
prevVolume = $(this).val();
});
$volumeCtrl.on('mouseup', function(event) {
execute(
{
type: 'request',
action: 'music.mpd.setvol',
args: { vol: $(this).val() }
},
onSuccess=undefined,
onError = function() {
$volumeCtrl.val(prevVolume);
}
);
});
}; };
var init = function() { var init = function() {

View file

@ -6,12 +6,23 @@
<span class="track"></span> <span class="track"></span>
</div> </div>
<div class="row playback-controls"> <div class="playback-controls">
<div class="row">
<div class="six columns offset-by-three slider-container" id="track-seeker-container">
<input type="range" min="0" id="track-seeker" disabled="disabled" class="slider">
</div>
</div>
<div class="row">
<div class="eight columns offset-by-two"> <div class="eight columns offset-by-two">
<button data-action="previous"> <button data-action="previous">
<i class="fa fa-step-backward"></i> <i class="fa fa-step-backward"></i>
</button> </button>
<button data-action="repeat">
<i class="fa fa-repeat"></i>
</button>
<button data-action="play"> <button data-action="play">
<i class="fa fa-play"></i> <i class="fa fa-play"></i>
</button> </button>
@ -24,12 +35,25 @@
<i class="fa fa-stop"></i> <i class="fa fa-stop"></i>
</button> </button>
<button data-action="random">
<i class="fa fa-random"></i>
</button>
<button data-action="next"> <button data-action="next">
<i class="fa fa-step-forward"></i> <i class="fa fa-step-forward"></i>
</button> </button>
</div> </div>
</div> </div>
<div class="row">
<div class="six columns offset-by-three slider-container" id="volume-ctrl-container">
<i class="fa fa-volume-down"></i> &nbsp;
<input type="range" min="0" max="100" id="volume-ctrl" class="slider" style="width:90%">
&nbsp; <i class="fa fa-volume-up"></i>
</div>
</div>
</div>
<div class="row"> <div class="row">
<div id="music-browser" class="three columns music-pane"></div> <div id="music-browser" class="three columns music-pane"></div>
<div id="playlist-content" class="nine columns music-pane"></div> <div id="playlist-content" class="nine columns music-pane"></div>

View file

@ -64,6 +64,18 @@ class MusicMpdPlugin(MusicPlugin):
self.setvol(str(new_volume)) self.setvol(str(new_volume))
return self.status() return self.status()
def random(self, value=None):
if value is None:
value = int(self.status().output['random'])
value = 1 if value == 0 else 0
self.client.random(value)
def repeat(self, value=None):
if value is None:
value = int(self.status().output['repeat'])
value = 1 if value == 0 else 0
self.client.repeat(value)
def add(self, resource): def add(self, resource):
return self._exec('add', resource) return self._exec('add', resource)