310 lines
13 KiB
HTML
310 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>MBC rc boatjes - commander</title>
|
|
<style>
|
|
* {
|
|
--background: #000000;
|
|
--background-second: #222222;
|
|
--foreground: #CCCCCC;
|
|
}
|
|
body {
|
|
background-color: var(--background);
|
|
color: var(--foreground);
|
|
}
|
|
.login {
|
|
position: fixed;
|
|
top: 50px;
|
|
right: 50px;
|
|
bottom: 50px;
|
|
left: 50px;
|
|
background-color: var(--background-second);
|
|
text-align: center;
|
|
padding: calc(50vh - 150px) 50px;
|
|
height: 200px;
|
|
}
|
|
.btn {
|
|
padding: 5px 10px;
|
|
cursor: pointer;
|
|
display: inline-block;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="login">
|
|
<input id="pass" type="password" value="1234" />
|
|
<button id="login">login</button>
|
|
</div>
|
|
<main>
|
|
<div id="refresh" class="btn">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
|
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2z"/>
|
|
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466"/>
|
|
</svg>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<caption>bootjes</caption>
|
|
<tr>
|
|
<th>id</th>
|
|
<th>naam</th>
|
|
<th>status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="boatjes"></tbody>
|
|
</table>
|
|
<table>
|
|
<thead>
|
|
<caption>clients</caption>
|
|
<tr>
|
|
<th>id</th>
|
|
<th>boat</th>
|
|
<th>status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="clients"></tbody>
|
|
</table>
|
|
</main>
|
|
<script>
|
|
const passEl = document.getElementById('pass');
|
|
const loginEl = document.getElementById('login');
|
|
const boatjesEl = document.getElementById('boatjes');
|
|
const clientsEl = document.getElementById('clients');
|
|
|
|
const kickIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-hand-thumbs-down\" viewBox=\"0 0 16 16\"><path d=\"M8.864 15.674c-.956.24-1.843-.484-1.908-1.42-.072-1.05-.23-2.015-.428-2.59-.125-.36-.479-1.012-1.04-1.638-.557-.624-1.282-1.179-2.131-1.41C2.685 8.432 2 7.85 2 7V3c0-.845.682-1.464 1.448-1.546 1.07-.113 1.564-.415 2.068-.723l.048-.029c.272-.166.578-.349.97-.484C6.931.08 7.395 0 8 0h3.5c.937 0 1.599.478 1.934 1.064.164.287.254.607.254.913 0 .152-.023.312-.077.464.201.262.38.577.488.9.11.33.172.762.004 1.15.069.13.12.268.159.403.077.27.113.567.113.856s-.036.586-.113.856c-.035.12-.08.244-.138.363.394.571.418 1.2.234 1.733-.206.592-.682 1.1-1.2 1.272-.847.283-1.803.276-2.516.211a10 10 0 0 1-.443-.05 9.36 9.36 0 0 1-.062 4.51c-.138.508-.55.848-1.012.964zM11.5 1H8c-.51 0-.863.068-1.14.163-.281.097-.506.229-.776.393l-.04.025c-.555.338-1.198.73-2.49.868-.333.035-.554.29-.554.55V7c0 .255.226.543.62.65 1.095.3 1.977.997 2.614 1.709.635.71 1.064 1.475 1.238 1.977.243.7.407 1.768.482 2.85.025.362.36.595.667.518l.262-.065c.16-.04.258-.144.288-.255a8.34 8.34 0 0 0-.145-4.726.5.5 0 0 1 .595-.643h.003l.014.004.058.013a9 9 0 0 0 1.036.157c.663.06 1.457.054 2.11-.163.175-.059.45-.301.57-.651.107-.308.087-.67-.266-1.021L12.793 7l.353-.354c.043-.042.105-.14.154-.315.048-.167.075-.37.075-.581s-.027-.414-.075-.581c-.05-.174-.111-.273-.154-.315l-.353-.354.353-.354c.047-.047.109-.176.005-.488a2.2 2.2 0 0 0-.505-.804l-.353-.354.353-.354c.006-.005.041-.05.041-.17a.9.9 0 0 0-.121-.415C12.4 1.272 12.063 1 11.5 1\"/></svg>"
|
|
const banIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-slash-circle\" viewBox=\"0 0 16 16\"><path d=\"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16\"/><path d=\"M11.354 4.646a.5.5 0 0 0-.708 0l-6 6a.5.5 0 0 0 .708.708l6-6a.5.5 0 0 0 0-.708\"/></svg>";
|
|
const openIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-key\" viewBox=\"0 0 16 16\"><path d=\"M0 8a4 4 0 0 1 7.465-2H14a.5.5 0 0 1 .354.146l1.5 1.5a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0L13 9.207l-.646.647a.5.5 0 0 1-.708 0L11 9.207l-.646.647a.5.5 0 0 1-.708 0L9 9.207l-.646.647A.5.5 0 0 1 8 10h-.535A4 4 0 0 1 0 8m4-3a3 3 0 1 0 2.712 4.285A.5.5 0 0 1 7.163 9h.63l.853-.854a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .708 0l.646.647.793-.793-1-1h-6.63a.5.5 0 0 1-.451-.285A3 3 0 0 0 4 5\"/><path d=\"M4 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0\"/></svg>";
|
|
const lockIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-lock\" viewBox=\"0 0 16 16\"><path d=\"M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2m3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2M5 8h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1\"/></svg>";
|
|
const freeIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-calendar-event\" viewBox=\"0 0 16 16\"><path d=\"M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\"/><path d=\"M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z\"/></svg>"
|
|
const logIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-list-check\" viewBox=\"0 0 16 16\"> <path fill-rule=\"evenodd\" d=\"M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M3.854 2.146a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708L2 3.293l1.146-1.147a.5.5 0 0 1 .708 0m0 4a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708L2 7.293l1.146-1.147a.5.5 0 0 1 .708 0m0 4a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 0 1 .708-.708l.146.147 1.146-1.147a.5.5 0 0 1 .708 0\"/></svg>"
|
|
|
|
|
|
const serverURL = 'ws://10.254.0.1:8080/';
|
|
|
|
var conn = false;
|
|
var boats = [];
|
|
var boatsLocked = [];
|
|
|
|
loginEl.addEventListener('click', login);
|
|
document.getElementById('refresh').addEventListener('click', refreshAll);
|
|
|
|
function login(e)
|
|
{
|
|
if (conn) conn.close();
|
|
conn = new WebSocket(serverURL, ['mbcRcRf']);
|
|
conn.addEventListener('open', onOpen);
|
|
conn.addEventListener('message', onMessage);
|
|
}
|
|
|
|
function onOpen(e)
|
|
{
|
|
conn.send(passEl.value + ";4675;" + Math.floor(new Date().getTime()/1000.0));
|
|
refreshAll()
|
|
}
|
|
|
|
function refreshAll()
|
|
{
|
|
reqBoats();
|
|
reqLockedBoats();
|
|
reqClients();
|
|
}
|
|
|
|
function onMessage(e)
|
|
{
|
|
console.log("recive: ", e.data);
|
|
let msg = e.data.split(':')
|
|
let data = msg[0];
|
|
msg.splice(0, 1);
|
|
msg = msg.join(':');
|
|
switch (data)
|
|
{
|
|
case 'boats':
|
|
boatjesEl.innerHTML = "";
|
|
addBoats(msg);
|
|
addBoats(boatsLocked);
|
|
boats = msg;
|
|
break;
|
|
case 'lockedBoats':
|
|
boatjesEl.innerHTML = "";
|
|
addBoats(boats);
|
|
addBoats(msg);
|
|
boatsLocked = msg;
|
|
passEl.parentElement.style.display = 'none';
|
|
break;
|
|
case 'clients':
|
|
addClients(msg);
|
|
break;
|
|
default:
|
|
console.warn('onMessage(): invlid data type (' + data + ')');
|
|
break;
|
|
}
|
|
}
|
|
|
|
function getDataFomEl(el)
|
|
{
|
|
while (el.tagName != "BODY" && el.dataset['id'] == null)
|
|
{
|
|
el = el.parentElement;
|
|
}
|
|
return el.dataset;
|
|
}
|
|
|
|
function kickClient(e)
|
|
{
|
|
let client = getDataFomEl(e.target);
|
|
console.log("kickClient", client);
|
|
conn.send(passEl.value + ";kick;" + client['id']);
|
|
}
|
|
|
|
function freeBoat(e)
|
|
{
|
|
let boat = getDataFomEl(e.target);
|
|
console.log("unlockBoat", boat);
|
|
conn.send(passEl.value + ";free;" + boat['id']);
|
|
}
|
|
|
|
function lockBoat(e)
|
|
{
|
|
let boat = getDataFomEl(e.target);
|
|
console.log("lockBoat", boat);
|
|
conn.send(passEl.value + ";lock;" + boat['id']);
|
|
}
|
|
|
|
function getBoatLog(e)
|
|
{
|
|
alert("loggy log");
|
|
}
|
|
|
|
function reqBoats()
|
|
{
|
|
conn.send(passEl.value + ";boats");
|
|
}
|
|
|
|
function reqLockedBoats()
|
|
{
|
|
conn.send(passEl.value + ";locked");
|
|
}
|
|
|
|
function reqClients()
|
|
{
|
|
conn.send(passEl.value + ";clients");
|
|
}
|
|
|
|
function addBoats(boats)
|
|
{
|
|
if (boats == "")
|
|
{
|
|
return;
|
|
}
|
|
boats = boats.split(':');
|
|
for (let boat in boats)
|
|
{
|
|
if (boats[boat] != "")
|
|
{
|
|
addBoat(boats[boat]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function addBoat(boat)
|
|
{
|
|
boat = boat.split(';')
|
|
if (boat.length == 3)
|
|
{
|
|
let boatRow = document.createElement("tr");
|
|
boatRow.className = "boat";
|
|
boatRow.dataset['id'] = boat[0];
|
|
boatRow.dataset['name'] = boat[1];
|
|
boatRow.dataset['state'] = boat[2];
|
|
let boatCells = [
|
|
document.createElement("td"),
|
|
document.createElement("td"),
|
|
document.createElement("td"),
|
|
document.createElement("td")
|
|
]
|
|
boatCells[0].innerText = boat[0];
|
|
boatCells[1].innerText = boat[1];
|
|
boatCells[2].innerText = boat[2];
|
|
let lockBtn = document.createElement("div");
|
|
lockBtn.className = "btn";
|
|
lockBtn.innerHTML = lockIcon;
|
|
lockBtn.ariaLabel = "lock";
|
|
lockBtn.addEventListener('click', lockBoat);
|
|
boatCells[3].append(lockBtn);
|
|
let freeBtn = document.createElement("div");
|
|
freeBtn.className = "btn";
|
|
freeBtn.innerHTML = freeIcon;
|
|
lockBtn.ariaLabel = "free";
|
|
freeBtn.addEventListener('click', freeBoat);
|
|
boatCells[3].append(freeBtn);
|
|
let logBtn = document.createElement("div");
|
|
logBtn.className = "btn";
|
|
logBtn.innerHTML = logIcon;
|
|
lockBtn.ariaLabel = "view log";
|
|
logBtn.addEventListener('click', getBoatLog);
|
|
boatCells[3].append(logBtn);
|
|
for (cell in boatCells)
|
|
{
|
|
boatRow.append(boatCells[cell]);
|
|
}
|
|
boatjesEl.append(boatRow);
|
|
}
|
|
else
|
|
{
|
|
console.warn("addBoat(): incorect number of args (" + boat.length.toString() + "; " + boat.toString() + ")");
|
|
}
|
|
}
|
|
|
|
function addClients(clients)
|
|
{
|
|
clientsEl.innerHTML = "";
|
|
clients = clients.split(':');
|
|
for (let client in clients)
|
|
{
|
|
if (clients[client] != "")
|
|
{
|
|
addClient(clients[client]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function addClient(client)
|
|
{
|
|
client = client.split(';')
|
|
if (client.length == 3)
|
|
{
|
|
let clientRow = document.createElement("tr");
|
|
clientRow.className = "client";
|
|
clientRow.dataset['id'] = client[0];
|
|
clientRow.dataset['boat'] = client[1];
|
|
clientRow.dataset['state'] = client[2];
|
|
let clientCells = [
|
|
document.createElement("td"),
|
|
document.createElement("td"),
|
|
document.createElement("td"),
|
|
document.createElement("td")
|
|
]
|
|
clientCells[0].innerText = client[0];
|
|
clientCells[1].innerText = client[1];
|
|
clientCells[2].innerText = client[2];
|
|
let kickBtn = document.createElement("div");
|
|
kickBtn.className = "btn";
|
|
kickBtn.innerHTML = kickIcon;
|
|
kickBtn.addEventListener('click', kickClient);
|
|
clientCells[3].append(kickBtn);
|
|
for (cell in clientCells)
|
|
{
|
|
clientRow.append(clientCells[cell]);
|
|
}
|
|
clientsEl.append(clientRow);
|
|
}
|
|
else
|
|
{
|
|
console.warn("addClient(): incorect number of args (" + client.length.toString() + "; " + client.toString() + ")");
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |