Przeglądaj źródła

feat(remotecontrol): announce remotecontrol support

master
hristoterezov 9 lat temu
rodzic
commit
0f33e59e4d

+ 3
- 3
app.js Wyświetl plik

22
 import API from './modules/API/API';
22
 import API from './modules/API/API';
23
 
23
 
24
 import translation from "./modules/translation/translation";
24
 import translation from "./modules/translation/translation";
25
-// For remote control testing:
26
-// import remoteControlController from "./modules/remotecontrol/Controller";
25
+import remoteControl from "./modules/remotecontrol/remotecontrol";
27
 
26
 
28
 const APP = {
27
 const APP = {
29
     // Used by do_external_connect.js if we receive the attach data after
28
     // Used by do_external_connect.js if we receive the attach data after
61
      */
60
      */
62
     ConferenceUrl : null,
61
     ConferenceUrl : null,
63
     connection: null,
62
     connection: null,
64
-    API
63
+    API,
64
+    remoteControl
65
 };
65
 };
66
 
66
 
67
 // TODO The execution of the mobile app starts from react/index.native.js.
67
 // TODO The execution of the mobile app starts from react/index.native.js.

+ 1
- 0
conference.js Wyświetl plik

488
             }).then(([tracks, con]) => {
488
             }).then(([tracks, con]) => {
489
                 logger.log('initialized with %s local tracks', tracks.length);
489
                 logger.log('initialized with %s local tracks', tracks.length);
490
                 APP.connection = connection = con;
490
                 APP.connection = connection = con;
491
+                APP.remoteControl.init();
491
                 this._bindConnectionFailedHandler(con);
492
                 this._bindConnectionFailedHandler(con);
492
                 this._createRoom(tracks);
493
                 this._createRoom(tracks);
493
                 this.isDesktopSharingEnabled =
494
                 this.isDesktopSharingEnabled =

+ 31
- 14
modules/API/API.js Wyświetl plik

55
             APP.conference.toggleScreenSharing.bind(APP.conference),
55
             APP.conference.toggleScreenSharing.bind(APP.conference),
56
         "video-hangup": () => APP.conference.hangup(),
56
         "video-hangup": () => APP.conference.hangup(),
57
         "email": APP.conference.changeLocalEmail,
57
         "email": APP.conference.changeLocalEmail,
58
-        "avatar-url": APP.conference.changeLocalAvatarUrl
58
+        "avatar-url": APP.conference.changeLocalAvatarUrl,
59
+        "remote-control-supported": isSupported =>
60
+            APP.remoteControl.onRemoteControlSupported(isSupported)
59
     };
61
     };
60
     Object.keys(commands).forEach(function (key) {
62
     Object.keys(commands).forEach(function (key) {
61
         postis.listen(key, args => commands[key](...args));
63
         postis.listen(key, args => commands[key](...args));
94
     }
96
     }
95
 }
97
 }
96
 
98
 
