Browse Source

Changes the implementation of the iframe API to use postis

j8
hristoterezov 8 years ago
parent
commit
02f176c75a
10 changed files with 516 additions and 571 deletions
  1. 1
    0
      .gitignore
  2. 11
    2
      Makefile
  3. 1
    4
      app.js
  4. 2
    11
      conference.js
  5. 28
    9
      doc/api.md
  6. 5
    0
      doc/debian/jitsi-meet/jitsi-meet.example
  7. 0
    378
      external_api.js
  8. 107
    166
      modules/API/API.js
  9. 359
    0
      modules/API/external/external_api.js
  10. 2
    1
      modules/TokenData/TokenData.js

+ 1
- 0
.gitignore View File

7
 libs/app.bundle.*
7
 libs/app.bundle.*
8
 libs/lib-jitsi-meet*
8
 libs/lib-jitsi-meet*
9
 libs/external_connect.js
9
 libs/external_connect.js
10
+libs/external_api.*
10
 all.css
11
 all.css
11
 .remote-sync.json
12
 .remote-sync.json

+ 11
- 2
Makefile View File

8
 BROWSERIFY_FLAGS = -d
8
 BROWSERIFY_FLAGS = -d
9
 OUTPUT_DIR = .
9
 OUTPUT_DIR = .
10
 LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet/
10
 LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet/
11
+IFRAME_API_DIR = ./modules/API/external
11
 
12
 
12
-all: update-deps compile uglify deploy clean
13
+all: update-deps compile compile-iframe-api uglify  uglify-iframe-api deploy clean
13
 
14
 
14
 update-deps:
15
 update-deps:
15
 	$(NPM) install
16
 	$(NPM) install
17
 compile:
18
 compile:
18
 	$(BROWSERIFY) $(BROWSERIFY_FLAGS) -e app.js -s APP | $(EXORCIST) $(OUTPUT_DIR)/app.bundle.js.map > $(OUTPUT_DIR)/app.bundle.js
19
 	$(BROWSERIFY) $(BROWSERIFY_FLAGS) -e app.js -s APP | $(EXORCIST) $(OUTPUT_DIR)/app.bundle.js.map > $(OUTPUT_DIR)/app.bundle.js
19
 
20
 
21
+compile-iframe-api:
22
+	$(BROWSERIFY) $(BROWSERIFY_FLAGS) -e $(IFRAME_API_DIR)/external_api.js -s JitsiMeetExternalAPI | $(EXORCIST) $(OUTPUT_DIR)/external_api.js.map > $(OUTPUT_DIR)/external_api.js
23
+
20
 clean:
24
 clean:
21
-	rm -f $(OUTPUT_DIR)/app.bundle.*
25
+	rm -f $(OUTPUT_DIR)/app.bundle.* $(OUTPUT_DIR)/external_api.*
22
 
26
 
23
 deploy: deploy-init deploy-appbundle deploy-lib-jitsi-meet deploy-css deploy-local
27
 deploy: deploy-init deploy-appbundle deploy-lib-jitsi-meet deploy-css deploy-local
24
 
28
 
28
 deploy-appbundle:
32
 deploy-appbundle:
29
 	cp $(OUTPUT_DIR)/app.bundle.min.js $(OUTPUT_DIR)/app.bundle.min.map \
33
 	cp $(OUTPUT_DIR)/app.bundle.min.js $(OUTPUT_DIR)/app.bundle.min.map \
30
 	$(OUTPUT_DIR)/app.bundle.js $(OUTPUT_DIR)/app.bundle.js.map \
34
 	$(OUTPUT_DIR)/app.bundle.js $(OUTPUT_DIR)/app.bundle.js.map \
35
+	$(OUTPUT_DIR)/external_api.js.map $(OUTPUT_DIR)/external_api.js \
36
+	$(OUTPUT_DIR)/external_api.min.map $(OUTPUT_DIR)/external_api.min.js \
31
 	$(DEPLOY_DIR)
37
 	$(DEPLOY_DIR)
32
 
38
 
33
 deploy-lib-jitsi-meet:
39
 deploy-lib-jitsi-meet:
46
 uglify:
52
 uglify:
47
 	$(UGLIFYJS) -p relative $(OUTPUT_DIR)/app.bundle.js -o $(OUTPUT_DIR)/app.bundle.min.js --source-map $(OUTPUT_DIR)/app.bundle.min.map --in-source-map $(OUTPUT_DIR)/app.bundle.js.map
53
 	$(UGLIFYJS) -p relative $(OUTPUT_DIR)/app.bundle.js -o $(OUTPUT_DIR)/app.bundle.min.js --source-map $(OUTPUT_DIR)/app.bundle.min.map --in-source-map $(OUTPUT_DIR)/app.bundle.js.map
48
 
54
 
55
+uglify-iframe-api:
56
+	$(UGLIFYJS) -p relative $(OUTPUT_DIR)/external_api.js -o $(OUTPUT_DIR)/external_api.min.js --source-map $(OUTPUT_DIR)/external_api.min.map --in-source-map $(OUTPUT_DIR)/external_api.js.map
57
+
49
 
58
 
50
 source-package:
59
 source-package:
51
 	mkdir -p source_package/jitsi-meet/css && \
60
 	mkdir -p source_package/jitsi-meet/css && \

+ 1
- 4
app.js View File

116
             APP.keyboardshortcut.init();
116
             APP.keyboardshortcut.init();
117
         }).catch(function (err) {
117
         }).catch(function (err) {
118
             APP.UI.hideRingOverLay();
118
             APP.UI.hideRingOverLay();
119
-            APP.API.sendPostisMessage({
120
-                method: 'video-conference-left',
121
-                params: {roomName: APP.conference.roomName}
122
-            });
119
+            APP.API.notifyConferenceLeft(APP.conference.roomName);
123
             console.error(err);
120
             console.error(err);
124
         });
121
         });
125
     }
122
     }

+ 2
- 11
conference.js View File

155
 function disconnectAndShowFeedback(requestFeedback) {
155
 function disconnectAndShowFeedback(requestFeedback) {
156
     APP.UI.hideRingOverLay();
156
     APP.UI.hideRingOverLay();
157
     connection.disconnect();
157
     connection.disconnect();
158
-    APP.API.sendPostisMessage({
159
-        method: 'video-conference-left',
160
-        params: {roomName: APP.conference.roomName}
161
-    });
158
+    APP.API.notifyConferenceLeft(APP.conference.roomName);
162
     if (requestFeedback) {
159
     if (requestFeedback) {
163
         return APP.UI.requestFeedback();
160
         return APP.UI.requestFeedback();
164
     } else {
161
     } else {
465
             this._createRoom(tracks);
462
             this._createRoom(tracks);
466
             this.isDesktopSharingEnabled =
463
             this.isDesktopSharingEnabled =
467
                 JitsiMeetJS.isDesktopSharingEnabled();
464
                 JitsiMeetJS.isDesktopSharingEnabled();
468
-            if(this.isDesktopSharingEnabled)
469
-                APP.API.addPostisMessageListener('toggle-share-screen',
470
-                    () => this.toggleScreenSharing());
471
 
465
 
472
             // if user didn't give access to mic or camera or doesn't have
466
             // if user didn't give access to mic or camera or doesn't have
473
             // them at all, we disable corresponding toolbar buttons
467
             // them at all, we disable corresponding toolbar buttons
908
         // add local streams when joined to the conference
902
         // add local streams when joined to the conference
909
         room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
903
         room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
910
             APP.UI.mucJoined();
904
             APP.UI.mucJoined();
911
-            APP.API.sendPostisMessage({
912
-              method: 'video-conference-joined',
913
-              params: {roomName: APP.conference.roomName}
914
-            });
905
+            APP.API.notifyConferenceJoined(APP.conference.roomName);
915
         });
906
         });
916
 
907
 
917
         room.on(
908
         room.on(

+ 28
- 9
doc/api.md View File

20
     var height = 700;
20
     var height = 700;
21
     var api = new JitsiMeetExternalAPI(domain, room, width, height);
21
     var api = new JitsiMeetExternalAPI(domain, room, width, height);
22
 </script>
22
 </script>
23
-``` 
23
+```
24
 You can paste that lines in your html code where you want to be placed the Jitsi Meet conference
24
 You can paste that lines in your html code where you want to be placed the Jitsi Meet conference
25
 or you can specify the parent HTML element for the Jitsi Meet conference in the JitsiMeetExternalAPI
25
 or you can specify the parent HTML element for the Jitsi Meet conference in the JitsiMeetExternalAPI
26
 constructor.
26
 constructor.
27
 ```javascript
27
 ```javascript
28
     var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
28
     var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement);
29
-``` 
29
+```
30
 If you don't specify room the user will enter in new conference with random room name.
30
 If you don't specify room the user will enter in new conference with random room name.
31
 
31
 
32
 You can overwrite options set in config.js and interface_config.js. For example, to enable the film-strip-only interface mode and disable simulcast, you can use:
32
 You can overwrite options set in config.js and interface_config.js. For example, to enable the film-strip-only interface mode and disable simulcast, you can use:
34
     var configOverwrite = {enableSimulcast: false};
34
     var configOverwrite = {enableSimulcast: false};
35
     var interfaceConfigOverwrite = {filmStripOnly: true};
35
     var interfaceConfigOverwrite = {filmStripOnly: true};
36
     var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, true, configOverwrite, interfaceConfigOverwrite);
36
     var api = new JitsiMeetExternalAPI(domain, room, width, height, htmlElement, true, configOverwrite, interfaceConfigOverwrite);
37
-``` 
37
+```
38
 
38
 
39
 Controlling embedded Jitsi Meet Conference
39
 Controlling embedded Jitsi Meet Conference
40
 =========
40
 =========
41
 
41
 
42
 You can control the embedded Jitsi Meet conference using the JitsiMeetExternalAPI object.
42
 You can control the embedded Jitsi Meet conference using the JitsiMeetExternalAPI object.
43
 
43
 
44
-You can send command to Jitsi Meet conference using ```executeCommand```. 
44
+You can send command to Jitsi Meet conference using ```executeCommand```.
45
 ```
45
 ```
46
 api.executeCommand(command, arguments)
46
 api.executeCommand(command, arguments)
47
 ```
47
 ```
48
 The ```command``` parameter is String object with the name of the command.
48
 The ```command``` parameter is String object with the name of the command.
49
-The ```arguments``` parameter is array with the arguments required by the command. 
49
+The ```arguments``` parameter is array with the arguments required by the command.
50
 If no arguments are required by the command this parameter can be omitted or you can pass empty array.
50
 If no arguments are required by the command this parameter can be omitted or you can pass empty array.
51
 Currently we support the following commands:
51
 Currently we support the following commands:
52
 
52
 
53
 
53
 
54
-* **displayName** - sets the display name of the local participant. This command requires one argument - 
54
+* **displayName** - sets the display name of the local participant. This command requires one argument -
55
 the new display name to be set
55
 the new display name to be set
56
 ```
56
 ```
57
 api.executeCommand('displayName', ['New Nickname']);
57
 api.executeCommand('displayName', ['New Nickname']);
77
 api.executeCommand('toggleContactList', [])
77
 api.executeCommand('toggleContactList', [])
78
 ```
78
 ```
79
 
79
 
80
-You can also execute multiple commands using the method ```executeCommands```. 
80
+* **toggleShareScreen** - starts / stops the screen sharing. No arguments are required.
81
+```
82
+api.executeCommand('toggleShareScreen', [])
83
+```
84
+
85
+You can also execute multiple commands using the method ```executeCommands```.
81
 ```
86
 ```
82
 api.executeCommands(commands)
87
 api.executeCommands(commands)
83
 ```
88
 ```
136
 jid: jid //the jid of the participant
141
 jid: jid //the jid of the participant
137
 }
142
 }
138
 ```
143
 ```
144
+* **video-conference-joined** - event notifications fired when the local user has joined the video conference.
145
+The listener will receive object with the following structure:
146
+```
147
+{
148
+roomName: room //the room name of the conference
149
+}
150
+```
151
+* **video-conference-left** - event notifications fired when the local user has left the video conference.
152
+The listener will receive object with the following structure:
153
+```
154
+{
155
+roomName: room //the room name of the conference
156
+}
157
+```
139
 
158
 
140
 You can also add multiple event listeners by using ```addEventListeners```.
159
 You can also add multiple event listeners by using ```addEventListeners```.
141
-This method requires one argument of type Object. The object argument must 
160
+This method requires one argument of type Object. The object argument must
142
 have keys with the names of the events and values the listeners of the events.
161
 have keys with the names of the events and values the listeners of the events.
143
 
162
 
144
 ```
163
 ```
173
 api.dispose()
192
 api.dispose()
174
 ```
193
 ```
175
 
194
 
176
-It is a good practice to remove the conference before the page is unloaded. 
195
+It is a good practice to remove the conference before the page is unloaded.

+ 5
- 0
doc/debian/jitsi-meet/jitsi-meet.example View File

33
         ssi on;
33
         ssi on;
34
     }
34
     }
35
 
35
 
36
+    # Backward compatibility
37
+    location ~ /external_api.* {
38
+        root /usr/share/jitsi-meet/libs;
39
+    }
40
+
36
     # BOSH
41
     # BOSH
