forked from platypush/platypush
Connected the wires between Snapcast backend and frontend
This commit is contained in:
parent
a346442246
commit
fd8c3bb846
4 changed files with 398 additions and 162 deletions
|
@ -1,5 +1,6 @@
|
|||
.snapcast-host-container {
|
||||
min-width: 40em;
|
||||
max-width: 80em;
|
||||
margin: 1em auto;
|
||||
background: rgba(245,245,245,0.6);
|
||||
border: 1px solid rgba(220,220,220,1.0);
|
||||
|
@ -9,26 +10,113 @@
|
|||
.snapcast-host-header {
|
||||
border-bottom: 1px solid rgba(220,220,220,1.0);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.snapcast-group-header {
|
||||
text-transform: uppercase;
|
||||
padding: 0 .5em;
|
||||
}
|
||||
|
||||
.snapcast-group-settings {
|
||||
text-align: center;
|
||||
.snapcast-host-header h1 {
|
||||
font-size: 1.9em;
|
||||
}
|
||||
|
||||
.snapcast-group-header {
|
||||
padding: .5em;
|
||||
margin: 0 1.4em 1.8em .2em;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.snapcast-settings-btn {
|
||||
cursor: pointer;
|
||||
padding: .2em;
|
||||
}
|
||||
|
||||
.snapcast-settings-btn:hover {
|
||||
border: .05em solid #e0e0e0;
|
||||
padding: .15em;
|
||||
}
|
||||
|
||||
.snapcast-group-header h2 {
|
||||
font-size: 1.5em;
|
||||
margin-top: .6em;
|
||||
}
|
||||
|
||||
.snapcast-client-container {
|
||||
.snapcast-client-disconnected {
|
||||
color: rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.snapcast-client-row {
|
||||
padding: 0 1.4em;
|
||||
margin: 1.5em .5em;
|
||||
}
|
||||
|
||||
.snapcast-client-header h3 {
|
||||
.snapcast-client-row h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.snapcast-client-mute-toggle {
|
||||
margin-top: -1.2em;
|
||||
}
|
||||
|
||||
.snapcast-form {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.snapcast-form * > input[type=text] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.snapcast-form > .row {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.snapcast-form-bottom {
|
||||
text-align: right;
|
||||
margin-top: 2rem;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.snapcast-form-bottom input {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.snapcast-form * > label {
|
||||
transform: translateY(25%);
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-info {
|
||||
max-width: 70%;
|
||||
margin: 1em auto .5em auto;
|
||||
padding: 2em;
|
||||
background: rgba(240,240,240,0.6);
|
||||
border-radius: 10px;
|
||||
border: .05em solid rgba(225,225,225,1.0)
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-info > .row {
|
||||
padding: .2em;
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-info > .row:hover {
|
||||
background-color: #daf8e2 !important;
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-info * > .info-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-info * > .info-value {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-delete {
|
||||
width: 30%;
|
||||
margin: 1em auto 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.snapcast-form > .snapcast-client-delete > label {
|
||||
display: inline;
|
||||
margin-left: .5em;
|
||||
color: rgba(200, 44, 23, 1.0);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
$(document).ready(function() {
|
||||
var statuses = [],
|
||||
var serverInfo = {},
|
||||
clientInfo = {},
|
||||
$container = $('#snapcast-container');
|
||||
|
||||
var createPowerToggleElement = function(data) {
|
||||
|
@ -25,19 +26,64 @@ $(document).ready(function() {
|
|||
return $powerToggle;
|
||||
};
|
||||
|
||||
var onEvent = function(event) {
|
||||
switch (event.args.type) {
|
||||
case 'platypush.message.event.music.snapcast.ClientConnectedEvent':
|
||||
case 'platypush.message.event.music.snapcast.ClientDisconnectedEvent':
|
||||
case 'platypush.message.event.music.snapcast.ClientNameChangeEvent':
|
||||
case 'platypush.message.event.music.snapcast.GroupStreamChangeEvent':
|
||||
case 'platypush.message.event.music.snapcast.ServerUpdateEvent':
|
||||
redraw();
|
||||
break;
|
||||
|
||||
case 'platypush.message.event.music.snapcast.ClientVolumeChangeEvent':
|
||||
var $host = $($container.find('.snapcast-host-container').filter(
|
||||
(i, hostDiv) => $(hostDiv).data('host') === event.args.host
|
||||
));
|
||||
|
||||
var $client = $($host.find('.snapcast-client-container').filter(
|
||||
(i, clientDiv) => $(clientDiv).data('id') === event.args.client
|
||||
));
|
||||
|
||||
$client.find('.snapcast-volume-slider').val(event.args.volume);
|
||||
$client.find('.snapcast-mute-toggle').find('input.toggle--checkbox')
|
||||
.prop('checked', !event.args.muted);
|
||||
|
||||
break;
|
||||
|
||||
case 'platypush.message.event.music.snapcast.GroupMuteChangeEvent':
|
||||
var $host = $($container.find('.snapcast-host-container').filter(
|
||||
(i, hostDiv) => $(hostDiv).data('host') === event.args.host
|
||||
));
|
||||
|
||||
var $group = $($host.find('.snapcast-group-container').filter(
|
||||
(i, groupDiv) => $(groupDiv).data('id') === event.args.group
|
||||
));
|
||||
|
||||
$group.find('.snapcast-group-mute-toggle').find('input.toggle--checkbox')
|
||||
.prop('checked', !event.args.muted);
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var update = function(statuses) {
|
||||
$container.html('');
|
||||
serverInfo = {};
|
||||
clientInfo = {};
|
||||
|
||||
var networkNames = Object.keys(window.config.snapcast_hosts);
|
||||
for (var i=0; i < networkNames.length; i++) {
|
||||
var hosts = Object.keys(window.config.snapcast_hosts);
|
||||
|
||||
for (var i=0; i < hosts.length; i++) {
|
||||
var status = statuses[i];
|
||||
var networkName = networkNames[i];
|
||||
var host = hosts[i];
|
||||
var name = status.server.host.name || status.server.host.ip;
|
||||
serverInfo[host] = status.server;
|
||||
|
||||
var $host = $('<div></div>')
|
||||
.addClass('snapcast-host-container')
|
||||
.data('name', name)
|
||||
.data('network-name', networkName);
|
||||
.data('host', host);
|
||||
|
||||
var $header = $('<div></div>').addClass('row')
|
||||
.addClass('snapcast-host-header');
|
||||
|
@ -58,21 +104,25 @@ $(document).ready(function() {
|
|||
.addClass('snapcast-group-header');
|
||||
|
||||
var $groupTitle = $('<h2></h2>')
|
||||
.addClass('ten columns');
|
||||
.addClass('snapcast-group-settings')
|
||||
.addClass('snapcast-settings-btn')
|
||||
.attr('data-modal', '#snapcast-group-modal')
|
||||
.addClass('eleven columns');
|
||||
|
||||
var $groupSettings = $('<i></i>')
|
||||
.addClass('snapcast-group-settings')
|
||||
.addClass('fa fa-cog')
|
||||
.data('name', groupName)
|
||||
.data('id', group.id);
|
||||
.attr('data-modal', '#snapcast-group-modal')
|
||||
.addClass('fa fa-ellipsis-v');
|
||||
|
||||
var $groupName = $('<span></span>')
|
||||
.attr('data-modal', '#snapcast-group-modal')
|
||||
.html(' ' + groupName);
|
||||
|
||||
var $groupMuteToggle = createPowerToggleElement({
|
||||
id: group.id,
|
||||
on: !group.muted,
|
||||
}).addClass('two columns').addClass('snapcast-group-mute-toggle');
|
||||
}).addClass('one column')
|
||||
.addClass('snapcast-mute-toggle')
|
||||
.addClass('snapcast-group-mute-toggle');
|
||||
|
||||
$groupSettings.appendTo($groupTitle);
|
||||
$groupName.appendTo($groupTitle);
|
||||
|
@ -82,22 +132,41 @@ $(document).ready(function() {
|
|||
|
||||
for (var client of group.clients) {
|
||||
var clientName = client.config.name || client.host.name || client.host.ip;
|
||||
clientInfo[client.id] = client.host;
|
||||
clientInfo[client.id].clientName = client.snapclient.name;
|
||||
clientInfo[client.id].clientVersion = client.snapclient.version;
|
||||
clientInfo[client.id].protocolVersion = client.snapclient.protocolVersion;
|
||||
|
||||
var $client = $('<div></div>')
|
||||
.addClass('snapcast-client-container')
|
||||
.data('name', clientName)
|
||||
.data('id', client.id);
|
||||
.data('id', client.id)
|
||||
.data('connected', client.connected);
|
||||
|
||||
if (!client.connected) {
|
||||
$client.addClass('snapcast-client-disconnected');
|
||||
}
|
||||
|
||||
var $clientRow = $('<div></div>').addClass('row')
|
||||
.addClass('snapcast-client-header');
|
||||
.addClass('snapcast-client-row');
|
||||
|
||||
var $clientTitle = $('<h3></h3>')
|
||||
.addClass('three columns')
|
||||
.data('connected', client.connected)
|
||||
.text(clientName);
|
||||
.addClass('snapcast-settings-btn')
|
||||
.addClass('snapcast-client-settings')
|
||||
.attr('data-modal', '#snapcast-client-modal')
|
||||
.addClass('two columns');
|
||||
|
||||
var $clientSettings = $('<i></i>')
|
||||
.attr('data-modal', '#snapcast-client-modal')
|
||||
.addClass('fa fa-ellipsis-v');
|
||||
|
||||
var $clientName = $('<span></span>')
|
||||
.attr('data-modal', '#snapcast-client-modal')
|
||||
.html(' ' + clientName);
|
||||
|
||||
var $volumeSlider = $('<input></input>')
|
||||
.addClass('slider snapcast-volume-slider')
|
||||
.addClass('eight columns')
|
||||
.addClass('nine columns')
|
||||
.data('id', client.id)
|
||||
.attr('type', 'range')
|
||||
.attr('min', 0).attr('max', 100)
|
||||
|
@ -108,8 +177,11 @@ $(document).ready(function() {
|
|||
on: !client.config.volume.muted,
|
||||
})
|
||||
.addClass('one column')
|
||||
.addClass('snapcast-mute-toggle')
|
||||
.addClass('snapcast-client-mute-toggle');
|
||||
|
||||
$clientSettings.appendTo($clientTitle);
|
||||
$clientName.appendTo($clientTitle);
|
||||
$clientTitle.appendTo($clientRow);
|
||||
$volumeSlider.appendTo($clientRow);
|
||||
$clientMuteToggle.appendTo($clientRow);
|
||||
|
@ -142,7 +214,7 @@ $(document).ready(function() {
|
|||
|
||||
$.when.apply($, promises)
|
||||
.done(function() {
|
||||
statuses = [];
|
||||
var statuses = [];
|
||||
for (var status of arguments) {
|
||||
statuses.push(status[0].response.output);
|
||||
}
|
||||
|
@ -154,168 +226,146 @@ $(document).ready(function() {
|
|||
};
|
||||
|
||||
var initBindings = function() {
|
||||
// $roomsList.on('click touch', '.room-item', function() {
|
||||
// $('.room-item').removeClass('selected');
|
||||
// $('.room-lights-item').hide();
|
||||
// $('.room-scenes-item').hide();
|
||||
$container.on('click touch', '.toggle--checkbox', function(evt) {
|
||||
evt.stopPropagation();
|
||||
var id = $(this).attr('id');
|
||||
var host = $(this).parents('.snapcast-host-container').data('host');
|
||||
var args = {
|
||||
host: host,
|
||||
port: window.config.snapcast_hosts[host],
|
||||
mute: !$(this).prop('checked'),
|
||||
};
|
||||
|
||||
// var roomId = $(this).data('id');
|
||||
// var $roomLights = $('.room-lights-item').filter(function(i, item) {
|
||||
// return $(item).data('id') === roomId
|
||||
// });
|
||||
if ($(this).parents('.snapcast-mute-toggle').hasClass('snapcast-client-mute-toggle')) {
|
||||
args.client = id;
|
||||
} else if ($(this).parents('.snapcast-mute-toggle').hasClass('snapcast-group-mute-toggle')) {
|
||||
args.group = id;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// var $roomScenes = $('.room-scenes-item').filter(function(i, item) {
|
||||
// return $(item).data('room-id') === roomId
|
||||
// });
|
||||
execute({
|
||||
type: 'request',
|
||||
action: 'music.snapcast.mute',
|
||||
args: args,
|
||||
});
|
||||
});
|
||||
|
||||
// $(this).addClass('selected');
|
||||
// $roomLights.show();
|
||||
// $roomScenes.show();
|
||||
// });
|
||||
$container.on('mouseup touchend', '.snapcast-volume-slider', function(evt) {
|
||||
evt.stopPropagation();
|
||||
var id = $(this).data('id');
|
||||
var host = $(this).parents('.snapcast-host-container').data('host');
|
||||
var args = {
|
||||
host: host,
|
||||
port: window.config.snapcast_hosts[host],
|
||||
client: id,
|
||||
volume: $(this).val(),
|
||||
};
|
||||
|
||||
// $scenesList.on('click touch', '.scene-item', function() {
|
||||
// $('.scene-item').removeClass('selected');
|
||||
// $(this).addClass('selected');
|
||||
execute({
|
||||
type: 'request',
|
||||
action: 'music.snapcast.volume',
|
||||
args: args,
|
||||
});
|
||||
});
|
||||
|
||||
// execute({
|
||||
// type: 'request',
|
||||
// action: 'light.hue.scene',
|
||||
// args: {
|
||||
// name: $(this).data('name')
|
||||
// }
|
||||
// }, refreshStatus);
|
||||
// });
|
||||
$container.on('click touch', '.snapcast-group-settings', function(evt) {
|
||||
var host = $(this).parents('.snapcast-host-container').data('host');
|
||||
var groupId = $(this).parents('.snapcast-group-container').data('id');
|
||||
var groupName = $(this).parents('.snapcast-group-container').data('name');
|
||||
var $modal = $($(this).data('modal'));
|
||||
|
||||
// $lightsList.on('click touch', '.light-item-name', function() {
|
||||
// var $lightItem = $(this).parents('.light-item');
|
||||
// var $colorSelector = $lightItem.find('.light-color-selector');
|
||||
$modal.find('.modal-header').text(groupName);
|
||||
});
|
||||
|
||||
// $('.light-color-selector').hide();
|
||||
// $colorSelector.toggle();
|
||||
$container.on('click touch', '.snapcast-client-settings', function(evt) {
|
||||
var host = $(this).parents('.snapcast-host-container').data('host');
|
||||
var clientId = $(this).parents('.snapcast-client-container').data('id');
|
||||
var clientName = $(this).parents('.snapcast-client-container').data('name');
|
||||
var info = clientInfo[clientId];
|
||||
var $modal = $($(this).data('modal'));
|
||||
var $form = $modal.find('#snapcast-client-form');
|
||||
var $info = $form.find('.snapcast-client-info');
|
||||
|
||||
// $('.light-item').removeClass('selected');
|
||||
// $lightItem.addClass('selected');
|
||||
// });
|
||||
$form.data('host', host);
|
||||
$form.data('client', clientId);
|
||||
$modal.find('.modal-header').text(clientName);
|
||||
$form.find('input[name=name]').val(clientName);
|
||||
|
||||
// $lightsList.on('click touch', '.light-ctrl-switch', function(e) {
|
||||
// e.stopPropagation();
|
||||
for (var attr in info) {
|
||||
$info.find('[data-bind=' + attr + ']').text(info[attr]);
|
||||
}
|
||||
});
|
||||
|
||||
// var $lightItem = $($(this).parents('.light-item'));
|
||||
// var type = $lightItem.data('type');
|
||||
// var name = $lightItem.data('name');
|
||||
// var isOn = $lightItem.data('on');
|
||||
// var action = 'light.hue.' + (isOn ? 'off' : 'on');
|
||||
// var key = (type == 'light' ? 'lights' : 'groups');
|
||||
// var args = {
|
||||
// type: 'request',
|
||||
// action: action,
|
||||
// args: {}
|
||||
// };
|
||||
$('.snapcast-form').on('click touch', '[data-dismiss-modal]', function(evt) {
|
||||
var $modal = $(this).parents($(this).data('dismiss-modal'));
|
||||
|
||||
// args['args'][key] = [name];
|
||||
// execute(args, function() {
|
||||
// $lightItem.data('on', !isOn);
|
||||
// refreshStatus();
|
||||
// });
|
||||
// });
|
||||
var clearModal = function() {
|
||||
$modal.find('form').find('input').prop('disabled', false);
|
||||
$modal.find('form').find('[name=delete]').prop('checked', false);
|
||||
};
|
||||
|
||||
// $lightsList.on('click touch', '.animation-switch', function(e) {
|
||||
// e.stopPropagation();
|
||||
console.log($modal);
|
||||
clearModal();
|
||||
});
|
||||
|
||||
// var turnedOn = $(this).prop('checked');
|
||||
// var args = {};
|
||||
// args['groups'] = $(this).parents('.animation-item').data('name');
|
||||
// args['animation'] = $(this).parents('.animation-item')
|
||||
// .find('input.animation-type:checked').data('type');
|
||||
$('#snapcast-client-form').on('submit', function(evt) {
|
||||
var $form = $(this);
|
||||
var host = $form.data('host');
|
||||
var clientId = $form.data('client');
|
||||
|
||||
// var $animationCtrl = $(this).parents('.animation-item')
|
||||
// .find('.animation-container').filter(
|
||||
// (index, node) => $(node).data('animation-type') === args['animation']
|
||||
// );
|
||||
var clearModal = function() {
|
||||
$form.parents('.modal').fadeOut();
|
||||
$form.find('input').prop('disabled', false);
|
||||
$form.find('[name=delete]').prop('checked', false);
|
||||
};
|
||||
|
||||
// var params = $animationCtrl.find('*').filter(
|
||||
// (index, node) => $(node).data('animation-property'))
|
||||
// .toArray().reduce(
|
||||
// (map, input) => {
|
||||
// if ($(input).val().length) {
|
||||
// var val = $(input).val();
|
||||
// val = Array.isArray(val) ? val.map((i) => parseFloat(i)) : parseFloat(val);
|
||||
// map[$(input).data('animation-property')] = val;
|
||||
// }
|
||||
var request = {
|
||||
type: 'request',
|
||||
args: {
|
||||
host: host,
|
||||
port: window.config.snapcast_hosts[host],
|
||||
client: clientId,
|
||||
},
|
||||
};
|
||||
|
||||
// return map
|
||||
// }, {}
|
||||
// );
|
||||
if ($form.find('[name=delete]').prop('checked')) {
|
||||
if (!confirm('Are you sure you want to remove this client?')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// for (var p of Object.keys(params)) {
|
||||
// args[p] = params[p];
|
||||
// }
|
||||
request.action = 'music.snapcast.delete_client';
|
||||
} else {
|
||||
request.action = 'music.snapcast.set_client_name';
|
||||
request.args.name = $form.find('input[name=name]').val().trim();
|
||||
}
|
||||
|
||||
// if (turnedOn) {
|
||||
// execute(
|
||||
// {
|
||||
// type: 'request',
|
||||
// action: 'light.hue.animate',
|
||||
// args: args,
|
||||
// },
|
||||
$form.find('input').prop('disabled', true);
|
||||
|
||||
// onSuccess = function() {
|
||||
// $(this).prop('checked', true);
|
||||
// }
|
||||
// );
|
||||
// } else {
|
||||
// execute(
|
||||
// {
|
||||
// type: 'request',
|
||||
// action: 'light.hue.stop_animation',
|
||||
// },
|
||||
execute(
|
||||
(response) => {},
|
||||
(xhr, status, error) => {
|
||||
createNotification({
|
||||
'icon': 'exclamation',
|
||||
'text': status + ': ' + error,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
clearModal();
|
||||
}
|
||||
);
|
||||
|
||||
// onSuccess = function() {
|
||||
// $(this).prop('checked', false);
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
// $lightsList.on('mouseup touchend', '.light-slider', function() {
|
||||
// var property = $(this).data('property');
|
||||
// var type = $(this).data('type');
|
||||
// var name = $(this).data('name');
|
||||
// var args = {
|
||||
// type: 'request',
|
||||
// action: 'light.hue.' + property,
|
||||
// args: { value: $(this).val() }
|
||||
// };
|
||||
|
||||
// if (type === 'light') {
|
||||
// args.args.lights = [name];
|
||||
// } else {
|
||||
// args.args.groups = [name];
|
||||
// }
|
||||
|
||||
// execute(args, refreshStatus);
|
||||
// });
|
||||
|
||||
// $lightsList.on('click touch', 'input.animation-type', function(e) {
|
||||
// var type = $(this).data('type');
|
||||
// var $animationContainers = $(this).parents('.animation-item').find('.animation-container')
|
||||
// var $animationContainer = $(this).parents('.animation-item').find('.animation-container')
|
||||
// .filter(function() { return $(this).data('animationType') === type })
|
||||
|
||||
// $animationContainers.hide();
|
||||
// $animationContainer.show();
|
||||
// });
|
||||
|
||||
// if (window.config.light.hue.default_group) {
|
||||
// var $defaultRoomItem = $roomsList.find('.room-item').filter(
|
||||
// (i, r) => $(r).data('name') == window.config.light.hue.default_group);
|
||||
|
||||
// $defaultRoomItem.click();
|
||||
// }
|
||||
var initEvents = function() {
|
||||
window.registerEventListener(onEvent);
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
redraw();
|
||||
initEvents();
|
||||
};
|
||||
|
||||
init();
|
||||
|
|
|
@ -13,6 +13,91 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div id="snapcast-group-modal" class="modal snapcast-modal">
|
||||
<div class="modal-container">
|
||||
<div class="modal-header"></div>
|
||||
<div class="modal-body">
|
||||
<form id="snapcast-group-form" class="snapcast-form" action="#">
|
||||
<div class="row snapcast-form-bottom">
|
||||
<div class="six columns offset-by-six forms-btns">
|
||||
<input type="button" class="btn-default" data-dismiss-modal="#snapcast-group-modal"
|
||||
value="Close">
|
||||
<input type="submit" class="btn-primary" value="Save">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="snapcast-client-modal" class="modal snapcast-modal">
|
||||
<div class="modal-container">
|
||||
<div class="modal-header"></div>
|
||||
<div class="modal-body">
|
||||
<form id="snapcast-client-form" class="snapcast-form" action="#">
|
||||
<div class="row form-row">
|
||||
<div class="two columns">
|
||||
<label for="name">Name</label>
|
||||
</div>
|
||||
<div class="ten columns">
|
||||
<input type="text" name="name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row snapcast-client-info">
|
||||
<div class="row">
|
||||
<div class="three columns info-name">IP Address</div>
|
||||
<div class="nine columns info-value" data-bind="ip"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="three columns info-name">MAC Address</div>
|
||||
<div class="nine columns info-value" data-bind="mac"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="three columns info-name">OS</div>
|
||||
<div class="nine columns info-value" data-bind="os"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="three columns info-name">Architecture</div>
|
||||
<div class="nine columns info-value" data-bind="arch"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="three columns info-name">Client Name</div>
|
||||
<div class="nine columns info-value" data-bind="clientName"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="three columns info-name">Client Version</div>
|
||||
<div class="nine columns info-value" data-bind="clientVersion"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="three columns info-name">Protocol Version</div>
|
||||
<div class="nine columns info-value" data-bind="protocolVersion"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row snapcast-client-delete">
|
||||
<input type="checkbox" name="delete">
|
||||
<label for="delete">Delete client</label>
|
||||
</div>
|
||||
|
||||
<div class="row snapcast-form-bottom">
|
||||
<div class="six columns offset-by-six forms-btns">
|
||||
<input type="button" class="btn-default" data-dismiss-modal="#snapcast-client-modal"
|
||||
value="Close">
|
||||
<input type="submit" class="btn-primary" value="Save">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="snapcast-container" class="row">
|
||||
</div>
|
||||
|
||||
|
|
|
@ -129,7 +129,20 @@ class MusicSnapcastBackend(Backend):
|
|||
|
||||
def _client(self, host, port):
|
||||
def _thread():
|
||||
status = None
|
||||
|
||||
try:
|
||||
status = self._status(host, port)
|
||||
except Exception as e:
|
||||
self.logger.warning(('Exception while getting the status ' +
|
||||
'of the Snapcast server {}:{}: {}').
|
||||
format(host, port, str(e)))
|
||||
|
||||
try:
|
||||
self._disconnect(host, port)
|
||||
time.sleep(5)
|
||||
except:
|
||||
pass
|
||||
|
||||
while not self.should_stop():
|
||||
try:
|
||||
|
|
Loading…
Reference in a new issue