97
-export default {
99
+class API {
100
+    /**
101
+     * Constructs new instance
102
+     * @constructor
103
+     */
104
+    constructor() { }
105
+
98
     /**
106
     /**
99
      * Initializes the APIConnector. Setups message event listeners that will
107
      * Initializes the APIConnector. Setups message event listeners that will
100
      * receive information from external applications that embed Jitsi Meet.
108
      * receive information from external applications that embed Jitsi Meet.
108
             return;
116
             return;
109
 
117
 
110
         enabled = true;
118
         enabled = true;
119
+    }
120
+
121
+    /**
122
+     * initializes postis library.
123
+     * @private
124
+     */
125
+    _initPostis() {
111
         let postisOptions = {
126
         let postisOptions = {
112
             window: target
127
             window: target
113
         };
128
         };
116
                 = "jitsi_meet_external_api_" + jitsi_meet_external_api_id;
131
                 = "jitsi_meet_external_api_" + jitsi_meet_external_api_id;
117
         postis = postisInit(postisOptions);
132
         postis = postisInit(postisOptions);
118
         initCommands();
133
         initCommands();
119
-    },
134
+    }
120
 
135
 
121
     /**
136
     /**
122
      * Notify external application (if API is enabled) that message was sent.
137
      * Notify external application (if API is enabled) that message was sent.
124
      */
139
      */
125
     notifySendingChatMessage (body) {
140
     notifySendingChatMessage (body) {
126
         triggerEvent("outgoing-message", {"message": body});
141
         triggerEvent("outgoing-message", {"message": body});
127
-    },
142
+    }
128
 
143
 
129
     /**
144
     /**
130
      * Notify external application (if API is enabled) that
145
      * Notify external application (if API is enabled) that
143
             "incoming-message",
158
             "incoming-message",
144
             {"from": id, "nick": nick, "message": body, "stamp": ts}
159
             {"from": id, "nick": nick, "message": body, "stamp": ts}
145
         );
160
         );
146
-    },
161
+    }
147
 
162
 
148
     /**
163
     /**
149
      * Notify external application (if API is enabled) that
164
      * Notify external application (if API is enabled) that
152
      */
167
      */
153
     notifyUserJoined (id) {
168
     notifyUserJoined (id) {
154
         triggerEvent("participant-joined", {id});
169
         triggerEvent("participant-joined", {id});
155
-    },
170
+    }
156
 
171
 
157
     /**
172
     /**
158
      * Notify external application (if API is enabled) that
173
      * Notify external application (if API is enabled) that
161
      */
176
      */
162
     notifyUserLeft (id) {
177
     notifyUserLeft (id) {
163
         triggerEvent("participant-left", {id});
178
         triggerEvent("participant-left", {id});
164
-    },
179
+    }
165
 
180
 
166
     /**
181
     /**
167
      * Notify external application (if API is enabled) that
182
      * Notify external application (if API is enabled) that
171
      */
186
      */
172
     notifyDisplayNameChanged (id, displayName) {
187
     notifyDisplayNameChanged (id, displayName) {
173
         triggerEvent("display-name-change", {id, displayname: displayName});
188
         triggerEvent("display-name-change", {id, displayname: displayName});
174
-    },
189
+    }
175
 
190
 
176
     /**
191
     /**
177
      * Notify external application (if API is enabled) that
192
      * Notify external application (if API is enabled) that
181
      */
196
      */
182
     notifyConferenceJoined (room) {
197
     notifyConferenceJoined (room) {
183
         triggerEvent("video-conference-joined", {roomName: room});
198
         triggerEvent("video-conference-joined", {roomName: room});
184
-    },
199
+    }
185
 
200
 
186
     /**
201
     /**
187
      * Notify external application (if API is enabled) that
202
      * Notify external application (if API is enabled) that
191
      */
206
      */
192
     notifyConferenceLeft (room) {
207
     notifyConferenceLeft (room) {
193
         triggerEvent("video-conference-left", {roomName: room});
208
         triggerEvent("video-conference-left", {roomName: room});
194
-    },
209
+    }
195
 
210
 
196
     /**
211
     /**
197
      * Notify external application (if API is enabled) that
212
      * Notify external application (if API is enabled) that
199
      */
214
      */
200
     notifyReadyToClose () {
215
     notifyReadyToClose () {
201
         triggerEvent("video-ready-to-close", {});
216
         triggerEvent("video-ready-to-close", {});
202
-    },
217
+    }
203
 
218
 
204
     /**
219
     /**
205
      * Sends remote control event.
220
      * Sends remote control event.
207
      */
222
      */
208
     sendRemoteControlEvent(event) {
223
     sendRemoteControlEvent(event) {
209
         sendMessage({method: "remote-control-event", params: event});
224
         sendMessage({method: "remote-control-event", params: event});
210
-    },
225
+    }
211
 
226
 
212
     /**
227
     /**
213
      * Removes the listeners.
228
      * Removes the listeners.
214
      */
229
      */
215
-    dispose: function () {
230
+    dispose () {
216
         if(enabled)
231
         if(enabled)
217
             postis.destroy();
232
             postis.destroy();
218
     }
233
     }
219
-};
234
+}
235
+
236
+export default new API();

