Massive changes. Added a quite nice webinterface with live data using WebSockets. Removed the FTP server (wasn't that useful anyways). JSON creating using ArduinoJson instead of String concatenation. Ans, and, and.
This commit is contained in:
236
include/index.html
Normal file
236
include/index.html
Normal file
@ -0,0 +1,236 @@
|
||||
const char* html = R"V0G0N(<!DOCTYPE html>
|
||||
<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>
|
||||
</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>
|
||||
</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');
|
||||
}
|
||||
}
|
||||
|
||||
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++) {
|
||||
var tr = $('<tr>').attr('data-folder', data.unmapped[i]).append($('<td>').html(data.unmapped[i].substr(1)));
|
||||
$('#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)));
|
||||
$('#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(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')); });
|
||||
$('#albums_without_id, #albums_with_id').on('click', 'tr', function(e) { ws.send("play " + $(e.target).parent().data('folder')); $('#openModal').modal('hide'); });
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
||||
)V0G0N";
|
Reference in New Issue
Block a user