105 lines
3.0 KiB
JavaScript
105 lines
3.0 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
const socket = io();
|
||
|
let connected = false;
|
||
|
let keystrokeId = 0;
|
||
|
const processingQueue = [];
|
||
|
|
||
|
function onSocketConnect() {
|
||
|
connected = true;
|
||
|
document.getElementById('status-connected').style.display = 'inline-block';
|
||
|
document.getElementById('status-disconnected').style.display = 'none';
|
||
|
document.getElementById('instructions').style.visibility = 'visible';
|
||
|
document.getElementById('disconnect-reason').style.visibility = 'hidden';
|
||
|
}
|
||
|
|
||
|
function onSocketDisconnect(reason) {
|
||
|
connected = false;
|
||
|
document.getElementById('status-connected').style.display = 'none';
|
||
|
document.getElementById('status-disconnected').style.display = 'inline-block';
|
||
|
document.getElementById('disconnect-reason').style.visibility = 'visible';
|
||
|
document.getElementById('disconnect-reason').innerText = 'Error: ' + reason;
|
||
|
document.getElementById('instructions').style.visibility = 'hidden';
|
||
|
}
|
||
|
|
||
|
function limitRecentKeys(limit) {
|
||
|
const recentKeysDiv = document.getElementById('recent-keys');
|
||
|
while (recentKeysDiv.childElementCount > limit) {
|
||
|
recentKeysDiv.removeChild(recentKeysDiv.firstChild);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function addKeyCard(key, keystrokeId) {
|
||
|
const card = document.createElement('div');
|
||
|
card.classList.add('key-card');
|
||
|
if (key === ' ') {
|
||
|
card.innerHTML = ' ';
|
||
|
} else {
|
||
|
card.innerText = key;
|
||
|
}
|
||
|
card.setAttribute('keystroke-id', keystrokeId);
|
||
|
document.getElementById('recent-keys').appendChild(card);
|
||
|
limitRecentKeys(10);
|
||
|
}
|
||
|
|
||
|
function updateKeyStatus(keystrokeId, success) {
|
||
|
const recentKeysDiv = document.getElementById('recent-keys');
|
||
|
const cards = recentKeysDiv.children;
|
||
|
for (let i = 0; i < cards.length; i++) {
|
||
|
const card = cards[i];
|
||
|
if (parseInt(card.getAttribute('keystroke-id')) === keystrokeId) {
|
||
|
if (success) {
|
||
|
card.classList.add('processed-key-card');
|
||
|
} else {
|
||
|
card.classList.add('unsupported-key-card');
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function onKeyDown(evt) {
|
||
|
if (!connected) {
|
||
|
return;
|
||
|
}
|
||
|
if (!evt.metaKey) {
|
||
|
evt.preventDefault();
|
||
|
addKeyCard(evt.key, keystrokeId);
|
||
|
processingQueue.push(keystrokeId);
|
||
|
keystrokeId++;
|
||
|
}
|
||
|
|
||
|
let location = null;
|
||
|
if (evt.location === 1) {
|
||
|
location = 'left';
|
||
|
} else if (evt.location === 2) {
|
||
|
location = 'right';
|
||
|
}
|
||
|
|
||
|
socket.emit('keystroke', {
|
||
|
metaKey: evt.metaKey,
|
||
|
altKey: evt.altKey,
|
||
|
shiftKey: evt.shiftKey,
|
||
|
ctrlKey: evt.ctrlKey,
|
||
|
key: evt.key,
|
||
|
keyCode: evt.keyCode,
|
||
|
location: location,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function onDisplayHistoryChanged(evt) {
|
||
|
if (evt.target.checked) {
|
||
|
document.getElementById('recent-keys').style.visibility = 'visible';
|
||
|
} else {
|
||
|
document.getElementById('recent-keys').style.visibility = 'hidden';
|
||
|
limitRecentKeys(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
document.querySelector('body').addEventListener("keydown", onKeyDown);
|
||
|
document.getElementById('display-history-checkbox').addEventListener("change", onDisplayHistoryChanged);
|
||
|
socket.on('connect', onSocketConnect);
|
||
|
socket.on('disconnect', onSocketDisconnect);
|
||
|
socket.on('keystroke-received', (data) => {
|
||
|
updateKeyStatus(processingQueue.shift(), data.success);
|
||
|
});
|