+ 33
- 17
modules/remotecontrol/Controller.js Wyświetl plik

1
 /* global $, APP */
1
 /* global $, APP */
2
 import * as KeyCodes from "../keycode/keycode";
2
 import * as KeyCodes from "../keycode/keycode";
3
+import {EVENT_TYPES, API_EVENT_TYPE}
4
+    from "../../service/remotecontrol/Constants";
3
 
5
 
4
 /**
6
 /**
5
  * Extract the keyboard key from the keyboard event.
7
  * Extract the keyboard key from the keyboard event.
42
  * It listens for mouse and keyboard events and sends them to the receiver
44
  * It listens for mouse and keyboard events and sends them to the receiver
43
  * party of the remote control session.
45
  * party of the remote control session.
44
  */
46
  */
45
-class Controller {
47
+export default class Controller {
46
     /**
48
     /**
47
      * Creates new instance.
49
      * Creates new instance.
48
      */
50
      */
49
-    constructor() {}
51
+    constructor() {
52
+        this.enabled = false;
53
+    }
54
+
55
+    /**
56
+     * Enables / Disables the remote control
57
+     * @param {boolean} enabled the new state.
58
+     */
59
+    enable(enabled) {
60
+        this.enabled = enabled;
61
+    }
50
 
62
 
51
     /**
63
     /**
52
      * Starts processing the mouse and keyboard events.
64
      * Starts processing the mouse and keyboard events.
54
      * attaching the listeners on.
66
      * attaching the listeners on.
55
      */
67
      */
56
     start(area) {
68
     start(area) {
69
+        if(!this.enabled)
70
+            return;
57
         this.area = area;
71
         this.area = area;
58
         this.area.mousemove(event => {
72
         this.area.mousemove(event => {
59
             const position = this.area.position();
73
             const position = this.area.position();
60
-            this._sendEvent({
61
-                type: "mousemove",
74
+            this._sendRemoteControlEvent({
75
+                type: EVENT_TYPES.mousemove,
62
                 x: (event.pageX - position.left)/this.area.width(),
76
                 x: (event.pageX - position.left)/this.area.width(),
63
                 y: (event.pageY - position.top)/this.area.height()
77
                 y: (event.pageY - position.top)/this.area.height()
64
             });
78
             });
65
         });
79
         });
66
-        this.area.mousedown(this._onMouseClickHandler.bind(this, "mousedown"));
67
-        this.area.mouseup(this._onMouseClickHandler.bind(this, "mouseup"));
80
+        this.area.mousedown(this._onMouseClickHandler.bind(this,
81
+            EVENT_TYPES.mousedown));
82
+        this.area.mouseup(this._onMouseClickHandler.bind(this,
83
+            EVENT_TYPES.mouseup));
68
         this.area.dblclick(
84
         this.area.dblclick(
69
-            this._onMouseClickHandler.bind(this, "mousedblclick"));
85
+            this._onMouseClickHandler.bind(this, EVENT_TYPES.mousedblclick));
70
         this.area.contextmenu(() => false);
86
         this.area.contextmenu(() => false);
71
         this.area[0].onmousewheel = event => {
87
         this.area[0].onmousewheel = event => {
72
-            this._sendEvent({
73
-                type: "mousescroll",
88
+            this._sendRemoteControlEvent({
89
+                type: EVENT_TYPES.mousescroll,
74
                 x: event.deltaX,
90
                 x: event.deltaX,
75
                 y: event.deltaY
91
                 y: event.deltaY
76
             });
92
             });
77
         };
93
         };
78
-        $(window).keydown(this._onKeyPessHandler.bind(this, "keydown"));
79
-        $(window).keyup(this._onKeyPessHandler.bind(this, "keyup"));
94
+        $(window).keydown(this._onKeyPessHandler.bind(this,
95
+            EVENT_TYPES.keydown));
96
+        $(window).keyup(this._onKeyPessHandler.bind(this, EVENT_TYPES.keyup));
80
     }
97
     }
81
 
98
 
82
     /**
99
     /**
99
      * @param {Event} event the mouse event.
116
      * @param {Event} event the mouse event.
100
      */
117
      */
101
     _onMouseClickHandler(type, event) {
118
     _onMouseClickHandler(type, event) {
102
-        this._sendEvent({
119
+        this._sendRemoteControlEvent({
103
             type: type,
120
             type: type,
104
             button: event.which
121
             button: event.which
105
         });
122
         });
111
      * @param {Event} event the key event.
128
      * @param {Event} event the key event.
112
      */
129
      */
113
     _onKeyPessHandler(type, event) {
130
     _onKeyPessHandler(type, event) {
114
-        this._sendEvent({
131
+        this._sendRemoteControlEvent({
115
             type: type,
132
             type: type,
116
             key: getKey(event),
133
             key: getKey(event),
117
             modifiers: getModifiers(event),
134
             modifiers: getModifiers(event),
123
      * @param {Object} event the remote control event.
140
      * @param {Object} event the remote control event.
124
      */
141
      */
125
     _sendRemoteControlEvent(event) {
142
     _sendRemoteControlEvent(event) {
143
+        if(!this.enabled)
144
+            return;
126
         try{
145
         try{
127
             APP.conference.sendEndpointMessage("",
146
             APP.conference.sendEndpointMessage("",
128
-                {type: "remote-control-event", event});
147
+                {type: API_EVENT_TYPE, event});
129
         } catch (e) {
148
         } catch (e) {
130
             // failed to send the event.
149
             // failed to send the event.
131
         }
150
         }
132
     }
151
     }
133
 }
152
 }
134
-
135
-
136
-export default new Controller();

+ 25
- 8
modules/remotecontrol/Receiver.js Wyświetl plik

1
 /* global APP, JitsiMeetJS */
1
 /* global APP, JitsiMeetJS */
2
+import {DISCO_REMOTE_CONTROL_FEATURE, API_EVENT_TYPE}
3
+    from "../../service/remotecontrol/Constants";
4
+
2
 const ConferenceEvents = JitsiMeetJS.events.conference;
5
 const ConferenceEvents = JitsiMeetJS.events.conference;
3
 
6
 
4
 /**
7
 /**
7
  * API module. From there the events can be received from wrapper application
10
  * API module. From there the events can be received from wrapper application
8
  * and executed.
11
  * and executed.
9
  */
12
  */
10
-class Receiver {
13
+export default class Receiver {
11
     /**
14
     /**
12
      * Creates new instance.
15
      * Creates new instance.
13
      * @constructor
16
      * @constructor
14
      */
17
      */
15
-    constructor() {}
18
+    constructor() {
19
+        this.enabled = false;
20
+    }
21
+
22
+    /**
23
+     * Enables / Disables the remote control
24
+     * @param {boolean} enabled the new state.
25
+     */
26
+    enable(enabled) {
27
+        if(this.enabled !== enabled && enabled === true) {
28
+            this.enabled = enabled;
29
+            // Announce remote control support.
30
+            APP.connection.addFeature(DISCO_REMOTE_CONTROL_FEATURE, true);
31
+        }
32
+    }
16
 
33
 
17
     /**
34
     /**
18
      * Attaches listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED events.
35
      * Attaches listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED events.
19
      */
36
      */
20
     start() {
37
     start() {
21
-        APP.conference.addConferenceListener(
22
-            ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
23
-            this._onRemoteControlEvent);
38
+        if(this.enabled) {
39
+            APP.conference.addConferenceListener(
40
+                ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
41
+                this._onRemoteControlEvent);
42
+        }
24
     }
43
     }
25
 
44
 
26
     /**
45
     /**
39
      * @param {Object} event the remote control event.
58
      * @param {Object} event the remote control event.
40
      */
59
      */
41
     _onRemoteControlEvent(participant, event) {
60
     _onRemoteControlEvent(participant, event) {
42
-        if(event.type === "remote-control-event")
61
+        if(event.type === API_EVENT_TYPE && this.enabled)
43
             APP.API.sendRemoteControlEvent(event.event);
62
             APP.API.sendRemoteControlEvent(event.event);
44
     }
63
     }
45
 }
64
 }
46
-
47
-export default new Receiver();

+ 51
- 0
modules/remotecontrol/RemoteControl.js Wyświetl plik

1
+/* global APP, config */
2
+import Controller from "./Controller";
3
+import Receiver from "./Receiver";
4
+
5
+/**
6
+ * Implements the remote control functionality.
7
+ */
8
+class RemoteControl {
9
+    /**
10
+     * Constructs new instance. Creates controller and receiver properties.
11
+     * @constructor
12
+     */
13
+    constructor() {
14
+        this.controller = new Controller();
15
+        this.receiver = new Receiver();
16
+        this.enabled = false;
17
+        this.initialized = false;
18
+    }
19
+
20
+    /**
21
+     * Initializes the remote control - checks if the remote control should be
22
+     * enabled or not, initializes the API module.
23
+     */
24
+    init() {
25
+        if(config.disableRemoteControl || this.initialized) {
26
+            return;
27
+        }
28
+        this.initialized = true;
29
+        APP.API.init({
30
+            forceEnable: true,
31
+        });
32
+        this.controller.enable(true);
33
+    }
34
+
35
+    /**
36
+     * Handles API event for support for executing remote control events into
37
+     * the wrapper application.
38
+     * @param {boolean} isSupported true if the receiver side is supported by
39
+     * the wrapper application.
40
+     */
41
+    onRemoteControlSupported(isSupported) {
42
+        if(isSupported && !config.disableRemoteControl) {
43
+            this.enabled = true;
44
+            if(this.initialized) {
45
+                this.receiver.enable(true);
46
+            }
47
+        }
48
+    }
49
+}
50
+
51
+export default new RemoteControl();

+ 0
- 4
modules/tokendata/TokenData.js Wyświetl plik

73
 
73
 
74
         this.jwt = jwt;
74
         this.jwt = jwt;
75
 
75
 
76
-        //External API settings
77
-        this.externalAPISettings = {
78
-            forceEnable: true
79
-        };
80
         this._decode();
76
         this._decode();
81
         // Use JWT param as token if there is not other token set and if the
77
         // Use JWT param as token if there is not other token set and if the
82
         // iss field is not anonymous. If you want to pass data with JWT token
78
         // iss field is not anonymous. If you want to pass data with JWT token

+ 1
- 1
react/features/app/functions.web.js Wyświetl plik

23
 
23
 
24
     APP.keyboardshortcut = KeyboardShortcut;
24
     APP.keyboardshortcut = KeyboardShortcut;
25
     APP.tokenData = getTokenData();
25
     APP.tokenData = getTokenData();
26
-    APP.API.init(APP.tokenData.externalAPISettings);
26
+    APP.API.init(APP.tokenData.jwt ? {forceEnable: true} : undefined);
27
 
27
 
28
     APP.translation.init(settings.getLanguage());
28
     APP.translation.init(settings.getLanguage());
29
 }
29
 }

+ 23
- 0
service/remotecontrol/Constants.js Wyświetl plik

1
+/**
2
+ * The value for the "var" attribute of feature tag in disco-info packets.
3
+ */
4
+export const DISCO_REMOTE_CONTROL_FEATURE
5
+    = "http://jitsi.org/meet/remotecontrol";
6
+
7
+/**
8
+ * Types of remote-control-event events.
9
+ */
10
+export const EVENT_TYPES = {
11
+    mousemove: "mousemove",
12
+    mousedown: "mousedown",
13
+    mouseup: "mouseup",
14
+    mousedblclick: "mousedblclick",
15
+    mousescroll: "mousescroll",
16
+    keydown: "keydown",
17
+    keyup: "keyup"
18
+};
19
+
20
+/**
21
+ * The type of remote control events sent trough the API module.
22
+ */
23
+export const API_EVENT_TYPE = "remote-control-event";

Ładowanie…
Anuluj
Zapisz