2019-11-16 23:35:23 +00:00
|
|
|
<!DOCTYPE html>
|
2019-11-16 22:03:13 +00:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
|
|
<title>ESMP3</title>
|
|
|
|
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=" crossorigin="anonymous"></script>
|
|
|
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
|
|
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
|
|
|
<script src="https://kit.fontawesome.com/272149490a.js" crossorigin="anonymous"></script>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body>
|
|
|
|
<div class="container bg-dark text-light">
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-sm-1">
|
|
|
|
<h1 id="play_state_icon"><i class="fa fa-stop"></i></h1>
|
|
|
|
</div>
|
|
|
|
<div class="col-sm-11">
|
|
|
|
<h2><i class="fa fa-compact-disc"></i> <span id="album"></span></h2>
|
|
|
|
<h2><i class="fa fa-scroll"></i> <span id="track"></span></h2>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="container">
|
|
|
|
<div class="row">
|
|
|
|
<div class="col">
|
|
|
|
<input type="range" class="custom-range" id="position_slider" disabled>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-sm-6">
|
|
|
|
</div>
|
|
|
|
<div class="col-sm-1">
|
|
|
|
<h3><i class="fa fa-volume-down"></i></h3>
|
|
|
|
</div>
|
|
|
|
<div class="col-sm-4">
|
|
|
|
<input type="range" class="custom-range" id="volume_slider">
|
|
|
|
</div>
|
|
|
|
<div class="col-sm-1">
|
|
|
|
<h3><i class="fa fa-volume-up"></i></h3>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_track_prev"><i class="fa fa-step-backward"></i></button>
|
|
|
|
</div>
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_stop"><i class="fa fa-stop"></i></button>
|
|
|
|
</div>
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_play"><i class="fa fa-play"></i></button>
|
|
|
|
</div>
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_track_next"><i class="fa fa-step-forward"></i></button>
|
|
|
|
</div>
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_lock"><i class="fa fa-lock-open"></i></button>
|
|
|
|
</div>
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_open"><i class="fa fa-eject"></i></button>
|
2019-11-16 23:35:23 +00:00
|
|
|
</div>
|
|
|
|
<div class="col">
|
|
|
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_settings"><i class="fa fa-cog"></i></button>
|
|
|
|
</div>
|
2019-11-16 22:03:13 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="container">
|
|
|
|
<table class="table table-hover table-sm" id="track_list_table">
|
|
|
|
<thead class="thead-light">
|
|
|
|
<tr>
|
|
|
|
<th>Nr.</th>
|
|
|
|
<th>Status</th>
|
|
|
|
<th>Track</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody class="" id="track_list">
|
|
|
|
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="modal fade" id="openModal" tabindex="-1" role="dialog">
|
|
|
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title">Album öffnen</h5>
|
|
|
|
<button type="button" class="close" data-dismiss="modal">
|
|
|
|
<span>×</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
<div id="albums_without_id_area">
|
|
|
|
<h6>Albums without RFID card</h6>
|
|
|
|
<table class="table table-hover table-sm">
|
|
|
|
<tbody id="albums_without_id">
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<h6>Albums with RFID</h6>
|
|
|
|
<table class="table table-hover table-sm">
|
|
|
|
<tbody id="albums_with_id">
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-11-16 23:35:23 +00:00
|
|
|
|
|
|
|
<div class="modal fade" id="settingsModal" tabindex="-1" role="dialog">
|
|
|
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title">Settings</h5>
|
|
|
|
<button type="button" class="close" data-dismiss="modal">
|
|
|
|
<span>×</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
<h6>Last RFID id:</h6>
|
|
|
|
<span id="last_rfid_id"></span> <button class="btn btn-warning" id="button_add_mapping"><i class="fa fa-arrows-alt-h"></i></button>
|
|
|
|
|
|
|
|
<h6>Last RFID data:</h6>
|
|
|
|
<span id="last_rfid_data"></span>
|
|
|
|
|
|
|
|
<h6>Actions</h6>
|
|
|
|
<button type="button" class="btn btn-danger btn-lg btn-block" id="button_reset_vs1053">Reset VS1053 chip</button>
|
|
|
|
<button type="button" class="btn btn-danger btn-lg btn-block" id="button_reboot">Reboot ESMP3</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-11-16 22:03:13 +00:00
|
|
|
</body>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
update_player = function(data) {
|
|
|
|
$('#play_state_icon i').removeClass('fa-stop', 'fa-play').addClass(data.playing ? 'fa-play' : 'fa-stop');
|
|
|
|
|
|
|
|
if (data.playing) {
|
|
|
|
$('#button_play').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
|
|
|
$('#button_stop').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
|
|
|
} else if (data.playlist) {
|
|
|
|
$('#button_play').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
|
|
|
$('#button_stop').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
|
|
|
} else {
|
|
|
|
$('#button_play').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
|
|
|
$('#button_stop').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
|
|
|
}
|
|
|
|
|
|
|
|
$('#volume_slider').attr('min', data.volume.min).attr('max', data.volume.max).val(data.volume.current);
|
|
|
|
|
|
|
|
if (data.playlist) update_playlist(data.playlist);
|
|
|
|
}
|
|
|
|
|
|
|
|
update_playlist = function(data) {
|
|
|
|
$('#track_list tr').remove();
|
|
|
|
for (var i=0; i<data.files.length; i++) {
|
|
|
|
tr = $('<tr>').data('track', i);
|
|
|
|
tr.append($('<td>').html(i + 1));
|
|
|
|
tr.append($('<td>').html(data.current_track==i ? '<i class="fa fa-play"></i>' : ''));
|
|
|
|
tr.append($('<td>').html(data.files[i].substr(data.files[i].lastIndexOf('/')+1)));
|
|
|
|
$('#track_list').append(tr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.has_track_next) {
|
|
|
|
$('#button_track_next').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
|
|
|
} else {
|
|
|
|
$('#button_track_next').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.has_track_prev) {
|
|
|
|
$('#button_track_prev').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
|
|
|
} else {
|
|
|
|
$('#button_track_prev').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
|
|
|
}
|
|
|
|
|
|
|
|
var file = data.files[data.current_track];
|
|
|
|
if (file) {
|
|
|
|
file = file.substr(1);
|
|
|
|
$('#album').html(file.substr(0, file.indexOf('/')));
|
|
|
|
file = file.substr(file.indexOf('/')+1);
|
|
|
|
$('#track').html(file.substr(0, file.lastIndexOf('.')));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
update_controller = function(data) {
|
|
|
|
if (data.lock_state == "locked") {
|
|
|
|
$('#button_lock').removeClass('btn-primary', 'btn-warning').addClass('btn-danger');
|
|
|
|
$('#button_lock i').removeClass('fa-lock-open').addClass('fa-lock');
|
|
|
|
} else if (data.lock_state == "locking") {
|
|
|
|
$('#button_lock').removeClass('btn-primary', 'btn-danger').addClass('btn-warning');
|
|
|
|
$('#button_lock i').removeClass('fa-lock-open').addClass('fa-lock');
|
|
|
|
} else {
|
|
|
|
$('#button_lock').removeClass('btn-danger', 'btn-warning').addClass('btn-primary');
|
|
|
|
$('#button_lock i').removeClass('fa-lock').addClass('fa-lock-open');
|
|
|
|
}
|
2019-11-16 23:35:23 +00:00
|
|
|
|
|
|
|
$('#button_add_mapping').toggle(data.last_rfid.uid.length>0);
|
|
|
|
$('#last_rfid_id').html(data.last_rfid.uid);
|
|
|
|
$('#last_rfid_data').html(data.last_rfid.data);
|
2019-11-16 22:03:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
update_playlist_manager = function(data) {
|
|
|
|
if (data.unmapped.length > 0) {
|
|
|
|
$('#albums_without_id_area').show();
|
|
|
|
$('#albums_without_id tr').remove();
|
|
|
|
data.unmapped = data.unmapped.sort();
|
|
|
|
for (var i=0; i<data.unmapped.length; i++) {
|
2019-11-16 23:35:23 +00:00
|
|
|
var tr = $('<tr>').attr('data-folder', data.unmapped[i]);
|
|
|
|
tr.append($('<td>').html(data.unmapped[i].substr(1)));
|
|
|
|
tr.append($('<td>').append($('<button>').addClass('button btn-warning add_mapping_button').hide().append($('<i>').addClass('fa fa-arrows-alt-h'))));
|
2019-11-16 22:03:13 +00:00
|
|
|
$('#albums_without_id').append(tr);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$('#albums_without_id_area').hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
var folders = Object.keys(data.folders).sort();
|
|
|
|
for (var i in folders) {
|
|
|
|
var folder = folders[i];
|
|
|
|
var tr = $('<tr>').attr('data-folder', folder);
|
|
|
|
tr.append($('<td>').html(folder.substr(1)));
|
2019-11-16 23:35:23 +00:00
|
|
|
tr.append($('<td>').append($('<button>').addClass('button btn-danger add_mapping_button').hide().append($('<i>').addClass('fa fa-arrows-alt-h'))));
|
2019-11-16 22:03:13 +00:00
|
|
|
$('#albums_with_id').append(tr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
update_position = function(data) {
|
|
|
|
$('#position_slider').attr('max', data.file_size).val(data.position);
|
|
|
|
}
|
|
|
|
|
|
|
|
process_ws_message = function(event) {
|
|
|
|
var data = event.data.split("\n");;
|
|
|
|
for (var i=0; i<data.length; i++) {
|
|
|
|
var json = JSON.parse(data[i]);
|
|
|
|
console.log(json);
|
|
|
|
switch(json["_type"]) {
|
|
|
|
case "position": update_position(json); break;
|
|
|
|
case "player": update_player(json); break;
|
|
|
|
case "playlist_manager": update_playlist_manager(json); break;
|
2019-11-16 23:35:23 +00:00
|
|
|
case "controller": update_controller(json); break;
|
2019-11-16 22:03:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$(function() {
|
|
|
|
ws = new WebSocket("ws://" + location.host + "/ws");
|
|
|
|
ws.onmessage = process_ws_message;
|
|
|
|
|
|
|
|
$('#volume_slider').change(function(e) { ws.send("volume=" + e.target.value); });
|
|
|
|
$('#button_play').click(function(e) { ws.send("play"); });
|
|
|
|
$('#button_stop').click(function(e) { ws.send("stop"); });
|
|
|
|
$('#button_track_next').click(function(e) { ws.send("track_next"); });
|
|
|
|
$('#button_track_prev').click(function(e) { ws.send("track_prev"); });
|
|
|
|
$('#button_open').click(function(e) { $('#openModal').modal('show'); });
|
|
|
|
$('#track_list').on('click', 'tr', function(e) { ws.send("track=" + $(e.target).parent().data('track')); });
|
2019-11-16 23:35:23 +00:00
|
|
|
$('#albums_without_id, #albums_with_id').on('click', 'tr', function(e) { ws.send("play " + $(e.target).parents('tr').data('folder')); $('#openModal').modal('hide'); });
|
|
|
|
$('#button_settings').click(function(e) { $('#settingsModal').modal('show'); });
|
|
|
|
$('#button_reset_vs1053').click(function(e) { ws.send("reset_vs1053"); $('#settingsModal').modal('hide'); });
|
|
|
|
$('#button_reboot').click(function(e) { ws.send("reboot"); $('#settingsModal').modal('hide'); });
|
|
|
|
$('#button_add_mapping').click(function(e) {
|
|
|
|
$('#settingsModal').modal('hide');
|
|
|
|
$('#openModal').modal('show');
|
|
|
|
$('.add_mapping_button').show();
|
|
|
|
});
|
|
|
|
$('#openModal').on('click', '.add_mapping_button', function(e) {console.log("add_mapping=" + $('#last_rfid_id').html() + "=" + $(e.target).parents('tr').data('folder')); $('#openModal').modal('hide'); $('.add_mapping_button').hide(); e.stopPropagation();});
|
2019-11-16 22:03:13 +00:00
|
|
|
});
|
|
|
|
</script>
|
|
|
|
</html>
|