2022-10-06 20:08:04 +02:00
|
|
|
// Timeline drag and drop
|
|
|
|
const tl_cont_attr = {id:"tl_cont", ondrop: "drop(event, this)", ondragover:"allowDrop(event)"};
|
|
|
|
const tl_drag_attr = {id:"tl_drag", draggable:"true", ondragstart:"drag(event, this)"};
|
|
|
|
|
2022-10-08 16:49:45 +02:00
|
|
|
// Config
|
|
|
|
var timeline_color_cursor = "#FF8839";
|
|
|
|
var timeline_color_bg = "#2EB8E6";
|
|
|
|
|
2022-10-06 20:08:04 +02:00
|
|
|
var src_id = "";
|
2022-10-08 16:49:45 +02:00
|
|
|
var medias_status = {};
|
2022-10-06 20:08:04 +02:00
|
|
|
|
|
|
|
function updatePlaylist(){
|
|
|
|
var new_list = [];
|
|
|
|
var media_count = document.getElementById("timeline").children.length;
|
|
|
|
for (i=media_count,l=0;i>l;i--) {
|
|
|
|
//~ new_list.push(document.getElementById("timeline").children[i].children[0].getAttribute("media_id"));
|
|
|
|
toMove = document.getElementById("timeline").children[i-1].children[0].getAttribute("media_id");
|
|
|
|
console.log(toMove);
|
|
|
|
sendCmd("/all/move/" + toMove + "/1");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function findTargetIndex(element, index, array, thisArg){
|
|
|
|
if (element == this) {
|
|
|
|
return index+1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
function moveElements(target) {
|
|
|
|
var elem_list = Array.from(src_id.parentElement.children);
|
|
|
|
var elem_list_slice = elem_list;
|
|
|
|
var source_idx = elem_list.findIndex(findTargetIndex, src_id);
|
|
|
|
var target_idx = elem_list.findIndex(findTargetIndex, target);
|
|
|
|
var idx;
|
|
|
|
if (source_idx < target_idx) {
|
|
|
|
elem_list_slice = elem_list.slice(source_idx+1, target_idx+1);
|
|
|
|
idx = source_idx;
|
|
|
|
} else {
|
|
|
|
elem_list_slice = elem_list.slice(target_idx, source_idx );
|
|
|
|
idx = target_idx+1;
|
|
|
|
}
|
|
|
|
for (i=0, l=elem_list_slice.length; i<l;i++) {
|
|
|
|
elem_list[idx+i].appendChild(elem_list_slice[i].children[0]);
|
|
|
|
}
|
|
|
|
return target;
|
|
|
|
};
|
|
|
|
|
|
|
|
function allowDrop(ev) {
|
|
|
|
ev.preventDefault();
|
|
|
|
drop_id = ev.dataTransfer.getData("text");
|
|
|
|
};
|
|
|
|
|
|
|
|
function drag(ev, source) {
|
|
|
|
src_id = ev.target.parentElement;
|
|
|
|
ev.dataTransfer.setData("text", ev.target.id);
|
|
|
|
};
|
|
|
|
|
|
|
|
function drop(ev, target) {
|
|
|
|
ev.preventDefault();
|
|
|
|
var data = ev.dataTransfer.getData("text");
|
|
|
|
if (src_id.id != target.id) {
|
|
|
|
dropTarget = moveElements(target);
|
|
|
|
if (dropTarget) {
|
|
|
|
dropTarget.appendChild(document.getElementById(data));
|
|
|
|
updatePlaylist();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
function adjustTl() {
|
|
|
|
var child = document.getElementById('timeline').children;
|
|
|
|
var divWidth = 100 / child.length;
|
|
|
|
for (i=0, l=child.length;i<l;i++) {
|
|
|
|
child[i].style.width= divWidth + "%";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-10-08 16:49:45 +02:00
|
|
|
function addAttr(id, attr, val , child=-1) {
|
|
|
|
var elem = document.getElementById(id);
|
|
|
|
if (child>-1){
|
|
|
|
elem = elem.children[child];
|
|
|
|
}
|
|
|
|
var att = document.createAttribute(attr);
|
|
|
|
att.value = val;
|
|
|
|
elem.setAttributeNode(att);
|
|
|
|
};
|
|
|
|
|
|
|
|
function addElement(type, attr, meta = 0, j = 0){
|
2022-10-06 20:08:04 +02:00
|
|
|
var elem = document.createElement(type);
|
|
|
|
var keys_array = Object.keys(attr);
|
|
|
|
for (i=0, l=keys_array.length;i<l;i++) {
|
|
|
|
var att = document.createAttribute(keys_array[i]);
|
|
|
|
if(!i){
|
|
|
|
att.value = Object.values(attr)[i]+j;
|
|
|
|
} else {
|
|
|
|
att.value = Object.values(attr)[i];
|
|
|
|
}
|
|
|
|
elem.setAttributeNode(att);
|
|
|
|
}
|
2022-10-08 16:49:45 +02:00
|
|
|
// Set playlist id attribute
|
|
|
|
if (meta) {
|
|
|
|
att = document.createAttribute("media_id");
|
|
|
|
att.value = meta[0];
|
|
|
|
elem.setAttributeNode(att);
|
|
|
|
}
|
2022-10-06 20:08:04 +02:00
|
|
|
// Get filename
|
|
|
|
elem.innerText = meta[1];
|
|
|
|
return elem;
|
|
|
|
};
|
|
|
|
|
2022-10-06 11:44:59 +02:00
|
|
|
var scanInterval = 3000;
|
|
|
|
// Bouttons de commande
|
|
|
|
addEventListener("DOMContentLoaded", function() {
|
|
|
|
sendCmd("/scan");
|
|
|
|
sendCmd("/browse");
|
|
|
|
sendCmd("/all/rssi");
|
2022-10-06 20:08:04 +02:00
|
|
|
sendCmd("/all/list");
|
|
|
|
adjustTl();
|
2022-10-06 11:44:59 +02:00
|
|
|
// Tous les elements avec la classe ".command"
|
|
|
|
var commandButtons = document.querySelectorAll(".command");
|
|
|
|
for (var i=0, l=commandButtons.length; i<l; i++) {
|
|
|
|
var button = commandButtons[i];
|
|
|
|
// Sur un click
|
|
|
|
button.addEventListener("click", function(event) {
|
|
|
|
// On intercepte le signal
|
|
|
|
event.preventDefault();
|
|
|
|
// On recupere la valeur de value="" sur le bouton
|
|
|
|
var clickedButton = event.currentTarget;
|
|
|
|
var command = clickedButton.value;
|
2022-10-18 19:54:18 +02:00
|
|
|
if ( command.indexOf("/reboot" ) > -1 || command.indexOf("/poweroff") > -1 ) {
|
2022-10-06 11:44:59 +02:00
|
|
|
if ( !confirm("Êtes vous certain de vouloir effectuer cette action ?") ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else if ( command == "/scan" ) {
|
|
|
|
document.getElementById("status_all").innerHTML = "Searching network for live hosts...";
|
|
|
|
} else if ( command.indexOf("/sort") > -1 ){
|
|
|
|
if (command.indexOf('/1/') > -1 ) {
|
|
|
|
clickedButton.value = clickedButton.value.replace('/1/','/0/')
|
|
|
|
} else {
|
|
|
|
clickedButton.value = clickedButton.value.replace('/0/','/1/')
|
|
|
|
}
|
|
|
|
} else if ( command.indexOf("/move") > -1 ) {
|
2022-10-06 20:08:04 +02:00
|
|
|
const test_array = [21,19,20];
|
2022-10-06 11:44:59 +02:00
|
|
|
for (i=test_array.length, l=0;i>l;i--){
|
|
|
|
console.log(test_array[i-1]);
|
|
|
|
sendCmd("/all/move/" + test_array[i-1] + "/1");
|
|
|
|
};
|
2022-10-06 20:08:04 +02:00
|
|
|
sendCmd("/all/list");
|
2022-10-06 11:44:59 +02:00
|
|
|
//setInterval( sendCmd, scanInterval, "/all/move/16/1");
|
|
|
|
};
|
|
|
|
|
|
|
|
// On envoie la commande en AJAX
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
if ( command == "/scan" ) {
|
2022-10-06 20:08:04 +02:00
|
|
|
request.onload = sendCmd(command);
|
2022-10-06 11:44:59 +02:00
|
|
|
}
|
|
|
|
// On construit la commande
|
|
|
|
request.open("GET", command, true);
|
|
|
|
// et on l'envoie
|
|
|
|
request.send();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}, true);
|
|
|
|
|
|
|
|
// Affichage des infos
|
|
|
|
function parseResult(command, infos_array) {
|
2022-10-06 20:08:04 +02:00
|
|
|
switch (command) {
|
|
|
|
case "/all/status":
|
|
|
|
// Iterate over array
|
|
|
|
for (var i = 0, l=infos_array.length; i<l; i++) {
|
2022-10-08 16:49:45 +02:00
|
|
|
// Get filename, time/length
|
|
|
|
document.getElementById("status_"+infos_array[i].host).innerHTML = infos_array[i].file + " <br/> " + infos_array[i].time + " / " + infos_array[i].leng;
|
|
|
|
medias_status[infos_array[i].id] = infos_array[i].pos;
|
|
|
|
// Find currently playing element
|
|
|
|
//~ var pl_length = document.getElementById("timeline").getAttribute("length");
|
|
|
|
//~ for (j=0,k=pl_length;j<k;j++){
|
|
|
|
//~ if (document.getElementById("timeline").children[j].children[0].getAttribute('media_id') == infos_array[i].id ) {
|
|
|
|
//~ addAttr(document.getElementById("timeline").children[j].children[0].id, "pos", infos_array[i].pos);
|
|
|
|
//~ }
|
|
|
|
//~ };
|
|
|
|
//~ document.getElementById("timeline").children[0].children[0].hasAttribute('media_id')
|
|
|
|
// Toggle loop indicator
|
|
|
|
if (infos_array[i].loop == "true") {
|
|
|
|
document.getElementById("loop_ind_" + infos_array[i].host).style.backgroundColor = "#0f0"
|
|
|
|
} else {
|
|
|
|
document.getElementById("loop_ind_" + infos_array[i].host).style.backgroundColor = "#f00"
|
|
|
|
};
|
|
|
|
// Toggle repeat indicator
|
|
|
|
if (infos_array[i].repeat == "true") {
|
|
|
|
document.getElementById("repeat_ind_" + infos_array[i].host).style.backgroundColor = "#0f0"
|
|
|
|
} else {
|
|
|
|
document.getElementById("repeat_ind_" + infos_array[i].host).style.backgroundColor = "#f00"
|
|
|
|
};
|
2022-10-06 20:08:04 +02:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
case "/all/list":
|
|
|
|
|
|
|
|
for (var i = 0, l=infos_array.length; i<l; i++) {
|
|
|
|
// Fill Playlist infos
|
|
|
|
document.getElementById("playlist_"+infos_array[i].host).innerHTML = infos_array[i].leng + " item(s) in playlist - " + infos_array[i].duration;
|
|
|
|
// Build html table and timeline
|
|
|
|
var items_array = Array.from(infos_array[i].items);
|
2022-10-18 19:54:18 +02:00
|
|
|
console.log(items_array.length);
|
|
|
|
if (items_array.length == 0){
|
|
|
|
var child_list = Array.from(document.getElementById("timeline").children);
|
|
|
|
for(i=0,l=child_list.length;i<l;i++){
|
|
|
|
document.getElementById("timeline").removeChild(child_list[i]);
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
}
|
2022-10-06 20:08:04 +02:00
|
|
|
var html_table = "<table>" +
|
|
|
|
"<tr>" +
|
|
|
|
"<th>Id</th>" +
|
|
|
|
"<th>Filename</th>" +
|
|
|
|
"<th>Duration</th>" +
|
|
|
|
"</tr>";
|
|
|
|
for (var j = 0, k=items_array.length; j<k; j++) {
|
|
|
|
// Table
|
|
|
|
item_meta = items_array[j].split(';');
|
|
|
|
html_table += "<tr>" +
|
|
|
|
"<td>" + item_meta[0] + "</td>" +
|
|
|
|
"<td>" + item_meta[1] + "</td>" +
|
|
|
|
"<td>" + item_meta[2] + "</td>" +
|
|
|
|
"</tr>" ;
|
|
|
|
// Timeline
|
|
|
|
var child_node = addElement("div", tl_drag_attr, item_meta, j);
|
|
|
|
var len = document.getElementById("timeline").children.length;
|
2022-10-08 16:49:45 +02:00
|
|
|
addAttr("timeline", "length", len);
|
2022-10-06 20:08:04 +02:00
|
|
|
if ( len < items_array.length ) {
|
2022-10-08 16:49:45 +02:00
|
|
|
document.getElementById("timeline").appendChild( addElement("div", tl_cont_attr, 0, len) );
|
2022-10-18 19:54:18 +02:00
|
|
|
}
|
2022-10-06 20:08:04 +02:00
|
|
|
document.getElementById(tl_cont_attr.id + j).replaceChildren(child_node);
|
2022-10-18 19:54:18 +02:00
|
|
|
// Adjust elements width
|
2022-10-08 16:49:45 +02:00
|
|
|
adjustTl();
|
2022-10-18 19:54:18 +02:00
|
|
|
// Highlight currently playing element
|
2022-10-06 20:08:04 +02:00
|
|
|
if (item_meta[3] != ""){
|
2022-10-08 16:49:45 +02:00
|
|
|
document.getElementById(tl_cont_attr.id + j).children[0].style.borderBottom = "4px solid " + timeline_color_cursor;
|
|
|
|
document.getElementById(tl_cont_attr.id + j).children[0].style.fontWeight = "bold";
|
|
|
|
var pos = medias_status[item_meta[0]] * 100;
|
|
|
|
//~ pos = pos.toPrecision(2);
|
|
|
|
var pos1 = pos-1 + "%";
|
|
|
|
pos = pos + "%";
|
|
|
|
//console.log( "linear-gradient(90deg," + timeline_color2 + " " + pos1 + ", " + timeline_color1 + " " + pos + ", " + timeline_color2 + " " + pos + ")" );
|
|
|
|
document.getElementById(tl_cont_attr.id + j).children[0].style.background = "linear-gradient(90deg," + timeline_color_bg + " " + pos1 + ", " + timeline_color_cursor + " " + pos + ", " + timeline_color_bg + " " + pos + ")";
|
2022-10-06 20:08:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
html_table += "</table>";
|
|
|
|
document.getElementById("playlist_"+infos_array[i].host).innerHTML += html_table;
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case "/scan":
|
|
|
|
var host_up = infos_array[0];
|
|
|
|
var host_down = infos_array[1];
|
|
|
|
for ( var i=0, l=host_up.length; i<l; i++){
|
2022-10-08 16:49:45 +02:00
|
|
|
document.getElementById(host_up[i]).style.display = 'block';
|
2022-10-06 20:08:04 +02:00
|
|
|
}
|
|
|
|
for ( var i=0, l=host_down.length; i<l; i++){
|
|
|
|
document.getElementById(host_down[i]).style.display = 'none';
|
|
|
|
}
|
|
|
|
//~ if (host_up.length) {
|
|
|
|
//~ scanInterval = 10000;
|
|
|
|
//~ document.getElementById("status_all").innerHTML = "Scan intarvel set to " + scanInterval;
|
|
|
|
//~ }
|
|
|
|
document.getElementById("status_all").innerHTML = host_up.length + " client(s) found.";
|
|
|
|
break;
|
|
|
|
case "/browse":
|
|
|
|
var html_table = "<table>" +
|
|
|
|
"<tr>" +
|
|
|
|
"<th>Filename</th>" +
|
|
|
|
"<th>Duration</th>" +
|
|
|
|
"</tr>";
|
|
|
|
for (var j = 0, k=infos_array.length; j<k; j++) {
|
|
|
|
html_table += "<tr>" +
|
|
|
|
"<td>" + infos_array[j] + "</td>" +
|
|
|
|
"<td>" + "00:00" + "</td>" +
|
|
|
|
"</tr>" ;
|
|
|
|
}
|
|
|
|
html_table += "</table>";
|
|
|
|
document.getElementById("filelist").innerHTML += html_table;
|
|
|
|
break;
|
|
|
|
case "/all/rssi":
|
|
|
|
var signal_color = 40;
|
|
|
|
var best_rssi = 30;
|
|
|
|
var worst_rssi = 70;
|
|
|
|
for (var j = 0, k=infos_array.length; j<k; j++) {
|
|
|
|
var rssi_norm = Math.ceil( (worst_rssi - parseInt(infos_array[j].rssi) ) / ( worst_rssi - best_rssi ) * 4 );
|
|
|
|
signal_color = (rssi_norm-1) * signal_color;
|
|
|
|
// Reset to grey
|
|
|
|
for (i=0, l=4; i<l;i++) {
|
|
|
|
document.getElementById("wl_"+i).style.backgroundColor = "hsl(0, 0%, 65%)";
|
|
|
|
};
|
|
|
|
// Color it
|
|
|
|
for (i=0, l=rssi_norm; i<l;i++) {
|
|
|
|
document.getElementById("wl_"+i).style.backgroundColor = "hsl(" + signal_color + ", 100%, 50%)";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
}; // End switch case
|
2022-10-06 11:44:59 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
function sendCmd(command) {
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
request.onload = function() {
|
|
|
|
if (request.readyState === request.DONE) {
|
|
|
|
if (request.status === 200) {
|
|
|
|
// responseText is a string, use parse to get an array.
|
|
|
|
var infos_array = JSON.parse(request.responseText);
|
|
|
|
//console.log(infos_array);
|
|
|
|
parseResult(command, infos_array);
|
|
|
|
//return infos_array;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// On construit la commande
|
|
|
|
request.open("GET", command, true);
|
|
|
|
// et on l'envoie
|
|
|
|
request.send();
|
|
|
|
};
|
2022-10-06 20:08:04 +02:00
|
|
|
|
2022-10-06 11:44:59 +02:00
|
|
|
setInterval( sendCmd, 500, "/all/status");
|
|
|
|
setInterval( sendCmd, 1000, "/all/list");
|
|
|
|
setInterval( sendCmd, scanInterval, "/scan");
|
|
|
|
setInterval( sendCmd, 10000, "/all/rssi");
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO :
|
|
|
|
* Change scanInterval after first results are in (3 to 30 seconds)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|