Refactoring: move events handlers to specifics functions, add an output interface to write texts on the server side

This commit is contained in:
Simon Vieille 2018-02-08 11:22:26 +01:00
parent 3d1a4e7600
commit 9f170ee2c1
No known key found for this signature in database
GPG Key ID: 919533E2B946EA10
4 changed files with 245 additions and 173 deletions

View File

@ -1,14 +1,175 @@
$(function() {
var ws = new WebSocket('ws://' + window.location.hostname + ':14598');
var $pointer = $('#pointer');
var $scroller = $('#scrollbar');
var mouseInitPosX = null;
var mouseInitPosY = null;
var mousePosX = null;
var mousePosY = null;
var scrollLastTimestamp = null;
var scrollLastValue = null;
var ws;
var $pointer, $scroller;
var scrollLastTimestamp, scrollLastValue;
var mousePosX, mousePosY, mouseInitPosX, mouseInitPosY;
var createWebSocketConnection = function() {
ws = new WebSocket('ws://' + window.location.hostname + ':14598');
ws.onopen = function(event) {
$('#disconneced').fadeOut();
}
ws.onclose = function(event) {
$('#disconneced').fadeIn();
window.setTimeout(createWebSocketConnection, 5000);
}
ws.onmessage = function(event) {}
}
var navigationClickHandler = function(e) {
$('.pane').hide();
var target = $(this).attr('href');
$(target).show();
$('#nav a').removeClass('active');
$(this).addClass('active');
}
var buttonClickHandler = function(e) {
var msg = $(this).attr('data-msg');
ws.send(msg);
}
var shortcutClearClickHandler = function(e) {
$('#shortcut-key').val('');
$('#shortcuts_special_keys input:checked').each(function() {
$(this).prop('checked', false).trigger('change');
});
}
var shortcutSendClickHandler = function(e) {
var keys = [];
$('#shortcuts_special_keys input:checked').each(function() {
keys.push($(this).val());
});
var key = $('#shortcut-key').val();
if (keys.length) {
if (key) {
keys.push(key);
}
var msg = '{"type":"keys","value": "' + (keys.join(',').replace('"', '\\"')) + '"}';
ws.send(msg);
}
}
var textClearClickHandler = function(e) {
$('#text').val('');
}
var textSendClickHandler = function(e) {
var keys = $('#text').val();
if (keys.length) {
var msg = '{"type":"text","value": "' + (keys.replace('"', '\\"')) + '"}';
ws.send(msg);
}
}
var textKeyUpHandler = function(e) {
var keys = $('#text').val();
if (e.keyCode === 13) {
var msg = '{"type":"text","value": "' + (keys.replace('"', '\\"')) + '"}';
ws.send(msg);
}
}
var liveTextKeyUpHandler = function(e) {
var value = $(this).val();
var live = false;
if (e.keyCode === 8) {
var msg = '{"type":"key","value": "backspace"}';
ws.send(msg);
} else if (e.keyCode === 13) {
var msg = '{"type":"key","value": "enter"}';
ws.send(msg);
} else if (value.length) {
if (value === ' ') {
var msg = '{"type":"key","value": "space"}';
ws.send(msg);
} else {
var msg = '{"type":"text","value": "' + (value.replace('"', '\\"')) + '"}';
ws.send(msg);
}
$(this).val('');
}
}
var shortcutsSpecialKeysOnChangeHandler = function(e) {
$('#shortcuts_special_keys input:checked').each(function() {
$(this).parent().addClass('btn-primary').removeClass('btn-secondary');
})
$('#shortcuts_special_keys input:not(:checked)').each(function() {
$(this).parent().addClass('btn-secondary').removeClass('btn-primary');
})
}
var pointerClickHandler = function(e) {
var msg = '{"type":"pointer","click":"left"}';
ws.send(msg);
}
var scrollerTouchStartHandler = function(e) {
var touch = e.targetTouches[0];
mouseInitPosY = touch.pageY;
}
var scrollerTouchMoveHandler = function(e) {
var touch = e.changedTouches[0];
var value = ((touch.pageY - mouseInitPosY > 0) ? 'down' : 'up');
var now = new Date().getTime();
if (value === scrollLastValue && scrollLastTimestamp !== null && now - scrollLastTimestamp < 200) {
return;
}
scrollLastTimestamp = now;
scrollLastValue = value;
var msg = '{"type":"scroll","value": "' + value + '"}';
mouseInitPosY = touch.pageY;
ws.send(msg);
}
var pointerTouchStartHandler = function(e) {
var touch = e.targetTouches[0];
mouseInitPosX = touch.pageX;
mouseInitPosY = touch.pageY;
}
var pointerTouchMoveHandler = function(e) {
if (e.changedTouches.length === 2) {
return scrollerTouchMoveHandler(e);
}
var touch = e.changedTouches[0];
mousePosX = touch.pageX;
mousePosY = touch.pageY;
var newX = mousePosX - mouseInitPosX;
var newY = mousePosY - mouseInitPosY;
mouseInitPosX = mousePosX;
mouseInitPosY = mousePosY;
var msg = '{"type":"pointer","x": "' + newX + '","y": "' + newY + '"}';
ws.send(msg);
}
var documentHashHandler = function() {
var hash = window.location.hash;
if (hash) {
@ -18,164 +179,41 @@ $(function() {
$('#pane-keyboard').show();
$('#nav a').first().addClass('active');
}
}
$('#nav a').click(function(e) {
$('.pane').hide();
var addListeners = function() {
$('#nav a').click(navigationClickHandler);
$('button[data-msg]').click(buttonClickHandler);
var target = $(this).attr('href');
$(target).show();
$('#shortcut-clear').click(shortcutClearClickHandler);
$('#shortcuts_special_keys input').change(shortcutsSpecialKeysOnChangeHandler);
$('#shortcut-send').click(shortcutSendClickHandler);
$('#nav a').removeClass('active');
$(this).addClass('active');
});
$('#text-clear').click(textClearClickHandler);
$('#text-send').click(textSendClickHandler);
$('#text').on('keyup', textKeyUpHandler);
$('#live-text').on('keyup', liveTextKeyUpHandler);
ws.onopen = function(event) {
$('#disconneced').hide();
}
$scroller
.on('touchstart', scrollerTouchStartHandler)
.on('touchmove', scrollerTouchMoveHandler);
ws.onclose = function(event) {
$('#disconneced').show();
}
$pointer
.on('click', pointerClickHandler)
.on('touchstart', pointerTouchStartHandler)
.on('touchmove', pointerTouchMoveHandler);
}
ws.onmessage = function(event) {}
var bootstrap = function() {
documentHashHandler();
shortcutsSpecialKeysOnChangeHandler();
createWebSocketConnection();
addListeners();
}
$('button[data-msg]').click(function() {
var msg = $(this).attr('data-msg');
ws.send(msg);
});
$(function() {
$pointer = $('#pointer');
$scroller = $('#scrollbar');
$('#shortcut-clear').click(function() {
$('#shortcut-key').val('');
$('#shortcuts_special_keys input:checked').each(function() {
$(this).prop('checked', false).trigger('change');
});
});
var shortcutsSpecialKeysOnChange = function() {
$('#shortcuts_special_keys input:checked').each(function() {
$(this).parent().addClass('btn-primary').removeClass('btn-secondary');
})
$('#shortcuts_special_keys input:not(:checked)').each(function() {
$(this).parent().addClass('btn-secondary').removeClass('btn-primary');
})
}
$('#shortcuts_special_keys input').change(shortcutsSpecialKeysOnChange);
shortcutsSpecialKeysOnChange();
$('#shortcut-send').click(function() {
var keys = [];
$('#shortcuts_special_keys input:checked').each(function() {
keys.push($(this).val());
});
var key = $('#shortcut-key').val();
if (keys.length) {
if (key) {
keys.push(key);
}
var msg = '{"type":"keys","value": "' + (keys.join(',').replace('"', '\\"')) + '"}';
ws.send(msg);
}
});
$('#text-clear').click(function() {
$('#text').val('');
});
$pointer.on('click', function(e) {
var msg = '{"type":"pointer","click":"left"}';
ws.send(msg);
});
$('#text-send').click(function() {
var keys = $('#text').val();
if (keys.length) {
var msg = '{"type":"text","value": "' + (keys.replace('"', '\\"')) + '"}';
ws.send(msg);
}
});
$('#text').on('keyup', function(e) {
var keys = $('#text').val();
if (e.keyCode === 13) {
var msg = '{"type":"text","value": "' + (keys.replace('"', '\\"')) + '"}';
ws.send(msg);
}
});
$('#live-text').on('keyup', function(e) {
var value = $(this).val();
var live = false;
if (e.keyCode === 8) {
var msg = '{"type":"key","value": "backspace"}';
ws.send(msg);
} else if (e.keyCode === 13) {
var msg = '{"type":"key","value": "enter"}';
ws.send(msg);
} else if (value.length) {
if (value === ' ') {
var msg = '{"type":"key","value": "space"}';
ws.send(msg);
} else {
var msg = '{"type":"text","value": "' + (value.replace('"', '\\"')) + '"}';
ws.send(msg);
}
$(this).val('');
}
});
$scroller.on('touchstart', function(e) {
var touch = e.targetTouches[0];
mouseInitPosY = touch.pageY;
});
$scroller.on('touchmove', function(e) {
var touch = e.changedTouches[0];
var value = ((touch.pageY - mouseInitPosY > 0) ? 'down' : 'up');
var now = new Date().getTime();
if (value === scrollLastValue && scrollLastTimestamp !== null && now - scrollLastTimestamp < 200) {
return;
}
scrollLastTimestamp = now;
scrollLastValue = value;
var msg = '{"type":"scroll","value": "' + value + '"}';
mouseInitPosY = touch.pageY;
ws.send(msg);
});
$pointer.on('touchstart', function(e) {
var touch = e.targetTouches[0];
mouseInitPosX = touch.pageX;
mouseInitPosY = touch.pageY;
});
$pointer.on('touchmove', function(e) {
var touch = e.changedTouches[0];
mousePosX = touch.pageX;
mousePosY = touch.pageY;
var newX = mousePosX - mouseInitPosX;
var newY = mousePosY - mouseInitPosY;
mouseInitPosX = mousePosX;
mouseInitPosY = mousePosY;
var msg = '{"type":"pointer","x": "' + newX + '","y": "' + newY + '"}';
ws.send(msg);
});
bootstrap();
});

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="assets/css/main.css" type="text/css">
<title>Remote i3-wm</title>

View File

@ -8,10 +8,17 @@ use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\ConnectionInterface;
$server = new Server();
$options = getopt(
'v',
['verbose', 'vv']
);
$serverOutput = new Output(isset($options['v']) || isset($options['verbose']));
$messageOutput = new Output(isset($options['vv']));
$server = new Server($serverOutput);
$shell = new Shell();
$server->addMessageHandler('pointer', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('pointer', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$x = $data['x'] ?? null;
$y = $data['y'] ?? null;
$click = $data['click'] ?? null;
@ -23,36 +30,43 @@ $server->addMessageHandler('pointer', function (ConnectionInterface $from, array
$mouseY = (int) ($matches[2] + $y * 2.5);
$shell->exec('xdotool mousemove %s %s', $mouseX, $mouseY);
$messageOutput->writeln('Pointer moved');
} elseif ($click !== null) {
if ($click === 'left') {
$shell->exec('xdotool click 1');
$messageOutput->writeln('Left click');
} elseif ($click === 'middle') {
$shell->exec('xdotool click 2');
$messageOutput->writeln('Middle click');
} elseif ($click === 'right') {
$shell->exec('xdotool click 3');
$messageOutput->writeln('Right click');
}
}
});
$server->addMessageHandler('scroll', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('scroll', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
if ($value === 'down') {
$shell->exec('xdotool click 5 && xdotool click 5');
$messageOutput->writeln('Scrolling down');
} elseif ($value === 'up') {
$shell->exec('xdotool click 4 && xdotool click 4');
$messageOutput->writeln('Scrolling up');
}
});
$server->addMessageHandler('workspace', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('workspace', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
if (!empty($value)) {
$shell->exec("i3-msg 'workspace \"%s\"'", $value);
$messageOutput->writeln('Workspace changed');
}
});
$server->addMessageHandler('volume', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('volume', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
if ($value === null) {
@ -66,9 +80,11 @@ $server->addMessageHandler('volume', function (ConnectionInterface $from, array
} else {
$shell->exec('amixer set Master %d%%', (int) $value);
}
$messageOutput->writeln('Volume modified');
});
$server->addMessageHandler('media', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('media', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
if ($value === 'playpause') {
@ -81,10 +97,11 @@ $server->addMessageHandler('media', function (ConnectionInterface $from, array $
if (!empty($cmd)) {
$shell->exec('playerctl -p spotify %s', $cmd);
$messageOutput->writeln('Spotify managed');
}
});
$server->addMessageHandler('keys', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('keys', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
if (!empty($value)) {
@ -103,10 +120,11 @@ $server->addMessageHandler('keys', function (ConnectionInterface $from, array $d
$value = implode('+', $keys);
$shell->exec('xdotool key %s', escapeshellarg($value));
$messageOutput->writeln('Key pressed');
}
});
$server->addMessageHandler('key', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('key', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
$map = [
'up' => 'Up',
@ -122,14 +140,16 @@ $server->addMessageHandler('key', function (ConnectionInterface $from, array $da
if (!empty($value) && isset($map[$value])) {
$shell->exec('xdotool key %s', $map[$value]);
$messageOutput->writeln('Key pressed');
}
});
$server->addMessageHandler('text', function (ConnectionInterface $from, array $data) use ($shell) {
$server->addMessageHandler('text', function (ConnectionInterface $from, array $data) use ($shell, $messageOutput) {
$value = $data['value'] ?? null;
if (trim($value) !== '') {
$shell->exec('xdotool type %s', escapeshellarg($value));
$messageOutput->writeln('Text wrote');
}
});

View File

@ -20,12 +20,18 @@ class Server implements MessageComponentInterface
*/
protected $messageHandlers = [];
/**
* @var Output
*/
protected $output;
/**
* Constructor.
*/
public function __construct()
public function __construct(Output $output)
{
$this->clients = new \SplObjectStorage();
$this->output = $output;
}
/**
@ -53,6 +59,7 @@ class Server implements MessageComponentInterface
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
$this->output->writeln('New client');
}
/**
@ -63,15 +70,22 @@ class Server implements MessageComponentInterface
$data = json_decode($msg, true);
if ($data === null) {
$this->output->writeln('Invalid message received (bad json)');
return;
}
$type = $data['type'] ?? null;
if ($type === null) {
$this->output->writeln('Invalid message received (type not defined)');
return;
}
$this->output->write('Message received: ');
$this->output->writeln($msg);
$handlers = $this->messageHandlers[$type] ?? [];
foreach ($handlers as $handler) {