37
     location /http-bind {
42
     location /http-bind {
38
         proxy_pass      http://localhost:5280/http-bind;
43
         proxy_pass      http://localhost:5280/http-bind;

+ 0
- 378
external_api.js View File

1
-/**
2
- * Implements API class that embeds Jitsi Meet in external applications.
3
- */
4
-var JitsiMeetExternalAPI = (function()
5
-{
6
-    /**
7
-     * The minimum width for the Jitsi Meet frame
8
-     * @type {number}
9
-     */
10
-    var MIN_WIDTH = 790;
11
-
12
-    /**
13
-     * The minimum height for the Jitsi Meet frame
14
-     * @type {number}
15
-     */
16
-    var MIN_HEIGHT = 300;
17
-
18
-    /**
19
-     * Constructs new API instance. Creates iframe element that loads
20
-     * Jitsi Meet.
21
-     * @param domain the domain name of the server that hosts the conference
22
-     * @param room_name the name of the room to join
23
-     * @param width width of the iframe
24
-     * @param height height of the iframe
25
-     * @param parent_node the node that will contain the iframe
26
-     * @param filmStripOnly if the value is true only the small videos will be
27
-     * visible.
28
-     * @param noSsl if the value is true https won't be used
29
-     * @constructor
30
-     */
31
-    function JitsiMeetExternalAPI(domain, room_name, width, height, parentNode,
32
-        configOverwrite, interfaceConfigOverwrite, noSsl) {
33
-        if (!width || width < MIN_WIDTH)
34
-            width = MIN_WIDTH;
35
-        if (!height || height < MIN_HEIGHT)
36
-            height = MIN_HEIGHT;
37
-
38
-        this.parentNode = null;
39
-        if (parentNode) {
40
-            this.parentNode = parentNode;
41
-        } else {
42
-            var scriptTag = document.scripts[document.scripts.length - 1];
43
-            this.parentNode = scriptTag.parentNode;
44
-        }
45
-
46
-        this.iframeHolder =
47
-            this.parentNode.appendChild(document.createElement("div"));
48
-        this.iframeHolder.id = "jitsiConference" + JitsiMeetExternalAPI.id;
49
-        if(width)
50
-            this.iframeHolder.style.width = width + "px";
51
-        if(height)
52
-            this.iframeHolder.style.height = height + "px";
53
-        this.frameName = "jitsiConferenceFrame" + JitsiMeetExternalAPI.id;
54
-        this.url = (noSsl) ? "http" : "https" +"://" + domain + "/";
55
-        if(room_name)
56
-            this.url += room_name;
57
-        this.url += "#external=true";
58
-
59
-        var key;
60
-        if (configOverwrite) {
61
-            for (key in configOverwrite) {
62
-                if (!configOverwrite.hasOwnProperty(key) ||
63
-                    typeof key !== 'string')
64
-                    continue;
65
-                this.url += "&config." + key + "=" + configOverwrite[key];
66
-            }
67
-        }
68
-
69
-        if (interfaceConfigOverwrite) {
70
-            for (key in interfaceConfigOverwrite) {
71
-                if (!interfaceConfigOverwrite.hasOwnProperty(key) ||
72
-                    typeof key !== 'string')
73
-                    continue;
74
-                this.url += "&interfaceConfig." + key + "=" +
75
-                    interfaceConfigOverwrite[key];
76
-            }
77
-        }
78
-
79
-        JitsiMeetExternalAPI.id++;
80
-
81
-        this.frame = document.createElement("iframe");
82
-        this.frame.src = this.url;
83
-        this.frame.name = this.frameName;
84
-        this.frame.id = this.frameName;
85
-        this.frame.width = "100%";
86
-        this.frame.height = "100%";
87
-        this.frame.setAttribute("allowFullScreen","true");
88
-        this.frame = this.iframeHolder.appendChild(this.frame);
89
-
90
-
91
-        this.frameLoaded = false;
92
-        this.initialCommands = [];
93
-        this.eventHandlers = {};
94
-        this.initListeners();
95
-    }
96
-
97
-    /**
98
-     * Last id of api object
99
-     * @type {number}
100
-     */
101
-    JitsiMeetExternalAPI.id = 0;
102
-
103
-    /**
104
-     * Sends the passed object to Jitsi Meet
105
-     * @param object the object to be sent
106
-     */
107
-    JitsiMeetExternalAPI.prototype.sendMessage = function(object) {
108
-        if (this.frameLoaded) {
109
-            this.frame.contentWindow.postMessage(
110
-                JSON.stringify(object), this.frame.src);
111
-        }
112
-        else {
113
-            this.initialCommands.push(object);
114
-        }
115
-
116
-    };
117
-
118
-    /**
119
-     * Executes command. The available commands are:
120
-     * displayName - sets the display name of the local participant to the value
121
-     * passed in the arguments array.
122
-     * toggleAudio - mutes / unmutes audio with no arguments
123
-     * toggleVideo - mutes / unmutes video with no arguments
124
-     * filmStrip - hides / shows the film strip with no arguments
125
-     * If the command doesn't require any arguments the parameter should be set
126
-     * to empty array or it may be omitted.
127
-     * @param name the name of the command
128
-     * @param arguments array of arguments
129
-     */
130
-    JitsiMeetExternalAPI.prototype.executeCommand = function(name,
131
-                                                             argumentsList) {
132
-        var argumentsArray = argumentsList;
133
-        if (!argumentsArray)
134
-            argumentsArray = [];
135
-        var object = {type: "command", action: "execute"};
136
-        object[name] = argumentsArray;
137
-        this.sendMessage(object);
138
-    };
139
-
140
-    /**
141
-     * Executes commands. The available commands are:
142
-     * displayName - sets the display name of the local participant to the value
143
-     * passed in the arguments array.
144
-     * toggleAudio - mutes / unmutes audio with no arguments
145
-     * toggleVideo - mutes / unmutes video with no arguments
146
-     * filmStrip - hides / shows the film strip with no arguments
147
-     * @param object the object with commands to be executed. The keys of the
148
-     * object are the commands that will be executed and the values are the
149
-     * arguments for the command.
150
-     */
151
-    JitsiMeetExternalAPI.prototype.executeCommands = function (object) {
152
-        object.type = "command";
153
-        object.action = "execute";
154
-        this.sendMessage(object);
155
-    };
156
-
157
-    /**
158
-     * Adds event listeners to Meet Jitsi. The object key should be the name of
159
-     * the event and value - the listener.
160
-     * Currently we support the following
161
-     * events:
162
-     * incomingMessage - receives event notifications about incoming
163
-     * messages. The listener will receive object with the following structure:
164
-     * {{
165
-     *  "from": from,//JID of the user that sent the message
166
-     *  "nick": nick,//the nickname of the user that sent the message
167
-     *  "message": txt//the text of the message
168
-     * }}
169
-     * outgoingMessage - receives event notifications about outgoing
170
-     * messages. The listener will receive object with the following structure:
171
-     * {{
172
-     *  "message": txt//the text of the message
173
-     * }}
174
-     * displayNameChanged - receives event notifications about display name
175
-     * change. The listener will receive object with the following structure:
176
-     * {{
177
-     * jid: jid,//the JID of the participant that changed his display name
178
-     * displayname: displayName //the new display name
179
-     * }}
180
-     * participantJoined - receives event notifications about new participant.
181
-     * The listener will receive object with the following structure:
182
-     * {{
183
-     * jid: jid //the jid of the participant
184
-     * }}
185
-     * participantLeft - receives event notifications about the participant that
186
-     * left the room.
187
-     * The listener will receive object with the following structure:
188
-     * {{
189
-     * jid: jid //the jid of the participant
190
-     * }}
191
-     * @param object
192
-     */
193
-    JitsiMeetExternalAPI.prototype.addEventListeners
194
-        = function (object) {
195
-
196
-        var message = {type: "event", action: "add", events: []};
197
-        for(var i in object)
198
-        {
199
-            message.events.push(i);
200
-            this.eventHandlers[i] = object[i];
201
-        }
202
-        this.sendMessage(message);
203
-    };
204
-
205
-    /**
206
-     * Adds event listeners to Meet Jitsi. Currently we support the following
207
-     * events:
208
-     * incomingMessage - receives event notifications about incoming
209
-     * messages. The listener will receive object with the following structure:
210
-     * {{
211
-     *  "from": from,//JID of the user that sent the message
212
-     *  "nick": nick,//the nickname of the user that sent the message
213
-     *  "message": txt//the text of the message
214
-     * }}
215
-     * outgoingMessage - receives event notifications about outgoing
216
-     * messages. The listener will receive object with the following structure:
217
-     * {{
218
-     *  "message": txt//the text of the message
219
-     * }}
220
-     * displayNameChanged - receives event notifications about display name
221
-     * change. The listener will receive object with the following structure:
222
-     * {{
223
-     * jid: jid,//the JID of the participant that changed his display name
224
-     * displayname: displayName //the new display name
225
-     * }}
226
-     * participantJoined - receives event notifications about new participant.
227
-     * The listener will receive object with the following structure:
228
-     * {{
229
-     * jid: jid //the jid of the participant
230
-     * }}
231
-     * participantLeft - receives event notifications about participant the that
232
-     * left the room.
233
-     * The listener will receive object with the following structure:
234
-     * {{
235
-     * jid: jid //the jid of the participant
236
-     * }}
237
-     * @param event the name of the event
238
-     * @param listener the listener
239
-     */
240
-    JitsiMeetExternalAPI.prototype.addEventListener
241
-        = function (event, listener) {
242
-
243
-        var message = {type: "event", action: "add", events: [event]};
244
-        this.eventHandlers[event] = listener;
245
-        this.sendMessage(message);
246
-    };
247
-
248
-    /**
249
-     * Removes event listener.
250
-     * @param event the name of the event.
251
-     */
252
-    JitsiMeetExternalAPI.prototype.removeEventListener
253
-        = function (event) {
254
-        if(!this.eventHandlers[event])
255
-        {
256
-            console.error("The event " + event + " is not registered.");
257
-            return;
258
-        }
259
-        var message = {type: "event", action: "remove", events: [event]};
260
-        delete this.eventHandlers[event];
261
-        this.sendMessage(message);
262
-    };
263
-
264
-    /**
265
-     * Removes event listeners.
266
-     * @param events array with the names of the events.
267
-     */
268
-    JitsiMeetExternalAPI.prototype.removeEventListeners
269
-        = function (events) {
270
-        var eventsArray = [];
271
-        for(var i = 0; i < events.length; i++)
272
-        {
273
-            var event = events[i];
274
-            if(!this.eventHandlers[event])
275
-            {
276
-                console.error("The event " + event + " is not registered.");
277
-                continue;
278
-            }
279
-            delete this.eventHandlers[event];
280
-            eventsArray.push(event);
281
-        }
282
-
283
-        if(eventsArray.length > 0)
284
-        {
285
-            this.sendMessage(
286
-                {type: "event", action: "remove", events: eventsArray});
287
-        }
288
-
289
-    };
290
-
291
-    /**
292
-     * Processes message events sent from Jitsi Meet
293
-     * @param event the event
294
-     */
295
-    JitsiMeetExternalAPI.prototype.processMessage = function(event) {
296
-        var message;
297
-        try {
298
-            message = JSON.parse(event.data);
299
-        } catch (e) {}
300
-
301
-        if(!message.type) {
302
-            console.error("Message without type is received.");
303
-            return;
304
-        }
305
-        switch (message.type) {
306
-            case "system":
307
-                if(message.loaded) {
308
-                    this.onFrameLoaded();
309
-                }
310
-                break;
311
-            case "event":
312
-                if(message.action != "result" ||
313
-                    !message.event || !this.eventHandlers[message.event]) {
314
-                    console.warn("The received event cannot be parsed.");
315
-                    return;
316
-                }
317
-                this.eventHandlers[message.event](message.result);
318
-                break;
319
-            default :
320
-                console.error("Unknown message type.");
321
-                return;
322
-        }
323
-    };
324
-
325
-    /**
326
-     * That method is called when the Jitsi Meet is loaded. Executes saved
327
-     * commands that are send before the frame was loaded.
328
-     */
329
-    JitsiMeetExternalAPI.prototype.onFrameLoaded = function () {
330
-        this.frameLoaded = true;
331
-        for (var i = 0; i < this.initialCommands.length; i++) {
332
-            this.sendMessage(this.initialCommands[i]);
333
-        }
334
-        this.initialCommands = null;
335
-    };
336
-
337
-    /**
338
-     * Setups the listener for message events from Jitsi Meet.
339
-     */
340
-    JitsiMeetExternalAPI.prototype.initListeners = function () {
341
-        var self = this;
342
-        this.eventListener = function (event) {
343
-            self.processMessage(event);
344
-        };
345
-        if (window.addEventListener) {
346
-            window.addEventListener('message',
347
-                this.eventListener, false);
348
-        }
349
-        else {
350
-            window.attachEvent('onmessage', this.eventListener);
351
-        }
352
-    };
353
-
354
-    /**
355
-     * Removes the listeners and removes the Jitsi Meet frame.
356
-     */
357
-    JitsiMeetExternalAPI.prototype.dispose = function () {
358
-        if (window.removeEventListener) {
359
-            window.removeEventListener('message',
360
-                this.eventListener, false);
361
-        }
362
-        else {
363
-            window.detachEvent('onmessage',
364
-                this.eventListener);
365
-        }
366
-        var frame = document.getElementById(this.frameName);
367
-        if(frame)
368
-            frame.src = 'about:blank';
369
-        var self = this;
370
-        window.setTimeout(function () {
371
-                self.iframeHolder.removeChild(self.frame);
372
-                self.iframeHolder.parentNode.removeChild(self.iframeHolder);
373
-        }, 10);
374
-    };
375
-
376
-    return JitsiMeetExternalAPI;
377
-
378
-})();

+ 107
- 166
modules/API/API.js View File

1
-/* global APP */
1
+/* global APP, getConfigParamsFromUrl */
2
 /**
2
 /**
3
  * Implements API class that communicates with external api class
3
  * Implements API class that communicates with external api class
4
  * and provides interface to access Jitsi Meet features by external
4
  * and provides interface to access Jitsi Meet features by external
5
  * applications that embed Jitsi Meet
5
  * applications that embed Jitsi Meet
6
  */
6
  */
7
 
7
 
8
- import postis from 'postis';
8
+import postisInit from 'postis';
9
 
9
 
10
 /**
10
 /**
11
  * List of the available commands.
11
  * List of the available commands.
20
  */
20
  */
21
 let commands = {};
21
 let commands = {};
22
 
22
 
23
+let hashParams = getConfigParamsFromUrl();
24
+
23
 /**
25
 /**
24
- * Object that will execute sendMessage
26
+ * JitsiMeetExternalAPI id - unique for a webpage.
25
  */
27
  */
26
-let target = window.opener ? window.opener : window.parent;
28
+let jitsi_meet_external_api_id = hashParams.jitsi_meet_external_api_id;
27
 
29
 
28
 /**
30
 /**
29
- * Array of functions that are going to receive the objects passed to this
30
- * window
31
+ * Object that will execute sendMessage
31
  */
32
  */
32
-let messageListeners = [];
33
+let target = window.opener ? window.opener : window.parent;
33
 
34
 
34
 /**
35
 /**
35
- * Current status (enabled/disabled) of Postis.
36
+ * Postis instance. Used to communicate with the external application.
36
  */
37
  */
37
-let enablePostis = false;
38
+let postis;
38
 
39
 
39
 /**
40
 /**
40
- * Current status (enabled/disabled) of Post Message API.
41
+ * Current status (enabled/disabled) of API.
41
  */
42
  */
42
-let enablePostMessage = false;
43
+let enabled = false;
43
 
44
 
44
 function initCommands() {
45
 function initCommands() {
45
     commands = {
46
     commands = {
46
-        displayName: APP.UI.inputDisplayNameHandler,
47
-        toggleAudio: APP.conference.toggleAudioMuted,
48
-        toggleVideo: APP.conference.toggleVideoMuted,
49
-        toggleFilmStrip: APP.UI.toggleFilmStrip,
50
-        toggleChat: APP.UI.toggleChat,
51
-        toggleContactList: APP.UI.toggleContactList
47
+        "display-name": APP.UI.inputDisplayNameHandler,
48
+        "toggle-audio": APP.conference.toggleAudioMuted,
49
+        "toggle-video": APP.conference.toggleVideoMuted,
50
+        "toggle-film-strip": APP.UI.toggleFilmStrip,
51
+        "toggle-chat": APP.UI.toggleChat,
52
+        "toggle-contact-list": APP.UI.toggleContactList,
53
+        "toggle-share-screen": APP.conference.toggleScreenSharing
52
     };
54
     };
55
+    Object.keys(commands).forEach(function (key) {
56
+        postis.listen(key, commands[key]);
57
+    });
53
 }
58
 }
54
 
59
 
55
 
60
 
57
  * Maps the supported events and their status
62
  * Maps the supported events and their status
58
  * (true it the event is enabled and false if it is disabled)
63
  * (true it the event is enabled and false if it is disabled)
59
  * @type {{
64
  * @type {{
60
- *              incomingMessage: boolean,
61
- *              outgoingMessage: boolean,
62
- *              displayNameChange: boolean,
63
- *              participantJoined: boolean,
64
- *              participantLeft: boolean
65
+ *              incoming-message: boolean,
66
+ *              outgoing-message: boolean,
67
+ *              display-name-change: boolean,
68
+ *              participant-left: boolean,
69
+ *              participant-joined: boolean,
70
+ *              video-conference-left: boolean,
71
+ *              video-conference-joined: boolean
65
  *      }}
72
  *      }}
66
  */
73
  */
67
 const events = {
74
 const events = {
68
-    incomingMessage: false,
69
-    outgoingMessage:false,
70
-    displayNameChange: false,
71
-    participantJoined: false,
72
-    participantLeft: false
75
+    "incoming-message": false,
76
+    "outgoing-message":false,
77
+    "display-name-change": false,
78
+    "participant-joined": false,
79
+    "participant-left": false,
80
+    "video-conference-joined": false,
81
+    "video-conference-left": false
73
 };
82
 };
74
 
83
 
75
-/**
76
- * Processes commands from external application.
77
- * @param message the object with the command
78
- */
79
-function processCommand(message) {
80
-    if (message.action != "execute") {
81
-        console.error("Unknown action of the message");
82
-        return;
83
-    }
84
-    for (var key in message) {
85
-        if(commands[key])
86
-            commands[key].apply(null, message[key]);
87
-    }
88
-}
89
-
90
-/**
91
- * Processes events objects from external applications
92
- * @param event the event
93
- */
94
-function processEvent(event) {
95
-    if (!event.action) {
96
-        console.error("Event with no action is received.");
97
-        return;
98
-    }
99
-
100
-    var i = 0;
101
-    switch(event.action) {
102
-        case "add":
103
-            for (; i < event.events.length; i++) {
104
-                events[event.events[i]] = true;
105
-            }
106
-            break;
107
-        case "remove":
108
-            for (; i < event.events.length; i++) {
109
-                events[event.events[i]] = false;
110
-            }
111
-            break;
112
-        default:
113
-            console.error("Unknown action for event.");
114
-    }
115
-}
116
-
117
-/**
118
- * Processes a message event from the external application
119
- * @param event the message event
120
- */
121
-function processMessage(event) {
122
-    var message;
123
-    try {
124
-        message = JSON.parse(event.data);
125
-    } catch (e) {
126
-        console.error("Cannot parse data", event.data);
127
-        return;
128
-    }
129
-
130
-    switch (message.type) {
131
-        case "command":
132
-            processCommand(message);
133
-            break;
134
-        case "event":
135
-            processEvent(message);
136
-            break;
137
-        default:
138
-            console.warn("Unknown message type");
139
-    }
140
-}
141
-
142
 /**
84
 /**
143
  * Sends message to the external application.
85
  * Sends message to the external application.
144
- * @param object {object} the object that will be sent as JSON string
86
+ * @param message {object}
87
+ * @param method {string}
88
+ * @param params {object} the object that will be sent as JSON string
145
  */
89
  */
146
-function sendMessage(object) {
147
-    if(enablePostMessage)
148
-        target.postMessage(JSON.stringify(object), "*");
90
+function sendMessage(message) {
91
+    if(enabled)
92
+        postis.send(message);
149
 }
93
 }
150
 
94
 
151
 /**
95
 /**
153
  * @returns {boolean}
97
  * @returns {boolean}
154
  */
98
  */
155
 function isEnabled () {
99
 function isEnabled () {
156
-    let hash = location.hash;
157
-    return !!(hash && hash.indexOf("external=true") > -1 && window.postMessage);
100
+    return (typeof jitsi_meet_external_api_id === "number");
158
 }
101
 }
159
 
102
 
160
 /**
103
 /**
173
  * @param object data associated with the event
116
  * @param object data associated with the event
174
  */
117
  */
175
 function triggerEvent (name, object) {
118
 function triggerEvent (name, object) {
176
-    if (isEventEnabled(name) && enablePostMessage) {
177
-        sendMessage({
178
-            type: "event",
179
-            action: "result",
180
-            event: name,
181
-            result: object
182
-        });
119
+    if(isEventEnabled(name))
120
+        sendMessage({method: name, params: object});
121
+}
122
+
123
+/**
124
+ * Handles system messages. (for example: enable/disable events)
125
+ * @param message {object} the message
126
+ */
127
+function onSystemMessage(message) {
128
+    switch (message.type) {
129
+        case "eventStatus":
130
+            if(!message.name || !message.value) {
131
+                console.warn("Unknown system message format", message);
132
+                break;
133
+            }
134
+            events[message.name] = message.value;
135
+            break;
136
+        default:
137
+            console.warn("Unknown system message type", message);
183
     }
138
     }
184
 }
139
 }
185
 
140
 
190
      * It also sends a message to the external application that APIConnector
145
      * It also sends a message to the external application that APIConnector
191
      * is initialized.
146
      * is initialized.
192
      * @param options {object}
147
      * @param options {object}
193
-     * @param enablePostis {boolean} if true the postis npm
194
-     * package for comminication with the parent window will be enabled.
195
-     * @param enablePostMessage {boolean} if true the postMessageAPI for
196
-     * comminication with the parent window will be enabled.
148
+     * @param forceEnable {boolean} if true the module will be enabled.
149
+     * @param enabledEvents {array} array of events that should be enabled.
197
      */
150
      */
198
-    init: function (options = {}) {
199
-        options.enablePostMessage = options.enablePostMessage || isEnabled();
200
-        if (!options.enablePostis &&
201
-            !options.enablePostMessage) {
151
+    init (options = {}) {
152
+        if(!isEnabled() && !options.forceEnable)
202
             return;
153
             return;
203
-        }
204
-        enablePostis = options.enablePostis;
205
-        enablePostMessage = options.enablePostMessage;
206
 
154
 
207
-        if(enablePostMessage) {
208
-            initCommands();
209
-            if (window.addEventListener) {
210
-                window.addEventListener('message', processMessage, false);
211
-            } else {
212
-                window.attachEvent('onmessage', processMessage);
213
-            }
214
-            sendMessage({type: "system", loaded: true});
215
-        }
216
-
217
-        if(enablePostis) {
218
-            this.postis = postis({window: target});
219
-        }
155
+        enabled = true;
156
+        if(options.enabledEvents)
157
+            options.enabledEvents.forEach(function (eventName) {
158
+                events[eventName] = true;
159
+            });
160
+        let postisOptions = {
161
+            window: target
162
+        };
163
+        if(typeof jitsi_meet_external_api_id === "number")
164
+            postisOptions.scope
165
+                = "jitsi_meet_external_api_" + jitsi_meet_external_api_id;
166
+        postis = postisInit(postisOptions);
167
+        postis.listen("jitsiSystemMessage", onSystemMessage);
168
+        initCommands();
220
     },
169
     },
221
 
170
 
222
     /**
171
     /**
224
      * @param {string} body message body
173
      * @param {string} body message body
225
      */
174
      */
226
     notifySendingChatMessage (body) {
175
     notifySendingChatMessage (body) {
227
-        triggerEvent("outgoingMessage", {"message": body});
228
-    },
229
-
230
-    /**
231
-     * Sends message to the external application.
232
-     * @param options {object}
233
-     * @param method {string}
234
-     * @param params {object} the object that will be sent as JSON string
235
-     */
236
-    sendPostisMessage(options) {
237
-        if(enablePostis)
238
-            this.postis.send(options);
239
-    },
240
-
241
-    /**
242
-     * Adds listener for Postis messages.
243
-     * @param method {string} postis mehtod
244
-     * @param listener {function}
245
-     */
246
-    addPostisMessageListener (method, listener) {
247
-        if(enablePostis)
248
-            this.postis.listen(method, listener);
176
+        triggerEvent("outgoing-message", {"message": body});
249
     },
177
     },
250
 
178
 
251
     /**
179
     /**
262
         }
190
         }
263
 
191
 
264
         triggerEvent(
192
         triggerEvent(
265
-            "incomingMessage",
193
+            "incoming-message",
266
             {"from": id, "nick": nick, "message": body, "stamp": ts}
194
             {"from": id, "nick": nick, "message": body, "stamp": ts}
267
         );
195
         );
268
     },
196
     },
273
      * @param {string} id user id
201
      * @param {string} id user id
274
      */
202
      */
275
     notifyUserJoined (id) {
203
     notifyUserJoined (id) {
276
-        triggerEvent("participantJoined", {id});
204
+        triggerEvent("participant-joined", {id});
277
     },
205
     },
278
 
206
 
279
     /**
207
     /**
282
      * @param {string} id user id
210
      * @param {string} id user id
283
      */
211
      */
284
     notifyUserLeft (id) {
212
     notifyUserLeft (id) {
285
-        triggerEvent("participantLeft", {id});
213
+        triggerEvent("participant-left", {id});
286
     },
214
     },
287
 
215
 
288
     /**
216
     /**
292
      * @param {string} displayName user nickname
220
      * @param {string} displayName user nickname
293
      */
221
      */
294
     notifyDisplayNameChanged (id, displayName) {
222
     notifyDisplayNameChanged (id, displayName) {
295
-        triggerEvent("displayNameChange", {id, displayname: displayName});
223
+        triggerEvent("display-name-change", {id, displayname: displayName});
224
+    },
225
+
226
+    /**
227
+     * Notify external application (if API is enabled) that
228
+     * user changed their nickname.
229
+     * @param {string} id user id
230
+     * @param {string} displayName user nickname
231
+     */
232
+    notifyConferenceJoined (room) {
233
+        triggerEvent("video-conference-joined", {roomName: room});
234
+    },
235
+
236
+    /**
237
+     * Notify external application (if API is enabled) that
238
+     * user changed their nickname.
239
+     * @param {string} id user id
240
+     * @param {string} displayName user nickname
241
+     */
242
+    notifyConferenceLeft (room) {
243
+        triggerEvent("video-conference-left", {roomName: room});
296
     },
244
     },
297
 
245
 
298
     /**
246
     /**
299
      * Removes the listeners.
247
      * Removes the listeners.
300
      */
248
      */
301
     dispose: function () {
249
     dispose: function () {
302
-        if (enablePostMessage) {
303
-            if (window.removeEventListener) {
304
-                window.removeEventListener("message", processMessage, false);
305
-            } else {
306
-                window.detachEvent('onmessage', processMessage);
307
-            }
308
-        }
309
-        if(enablePostis)
310
-            this.postis.destroy();
250
+        if(enabled)
251
+            postis.destroy();
311
     }
252
     }
312
 };
253
 };

+ 359
- 0
modules/API/external/external_api.js View File

1
+/**
2
+ * Implements API class that embeds Jitsi Meet in external applications.
3
+ */
4
+
5
+var postisInit = require("postis");
6
+
7
+/**
8
+ * The minimum width for the Jitsi Meet frame
9
+ * @type {number}
10
+ */
11
+var MIN_WIDTH = 790;
12
+
13
+/**
14
+ * The minimum height for the Jitsi Meet frame
15
+ * @type {number}
16
+ */
17
+var MIN_HEIGHT = 300;
18
+
19
+/**
20
+ * Last id of api object
21
+ * @type {number}
22
+ */
23
+var id = 0;
24
+
25
+/**
26
+ * Maps the names of the commands expected by the API with the name of the
27
+ * commands expected by jitsi-meet
28
+ */
29
+var commands = {
30
+    "displayName": "display-name",
31
+    "toggleAudio": "toggle-audio",
32
+    "toggleVideo": "toggle-video",
33
+    "toggleFilmStrip": "toggle-film-strip",
34
+    "toggleChat": "toggle-chat",
35
+    "toggleContactList": "toggle-contact-list",
36
+    "toggleShareScreen": "toggle-share-screen"
37
+};
38
+
39
+/**
40
+ * Maps the names of the events expected by the API with the name of the
41
+ * events expected by jitsi-meet
42
+ */
43
+var events = {
44
+    "incomingMessage": "incoming-message",
45
+    "outgoingMessage": "outgoing-message",
46
+    "displayNameChange": "display-name-change",
47
+    "participantJoined": "participant-joined",
48
+    "participantLeft": "participant-left",
49
+    "videoConferenceJoined": "video-conference-joined",
50
+    "videoConferenceLeft": "video-conference-left"
51
+};
52
+
53
+/**
54
+ * Sends the passed object to Jitsi Meet
55
+ * @param postis {Postis object} the postis instance that is going to be used
56
+ * to send the message
57
+ * @param object the object to be sent
58
+ * - method {sting}
59
+ * - params {object}
60
+ */
61
+function sendMessage(postis, object) {
62
+    postis.send(object);
63
+}
64
+
65
+/**
66
+ * Sends message for event enable/disable status change.
67
+ * @param postis {Postis object} the postis instance that is going to be used.
68
+ * @param event {string} the name of the event
69
+ * @param status {boolean} true - enabled; false - disabled;
70
+ */
71
+function changeEventStatus(postis, event, status) {
72
+    if(!(event in events)) {
73
+        console.error("Not supported event name.");
74
+        return;
75
+    }
76
+    sendMessage(postis, {
77
+        method: "jitsiSystemMessage",
78
+        params: {type: "eventStatus", name: events[event], value: status}
79
+    });
80
+}
81
+
82
+/**
83
+ * Constructs new API instance. Creates iframe element that loads
84
+ * Jitsi Meet.
85
+ * @param domain the domain name of the server that hosts the conference
86
+ * @param room_name the name of the room to join
87
+ * @param width width of the iframe
88
+ * @param height height of the iframe
89
+ * @param parent_node the node that will contain the iframe
90
+ * @param filmStripOnly if the value is true only the small videos will be
91
+ * visible.
92
+ * @param noSsl if the value is true https won't be used
93
+ * @constructor
94
+ */
95
+function JitsiMeetExternalAPI(domain, room_name, width, height, parentNode,
96
+    configOverwrite, interfaceConfigOverwrite, noSsl) {
97
+    if (!width || width < MIN_WIDTH)
98
+        width = MIN_WIDTH;
99
+    if (!height || height < MIN_HEIGHT)
100
+        height = MIN_HEIGHT;
101
+
102
+    this.parentNode = null;
103
+    if (parentNode) {
104
+        this.parentNode = parentNode;
105
+    } else {
106
+        var scriptTag = document.scripts[document.scripts.length - 1];
107
+        this.parentNode = scriptTag.parentNode;
108
+    }
109
+
110
+    this.iframeHolder =
111
+        this.parentNode.appendChild(document.createElement("div"));
112
+    this.iframeHolder.id = "jitsiConference" + id;
113
+    if(width)
114
+        this.iframeHolder.style.width = width + "px";
115
+    if(height)
116
+        this.iframeHolder.style.height = height + "px";
117
+    this.frameName = "jitsiConferenceFrame" + id;
118
+    this.url = (noSsl) ? "http" : "https" +"://" + domain + "/";
119
+    if(room_name)
120
+        this.url += room_name;
121
+    this.url += "#jitsi_meet_external_api_id=" + id;
122
+
123
+    var key;
124
+    if (configOverwrite) {
125
+        for (key in configOverwrite) {
126
+            if (!configOverwrite.hasOwnProperty(key) ||
127
+                typeof key !== 'string')
128
+                continue;
129
+            this.url += "&config." + key + "=" + configOverwrite[key];
130
+        }
131
+    }
132
+
133
+    if (interfaceConfigOverwrite) {
134
+        for (key in interfaceConfigOverwrite) {
135
+            if (!interfaceConfigOverwrite.hasOwnProperty(key) ||
136
+                typeof key !== 'string')
137
+                continue;
138
+            this.url += "&interfaceConfig." + key + "=" +
139
+                interfaceConfigOverwrite[key];
140
+        }
141
+    }
142
+
143
+    this.frame = document.createElement("iframe");
144
+    this.frame.src = this.url;
145
+    this.frame.name = this.frameName;
146
+    this.frame.id = this.frameName;
147
+    this.frame.width = "100%";
148
+    this.frame.height = "100%";
149
+    this.frame.setAttribute("allowFullScreen","true");
150
+    this.frame = this.iframeHolder.appendChild(this.frame);
151
+    this.postis = postisInit({
152
+        window: this.frame.contentWindow,
153
+        scope: "jitsi_meet_external_api_" + id
154
+    });
155
+
156
+    this.eventHandlers = {};
157
+
158
+    id++;
159
+}
160
+
161
+/**
162
+ * Executes command. The available commands are:
163
+ * displayName - sets the display name of the local participant to the value
164
+ * passed in the arguments array.
165
+ * toggleAudio - mutes / unmutes audio with no arguments
166
+ * toggleVideo - mutes / unmutes video with no arguments
167
+ * filmStrip - hides / shows the film strip with no arguments
168
+ * If the command doesn't require any arguments the parameter should be set
169
+ * to empty array or it may be omitted.
170
+ * @param name the name of the command
171
+ * @param arguments array of arguments
172
+ */
173
+JitsiMeetExternalAPI.prototype.executeCommand = function(name, argumentsList) {
174
+    if(!(name in commands)) {
175
+        console.error("Not supported command name.");
176
+        return;
177
+    }
178
+    var argumentsArray = argumentsList;
179
+    if (!argumentsArray)
180
+        argumentsArray = [];
181
+    sendMessage(this.postis, {method: commands[name], params: argumentsArray});
182
+};
183
+
184
+/**
185
+ * Executes commands. The available commands are:
186
+ * displayName - sets the display name of the local participant to the value
187
+ * passed in the arguments array.
188
+ * toggleAudio - mutes / unmutes audio. no arguments
189
+ * toggleVideo - mutes / unmutes video. no arguments
190
+ * filmStrip - hides / shows the film strip. no arguments
191
+ * toggleChat - hides / shows chat. no arguments.
192
+ * toggleContactList - hides / shows contact list. no arguments.
193
+ * toggleShareScreen - starts / stops screen sharing. no arguments.
194
+ * @param object the object with commands to be executed. The keys of the
195
+ * object are the commands that will be executed and the values are the
196
+ * arguments for the command.
197
+ */
198
+JitsiMeetExternalAPI.prototype.executeCommands = function(object) {
199
+    for(var key in object)
200
+        this.executeCommand(key, object[key]);
201
+};
202
+
203
+/**
204
+ * Adds event listeners to Meet Jitsi. The object key should be the name of
205
+ * the event and value - the listener.
206
+ * Currently we support the following
207
+ * events:
208
+ * incomingMessage - receives event notifications about incoming
209
+ * messages. The listener will receive object with the following structure:
210
+ * {{
211
+ *  "from": from,//JID of the user that sent the message
212
+ *  "nick": nick,//the nickname of the user that sent the message
213
+ *  "message": txt//the text of the message
214
+ * }}
215
+ * outgoingMessage - receives event notifications about outgoing
216
+ * messages. The listener will receive object with the following structure:
217
+ * {{
218
+ *  "message": txt//the text of the message
219
+ * }}
220
+ * displayNameChanged - receives event notifications about display name
221
+ * change. The listener will receive object with the following structure:
222
+ * {{
223
+ * jid: jid,//the JID of the participant that changed his display name
224
+ * displayname: displayName //the new display name
225
+ * }}
226
+ * participantJoined - receives event notifications about new participant.
227
+ * The listener will receive object with the following structure:
228
+ * {{
229
+ * jid: jid //the jid of the participant
230
+ * }}
231
+ * participantLeft - receives event notifications about the participant that
232
+ * left the room.
233
+ * The listener will receive object with the following structure:
234
+ * {{
235
+ * jid: jid //the jid of the participant
236
+ * }}
237
+ * video-conference-joined - receives event notifications about the local user
238
+ * has successfully joined the video conference.
239
+ * The listener will receive object with the following structure:
240
+ * {{
241
+ * roomName: room //the room name of the conference
242
+ * }}
243
+ * video-conference-left - receives event notifications about the local user
244
+ * has left the video conference.
245
+ * The listener will receive object with the following structure:
246
+ * {{
247
+ * roomName: room //the room name of the conference
248
+ * }}
249
+ * @param object
250
+ */
251
+JitsiMeetExternalAPI.prototype.addEventListeners = function(object) {
252
+    for(var i in object)
253
+        this.addEventListener(i, object[i]);
254
+};
255
+
256
+/**
257
+ * Adds event listeners to Meet Jitsi. Currently we support the following
258
+ * events:
259
+ * incomingMessage - receives event notifications about incoming
260
+ * messages. The listener will receive object with the following structure:
261
+ * {{
262
+ *  "from": from,//JID of the user that sent the message
263
+ *  "nick": nick,//the nickname of the user that sent the message
264
+ *  "message": txt//the text of the message
265
+ * }}
266
+ * outgoingMessage - receives event notifications about outgoing
267
+ * messages. The listener will receive object with the following structure:
268
+ * {{
269
+ *  "message": txt//the text of the message
270
+ * }}
271
+ * displayNameChanged - receives event notifications about display name
272
+ * change. The listener will receive object with the following structure:
273
+ * {{
274
+ * jid: jid,//the JID of the participant that changed his display name
275
+ * displayname: displayName //the new display name
276
+ * }}
277
+ * participantJoined - receives event notifications about new participant.
278
+ * The listener will receive object with the following structure:
279
+ * {{
280
+ * jid: jid //the jid of the participant
281
+ * }}
282
+ * participantLeft - receives event notifications about participant the that
283
+ * left the room.
284
+ * The listener will receive object with the following structure:
285
+ * {{
286
+ * jid: jid //the jid of the participant
287
+ * }}
288
+ * video-conference-joined - receives event notifications fired when the local
289
+ * user has joined the video conference.
290
+ * The listener will receive object with the following structure:
291
+ * {{
292
+ * roomName: room //the room name of the conference
293
+ * }}
294
+ * video-conference-left - receives event notifications fired when the local
295
+ * user has joined the video conference.
296
+ * The listener will receive object with the following structure:
297
+ * {{
298
+ * roomName: room //the room name of the conference
299
+ * }}
300
+ * @param event the name of the event
301
+ * @param listener the listener
302
+ */
303
+JitsiMeetExternalAPI.prototype.addEventListener = function(event, listener) {
304
+    if(!(event in events)) {
305
+        console.error("Not supported event name.");
306
+        return;
307
+    }
308
+    // We cannot remove listeners from postis that's why we are handling the
309
+    // callback that way.
310
+    if(!(event in this.eventHandlers))
311
+        this.postis.listen(events[event], function(data) {
312
+            if((event in this.eventHandlers) &&
313
+                typeof this.eventHandlers[event] === "function")
314
+                this.eventHandlers[event].call(null, data);
315
+        }.bind(this));
316
+    this.eventHandlers[event] = listener;
317
+    changeEventStatus(this.postis, event, true);
318
+};
319
+
320
+/**
321
+ * Removes event listener.
322
+ * @param event the name of the event.
323
+ */
324
+JitsiMeetExternalAPI.prototype.removeEventListener = function(event) {
325
+    if(!(event in this.eventHandlers))
326
+    {
327
+        console.error("The event " + event + " is not registered.");
328
+        return;
329
+    }
330
+    delete this.eventHandlers[event];
331
+    changeEventStatus(this.postis, event, false);
332
+};
333
+
334
+/**
335
+ * Removes event listeners.
336
+ * @param events array with the names of the events.
337
+ */
338
+JitsiMeetExternalAPI.prototype.removeEventListeners = function(events) {
339
+    var eventsArray = [];
340
+    for(var i = 0; i < events.length; i++)
341
+        this.removeEventListener(events[i]);
342
+};
343
+
344
+/**
345
+ * Removes the listeners and removes the Jitsi Meet frame.
346
+ */
347
+JitsiMeetExternalAPI.prototype.dispose = function() {
348
+    this.postis.dispose();
349
+    var frame = document.getElementById(this.frameName);
350
+    if(frame)
351
+        frame.src = 'about:blank';
352
+    var self = this;
353
+    window.setTimeout(function () {
354
+        self.iframeHolder.removeChild(self.frame);
355
+        self.iframeHolder.parentNode.removeChild(self.iframeHolder);
356
+    }, 10);
357
+};
358
+
359
+module.exports = JitsiMeetExternalAPI;

+ 2
- 1
modules/TokenData/TokenData.js View File

72
 
72
 
73
         //External API settings
73
         //External API settings
74
         this.externalAPISettings = {
74
         this.externalAPISettings = {
75
-            enablePostis: true
75
+            forceEnable: true,
76
+            enabledEvents: ["video-conference-joined", "video-conference-left"]
76
         };
77
         };
77
         this._decode();
78
         this._decode();
78
         // Use JWT param as token if there is not other token set and if the
79
         // Use JWT param as token if there is not other token set and if the

Loading…
Cancel
Save