feat(remotecontrol): Implement requesting remote control permissions
This commit is contained in:
parent
c07fe8fa1e
commit
59b79cffe5
|
@ -1,5 +1,5 @@
|
|||
# Electron's version.
|
||||
export npm_config_target=1.4.7
|
||||
export npm_config_target=1.4.13
|
||||
# The architecture of Electron, can be ia32 or x64.
|
||||
export npm_config_arch=x64
|
||||
export npm_config_target_arch=x64
|
||||
|
|
1
main.js
1
main.js
|
@ -1,3 +1,4 @@
|
|||
/* global __dirname, process */
|
||||
//Electron includes
|
||||
const electron = require("electron");
|
||||
const APP = electron.app;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
module.exports = {
|
||||
/**
|
||||
* Types of remote-control-event events.
|
||||
*/
|
||||
EVENT_TYPES: {
|
||||
mousemove: "mousemove",
|
||||
mousedown: "mousedown",
|
||||
mouseup: "mouseup",
|
||||
mousedblclick: "mousedblclick",
|
||||
mousescroll: "mousescroll",
|
||||
keydown: "keydown",
|
||||
keyup: "keyup",
|
||||
permissions: "permissions",
|
||||
stop: "stop",
|
||||
supported: "supported"
|
||||
},
|
||||
|
||||
/**
|
||||
* Actions for the remote control permission events.
|
||||
*/
|
||||
PERMISSIONS_ACTIONS: {
|
||||
request: "request",
|
||||
grant: "grant",
|
||||
deny: "deny"
|
||||
},
|
||||
|
||||
/**
|
||||
* The type of remote control events sent trough the API module.
|
||||
*/
|
||||
REMOTE_CONTROL_EVENT_TYPE: "remote-control-event"
|
||||
};
|
|
@ -1,4 +1,6 @@
|
|||
let robot = require("robotjs");
|
||||
const constants = require("../../modules/remotecontrol/constants");
|
||||
const {EVENT_TYPES, PERMISSIONS_ACTIONS, REMOTE_CONTROL_EVENT_TYPE} = constants;
|
||||
|
||||
/**
|
||||
* Attaching to the window for debug purposes.
|
||||
|
@ -59,6 +61,45 @@ class RemoteControl {
|
|||
this.started = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the remote control functionality.
|
||||
*/
|
||||
init(channel, windowManager) {
|
||||
this.windowManager = windowManager;
|
||||
this.channel = channel;
|
||||
this.start();
|
||||
this.channel.ready(() => {
|
||||
this.channel.listen(REMOTE_CONTROL_EVENT_TYPE,
|
||||
event => this.onRemoteControlEvent(event));
|
||||
this.sendEvent({type: EVENT_TYPES.supported});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles permission requests from Jitsi Meet.
|
||||
* @param {object} userInfo - information about the user that has requested
|
||||
* permissions:
|
||||
* @param {string} userInfo.displayName - display name
|
||||
* @param {string} userInfo.userJID - the JID of the user.
|
||||
* @param {string} userInfo.userId - the user id (the resource of the JID)
|
||||
*/
|
||||
handlePermissionRequest(userInfo) {
|
||||
this.windowManager.requestRemoteControlPermissions(userInfo)
|
||||
.then(result => {
|
||||
this.sendEvent({
|
||||
type: EVENT_TYPES.permissions,
|
||||
action: result ? PERMISSIONS_ACTIONS.grant
|
||||
: PERMISSIONS_ACTIONS.deny,
|
||||
userId: userInfo.userId
|
||||
});
|
||||
if(result) {
|
||||
this.start();
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts processing the events.
|
||||
*/
|
||||
|
@ -77,12 +118,13 @@ class RemoteControl {
|
|||
* Executes the passed event.
|
||||
* @param {Object} event the remote-control-event.
|
||||
*/
|
||||
executeRemoteControlEvent(event) {
|
||||
if(!this.started) {
|
||||
onRemoteControlEvent(event) {
|
||||
|
||||
if(!this.started && event.type !== EVENT_TYPES.permissions) {
|
||||
return;
|
||||
}
|
||||
switch(event.type) {
|
||||
case "mousemove":
|
||||
case EVENT_TYPES.mousemove: {
|
||||
const x = event.x * width, y = event.y * height;
|
||||
if(mouseButtonStatus === "down") {
|
||||
robot.dragMouse(x, y);
|
||||
|
@ -90,20 +132,23 @@ class RemoteControl {
|
|||
robot.moveMouse(x, y);
|
||||
}
|
||||
break;
|
||||
case "mousedown":
|
||||
case "mouseup":
|
||||
}
|
||||
case EVENT_TYPES.mousedown:
|
||||
case EVENT_TYPES.mouseup: {
|
||||
mouseButtonStatus = MOUSE_ACTIONS_FROM_EVENT_TYPE[event.type];
|
||||
robot.mouseToggle(
|
||||
mouseButtonStatus,
|
||||
(event.button ? MOUSE_BUTTONS[event.button] : undefined));
|
||||
break;
|
||||
case "mousedblclick":
|
||||
}
|
||||
case EVENT_TYPES.mousedblclick: {
|
||||
robot.mouseClick(
|
||||
(event.button ? MOUSE_BUTTONS[event.button] : undefined),
|
||||
true);
|
||||
break;
|
||||
case "mousescroll":
|
||||
//FIXME: implement horizontal scrolling
|
||||
}
|
||||
case EVENT_TYPES.mousescroll:{
|
||||
//FIXME: implement horizontal scrolling
|
||||
if(event.y !== 0) {
|
||||
robot.scrollMouse(
|
||||
Math.abs(event.y),
|
||||
|
@ -111,15 +156,40 @@ class RemoteControl {
|
|||
);
|
||||
}
|
||||
break;
|
||||
case "keydown":
|
||||
case "keyup":
|
||||
}
|
||||
case EVENT_TYPES.keydown:
|
||||
case EVENT_TYPES.keyup: {
|
||||
robot.keyToggle(event.key,
|
||||
KEY_ACTIONS_FROM_EVENT_TYPE[event.type], event.modifiers);
|
||||
break;
|
||||
}
|
||||
case EVENT_TYPES.permissions: {
|
||||
if(event.action !== PERMISSIONS_ACTIONS.request)
|
||||
break;
|
||||
|
||||
//Open Dialog and answer
|
||||
this.handlePermissionRequest({
|
||||
userId: event.userId,
|
||||
userJID: event.userJID,
|
||||
displayName: event.displayName});
|
||||
break;
|
||||
}
|
||||
case EVENT_TYPES.stop: {
|
||||
this.stop();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.error("Unknown event type!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends remote control event to the controlled participant.
|
||||
* @param {Object} event the remote control event.
|
||||
*/
|
||||
sendEvent(event) {
|
||||
this.channel.send({method: REMOTE_CONTROL_EVENT_TYPE, params: event});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new RemoteControl();
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"postis": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "1.4.7",
|
||||
"electron": "1.4.13",
|
||||
"eslint": ">=3",
|
||||
"eslint-plugin-jsdoc": "*",
|
||||
"precommit-hook": "3.0.0"
|
||||
|
|
|
@ -2,6 +2,7 @@ const remoteControl = require("../../modules/remotecontrol");
|
|||
let postis = require("postis");
|
||||
const setupScreenSharingForWindow = require("../../modules/screensharing");
|
||||
const config = require("../../config.js");
|
||||
const {dialog} = require('electron').remote;
|
||||
|
||||
/**
|
||||
* The postis channel.
|
||||
|
@ -18,16 +19,51 @@ iframe.onload = onload;
|
|||
document.body.appendChild(iframe);
|
||||
|
||||
/**
|
||||
* Initializes the remote control functionality.
|
||||
* Factory for dialogs.
|
||||
*/
|
||||
function initRemoteControl() {
|
||||
remoteControl.start();
|
||||
channel.ready(() =>
|
||||
channel.listen('remote-control-event',
|
||||
event => remoteControl.executeRemoteControlEvent(event))
|
||||
);
|
||||
class DialogFactory {
|
||||
/**
|
||||
* Creates new instance
|
||||
* @constructor
|
||||
*/
|
||||
constructor() { }
|
||||
|
||||
/**
|
||||
* Shows message box dialog for request for remote control permissions
|
||||
* @param {object} userInfo - information about the user that has sent the
|
||||
* request:
|
||||
* @param {string} userInfo.displayName - display name
|
||||
* @param {string} userInfo.userJID - the JID of the user.
|
||||
*/
|
||||
requestRemoteControlPermissions(userInfo) {
|
||||
return new Promise( resolve =>
|
||||
dialog.showMessageBox({
|
||||
type: "question",
|
||||
buttons: ["Yes", "No"],
|
||||
defaultId: 0,
|
||||
title: "Request for permission for remote control",
|
||||
message: "Would you like to allow " + userInfo.displayName
|
||||
+ " to remotely control your desktop.",
|
||||
detail: "userId: " + userInfo.userJID,
|
||||
cancelId: 1
|
||||
}, response => resolve(response === 0? true : false))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog factory instance.
|
||||
*/
|
||||
const dialogFactory = new DialogFactory();
|
||||
|
||||
/**
|
||||
* Boolean variable that indicates whether the onloaded function was already
|
||||
* called.
|
||||
* NOTE: Used to not call the onload method more than once during reloads of
|
||||
* the iframe or location changes.
|
||||
*/
|
||||
let loaded = false;
|
||||
|
||||
/**
|
||||
* Handles loaded event for iframe:
|
||||
* Enables screen sharing functionality to the iframe webpage.
|
||||
|
@ -35,10 +71,14 @@ function initRemoteControl() {
|
|||
* Initializes remote control.
|
||||
*/
|
||||
function onload() {
|
||||
if(loaded) {
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
setupScreenSharingForWindow(iframe.contentWindow);
|
||||
channel = postis({
|
||||
window: iframe.contentWindow,
|
||||
windowForEventListening: window
|
||||
});
|
||||
initRemoteControl();
|
||||
remoteControl.init(channel, dialogFactory);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue