mirror of https://github.com/jitsi/jitsi-meet
parent
db5010be9d
commit
896650d005
@ -0,0 +1,160 @@ |
||||
/** |
||||
* Enumerates the supported keys. |
||||
*/ |
||||
export const KEYS = { |
||||
BACKSPACE: "backspace" , |
||||
DELETE : "delete", |
||||
RETURN : "enter", |
||||
TAB : "tab", |
||||
ESCAPE : "escape", |
||||
UP : "up", |
||||
DOWN : "down", |
||||
RIGHT : "right", |
||||
LEFT : "left", |
||||
HOME : "home", |
||||
END : "end", |
||||
PAGEUP : "pageup", |
||||
PAGEDOWN : "pagedown", |
||||
|
||||
F1 : "f1", |
||||
F2 : "f2", |
||||
F3 : "f3", |
||||
F4 : "f4", |
||||
F5 : "f5", |
||||
F6 : "f6", |
||||
F7 : "f7", |
||||
F8 : "f8", |
||||
F9 : "f9", |
||||
F10 : "f10", |
||||
F11 : "f11", |
||||
F12 : "f12", |
||||
META : "command", |
||||
CMD_L: "command", |
||||
CMD_R: "command", |
||||
ALT : "alt", |
||||
CONTROL : "control", |
||||
SHIFT : "shift", |
||||
CAPS_LOCK: "caps_lock", //not supported by robotjs
|
||||
SPACE : "space", |
||||
PRINTSCREEN : "printscreen", |
||||
INSERT : "insert", |
||||
|
||||
NUMPAD_0 : "numpad_0", |
||||
NUMPAD_1 : "numpad_1", |
||||
NUMPAD_2 : "numpad_2", |
||||
NUMPAD_3 : "numpad_3", |
||||
NUMPAD_4 : "numpad_4", |
||||
NUMPAD_5 : "numpad_5", |
||||
NUMPAD_6 : "numpad_6", |
||||
NUMPAD_7 : "numpad_7", |
||||
NUMPAD_8 : "numpad_8", |
||||
NUMPAD_9 : "numpad_9", |
||||
|
||||
COMMA: ",", |
||||
|
||||
PERIOD: ".", |
||||
SEMICOLON: ";", |
||||
QUOTE: "'", |
||||
BRACKET_LEFT: "[", |
||||
BRACKET_RIGHT: "]", |
||||
BACKQUOTE: "`", |
||||
BACKSLASH: "\\", |
||||
MINUS: "-", |
||||
EQUAL: "=", |
||||
SLASH: "/" |
||||
}; |
||||
|
||||
/** |
||||
* Mapping between the key codes and keys deined in KEYS. |
||||
* The mappings are based on |
||||
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Specifications
|
||||
*/ |
||||
let keyCodeToKey = { |
||||
8: KEYS.BACKSPACE, |
||||
9: KEYS.TAB, |
||||
13: KEYS.RETURN, |
||||
16: KEYS.SHIFT, |
||||
17: KEYS.CONTROL, |
||||
18: KEYS.ALT, |
||||
20: KEYS.CAPS_LOCK, |
||||
27: KEYS.ESCAPE, |
||||
32: KEYS.SPACE, |
||||
33: KEYS.PAGEUP, |
||||
34: KEYS.PAGEDOWN, |
||||
35: KEYS.END, |
||||
36: KEYS.HOME, |
||||
37: KEYS.LEFT, |
||||
38: KEYS.UP, |
||||
39: KEYS.RIGHT, |
||||
40: KEYS.DOWN, |
||||
42: KEYS.PRINTSCREEN, |
||||
44: KEYS.PRINTSCREEN, |
||||
45: KEYS.INSERT, |
||||
46: KEYS.DELETE, |
||||
59: KEYS.SEMICOLON, |
||||
61: KEYS.EQUAL, |
||||
91: KEYS.CMD_L, |
||||
92: KEYS.CMD_R, |
||||
93: KEYS.CMD_R, |
||||
96: KEYS.NUMPAD_0, |
||||
97: KEYS.NUMPAD_1, |
||||
98: KEYS.NUMPAD_2, |
||||
99: KEYS.NUMPAD_3, |
||||
100: KEYS.NUMPAD_4, |
||||
101: KEYS.NUMPAD_5, |
||||
102: KEYS.NUMPAD_6, |
||||
103: KEYS.NUMPAD_7, |
||||
104: KEYS.NUMPAD_8, |
||||
105: KEYS.NUMPAD_9, |
||||
112: KEYS.F1, |
||||
113: KEYS.F2, |
||||
114: KEYS.F3, |
||||
115: KEYS.F4, |
||||
116: KEYS.F5, |
||||
117: KEYS.F6, |
||||
118: KEYS.F7, |
||||
119: KEYS.F8, |
||||
120: KEYS.F9, |
||||
121: KEYS.F10, |
||||
122: KEYS.F11, |
||||
123: KEYS.F12, |
||||
124: KEYS.PRINTSCREEN, |
||||
173: KEYS.MINUS, |
||||
186: KEYS.SEMICOLON, |
||||
187: KEYS.EQUAL, |
||||
188: KEYS.COMMA, |
||||
189: KEYS.MINUS, |
||||
190: KEYS.PERIOD, |
||||
191: KEYS.SLASH, |
||||
192: KEYS.BACKQUOTE, |
||||
219: KEYS.BRACKET_LEFT, |
||||
220: KEYS.BACKSLASH, |
||||
221: KEYS.BRACKET_RIGHT, |
||||
222: KEYS.QUOTE, |
||||
224: KEYS.META, |
||||
229: KEYS.SEMICOLON |
||||
}; |
||||
|
||||
/** |
||||
* Generate codes for digit keys (0-9) |
||||
*/ |
||||
for(let i = 0; i < 10; i++) { |
||||
keyCodeToKey[i + 48] = `${i}`; |
||||
} |
||||
|
||||
/** |
||||
* Generate codes for letter keys (a-z) |
||||
*/ |
||||
for(let i = 0; i < 26; i++) { |
||||
let keyCode = i + 65; |
||||
keyCodeToKey[keyCode] = String.fromCharCode(keyCode).toLowerCase(); |
||||
} |
||||
|
||||
/** |
||||
* Returns key associated with the keyCode from the passed event. |
||||
* @param {KeyboardEvent} event the event |
||||
* @returns {KEYS} the key on the keyboard. |
||||
*/ |
||||
export function keyboardEventToKey(event) { |
||||
return keyCodeToKey[event.which]; |
||||
} |
@ -0,0 +1,136 @@ |
||||
/* global $, APP */ |
||||
import * as KeyCodes from "../keycode/keycode"; |
||||
|
||||
/** |
||||
* Extract the keyboard key from the keyboard event. |
||||
* @param event {KeyboardEvent} the event. |
||||
* @returns {KEYS} the key that is pressed or undefined. |
||||
*/ |
||||
function getKey(event) { |
||||
return KeyCodes.keyboardEventToKey(event); |
||||
} |
||||
|
||||
/** |
||||
* Extract the modifiers from the keyboard event. |
||||
* @param event {KeyboardEvent} the event. |
||||
* @returns {Array} with possible values: "shift", "control", "alt", "command". |
||||
*/ |
||||
function getModifiers(event) { |
||||
let modifiers = []; |
||||
if(event.shiftKey) { |
||||
modifiers.push("shift"); |
||||
} |
||||
|
||||
if(event.ctrlKey) { |
||||
modifiers.push("control"); |
||||
} |
||||
|
||||
|
||||
if(event.altKey) { |
||||
modifiers.push("alt"); |
||||
} |
||||
|
||||
if(event.metaKey) { |
||||
modifiers.push("command"); |
||||
} |
||||
|
||||
return modifiers; |
||||
} |
||||
|
||||
/** |
||||
* This class represents the controller party for a remote controller session. |
||||
* It listens for mouse and keyboard events and sends them to the receiver |
||||
* party of the remote control session. |
||||
*/ |
||||
class Controller { |
||||
/** |
||||
* Creates new instance. |
||||
*/ |
||||
constructor() {} |
||||
|
||||
/** |
||||
* Starts processing the mouse and keyboard events. |
||||
* @param {JQuery.selector} area the selector which will be used for |
||||
* attaching the listeners on. |
||||
*/ |
||||
start(area) { |
||||
this.area = area; |
||||
this.area.mousemove(event => { |
||||
const position = this.area.position(); |
||||
this._sendEvent({ |
||||
type: "mousemove", |
||||
x: (event.pageX - position.left)/this.area.width(), |
||||
y: (event.pageY - position.top)/this.area.height() |
||||
}); |
||||
}); |
||||
this.area.mousedown(this._onMouseClickHandler.bind(this, "mousedown")); |
||||
this.area.mouseup(this._onMouseClickHandler.bind(this, "mouseup")); |
||||
this.area.dblclick( |
||||
this._onMouseClickHandler.bind(this, "mousedblclick")); |
||||
this.area.contextmenu(() => false); |
||||
this.area[0].onmousewheel = event => { |
||||
this._sendEvent({ |
||||
type: "mousescroll", |
||||
x: event.deltaX, |
||||
y: event.deltaY |
||||
}); |
||||
}; |
||||
$(window).keydown(this._onKeyPessHandler.bind(this, "keydown")); |
||||
$(window).keyup(this._onKeyPessHandler.bind(this, "keyup")); |
||||
} |
||||
|
||||
/** |
||||
* Stops processing the mouse and keyboard events. |
||||
*/ |
||||
stop() { |
||||
this.area.off( "mousemove" ); |
||||
this.area.off( "mousedown" ); |
||||
this.area.off( "mouseup" ); |
||||
this.area.off( "contextmenu" ); |
||||
this.area.off( "dblclick" ); |
||||
$(window).off( "keydown"); |
||||
$(window).off( "keyup"); |
||||
this.area[0].onmousewheel = undefined; |
||||
} |
||||
|
||||
/** |
||||
* Handler for mouse click events. |
||||
* @param {String} type the type of event ("mousedown"/"mouseup") |
||||
* @param {Event} event the mouse event. |
||||
*/ |
||||
_onMouseClickHandler(type, event) { |
||||
this._sendEvent({ |
||||
type: type, |
||||
button: event.which |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Handler for key press events. |
||||
* @param {String} type the type of event ("keydown"/"keyup") |
||||
* @param {Event} event the key event. |
||||
*/ |
||||
_onKeyPessHandler(type, event) { |
||||
this._sendEvent({ |
||||
type: type, |
||||
key: getKey(event), |
||||
modifiers: getModifiers(event), |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* Sends remote control event to the controlled participant. |
||||
* @param {Object} event the remote control event. |
||||
*/ |
||||
_sendRemoteControlEvent(event) { |
||||
try{ |
||||
APP.conference.sendEndpointMessage("", |
||||
{type: "remote-control-event", event}); |
||||
} catch (e) { |
||||
// failed to send the event.
|
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
export default new Controller(); |
@ -0,0 +1,47 @@ |
||||
/* global APP, JitsiMeetJS */ |
||||
const ConferenceEvents = JitsiMeetJS.events.conference; |
||||
|
||||
/** |
||||
* This class represents the receiver party for a remote controller session. |
||||
* It handles "remote-control-event" events and sends them to the |
||||
* API module. From there the events can be received from wrapper application |
||||
* and executed. |
||||
*/ |
||||
class Receiver { |
||||
/** |
||||
* Creates new instance. |
||||
* @constructor |
||||
*/ |
||||
constructor() {} |
||||
|
||||
/** |
||||
* Attaches listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED events. |
||||
*/ |
||||
start() { |
||||
APP.conference.addConferenceListener( |
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, |
||||
this._onRemoteControlEvent); |
||||
} |
||||
|
||||
/** |
||||
* Removes the listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED |
||||
* events. |
||||
*/ |
||||
stop() { |
||||
APP.conference.removeConferenceListener( |
||||
ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, |
||||
this._onRemoteControlEvent); |
||||
} |
||||
|
||||
/** |
||||
* Sends "remote-control-event" events to to the API module. |
||||
* @param {JitsiParticipant} participant the controller participant |
||||
* @param {Object} event the remote control event. |
||||
*/ |
||||
_onRemoteControlEvent(participant, event) { |
||||
if(event.type === "remote-control-event") |
||||
APP.API.sendRemoteControlEvent(event.event); |
||||
} |
||||
} |
||||
|
||||
export default new Receiver(); |
Loading…
Reference in new issue