Просмотр исходного кода

Adds a message handler and messages to the user including when the video bridge is not available.

j8
fo 10 лет назад
Родитель
Сommit
bb45d72737
9 измененных файлов: 406 добавлений и 283 удалений
  1. 102
    83
      app.js
  2. 7
    0
      desktopsharing.js
  3. 8
    7
      index.html
  4. 4
    3
      libs/colibri/colibri.focus.js
  5. 87
    0
      message_handler.js
  6. 3
    0
      moderatemuc.js
  7. 25
    3
      muc.js
  8. 67
    75
      prezi.js
  9. 103
    112
      toolbar.js

+ 102
- 83
app.js Просмотреть файл

@@ -12,6 +12,7 @@ var roomUrl = null;
12 12
 var roomName = null;
13 13
 var ssrc2jid = {};
14 14
 var mediaStreams = [];
15
+var bridgeIsDown = false;
15 16
 
16 17
 /**
17 18
  * The stats collector that process stats data and triggers updates to app.js.
@@ -41,7 +42,6 @@ var mutedAudios = {};
41 42
 var localVideoSrc = null;
42 43
 var flipXLocalVideo = true;
43 44
 var isFullScreen = false;
44
-var toolbarTimeout = null;
45 45
 var currentVideoWidth = null;
46 46
 var currentVideoHeight = null;
47 47
 /**
@@ -171,6 +171,9 @@ function obtainAudioAndVideoPermissions(callback) {
171 171
                 media: error.media || 'video',
172 172
                 name : error.name
173 173
             });
174
+            messageHandler.showError("Error",
175
+                "Failed to obtain permissions to use the local microphone" +
176
+                    "and/or camera.");
174 177
         },
175 178
         config.resolution || '360');
176 179
 }
@@ -239,6 +242,8 @@ function doJoin() {
239 242
 function waitForRemoteVideo(selector, ssrc, stream) {
240 243
     if (selector.removed || !selector.parent().is(":visible")) {
241 244
         console.warn("Media removed before had started", selector);
245
+        messageHandler.showError("Warning",
246
+            "Media was removed before it had started.");
242 247
         return;
243 248
     }
244 249
 
@@ -255,6 +260,7 @@ function waitForRemoteVideo(selector, ssrc, stream) {
255 260
             videoSrcToSsrc[selector.attr('src')] = ssrc;
256 261
         } else {
257 262
             console.warn("No ssrc given for video", selector);
263
+            messageHandler.showError('Warning', 'No ssrc was given for the video.');
258 264
         }
259 265
 
260 266
         $(document).trigger('videoactive.jingle', [selector]);
@@ -327,9 +333,11 @@ function waitForPresence(data, sid) {
327 333
                 'participant_' + Strophe.getResourceFromJid(data.peerjid));
328 334
     } else {
329 335
         if (data.stream.id !== 'mixedmslabel') {
330
-            console.error(  'can not associate stream',
331
-                            data.stream.id,
332
-                            'with a participant');
336
+            console.error('can not associate stream',
337
+                data.stream.id,
338
+                'with a participant');
339
+            messageHandler.showError('Oops',
340
+                'We could not associate the current stream with a participant.');
333 341
             // We don't want to add it here since it will cause troubles
334 342
             return;
335 343
         }
@@ -398,16 +406,19 @@ function sendKeyframe(pc) {
398 406
                         },
399 407
                         function (error) {
400 408
                             console.log('triggerKeyframe setLocalDescription failed', error);
409
+                            messageHandler.showError();
401 410
                         }
402 411
                     );
403 412
                 },
404 413
                 function (error) {
405 414
                     console.log('triggerKeyframe createAnswer failed', error);
415
+                    messageHandler.showError();
406 416
                 }
407 417
             );
408 418
         },
409 419
         function (error) {
410 420
             console.log('triggerKeyframe setRemoteDescription failed', error);
421
+            messageHandler.showError();
411 422
         }
412 423
     );
413 424
 }
@@ -435,16 +446,24 @@ function muteVideo(pc, unmute) {
435 446
                         },
436 447
                         function (error) {
437 448
                             console.log('mute SLD error');
449
+                            messageHandler.showError('Error',
450
+                                'Oops! Something went wrong and we failed to ' +
451
+                                    'mute! (SLD Failure)');
438 452
                         }
439 453
                     );
440 454
                 },
441 455
                 function (error) {
442 456
                     console.log(error);
457
+                    messageHandler.showError();
443 458
                 }
444 459
             );
445 460
         },
446 461
         function (error) {
447 462
             console.log('muteVideo SRD error');
463
+            messageHandler.showError('Error',
464
+                'Oops! Something went wrong and we failed to stop video!' +
465
+                    '(SRD Failure)');
466
+
448 467
         }
449 468
     );
450 469
 }
@@ -563,7 +582,7 @@ $(document).bind('callterminated.jingle', function (event, sid, jid, reason) {
563 582
     if (connection.emuc.joined && focus == null && reason === 'kick') {
564 583
         sessionTerminated = true;
565 584
         connection.emuc.doLeave();
566
-        openMessageDialog(  "Session Terminated",
585
+        messageHandler.openMessageDialog("Session Terminated",
567 586
                             "Ouch! You have been kicked out of the meet!");
568 587
     }
569 588
 });
@@ -687,7 +706,13 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
687 706
         // FIXME: this should prepare the video
688 707
         if (focus.confid === null) {
689 708
             console.log('make new conference with', jid);
690
-            focus.makeConference(Object.keys(connection.emuc.members));
709
+            focus.makeConference(Object.keys(connection.emuc.members),
710
+                function(error) {
711
+                    bridgeIsDown = true;
712
+                    connection.emuc.addBridgeIsDownToPresence();
713
+                    connection.emuc.sendPresence();
714
+                }
715
+            );
691 716
             Toolbar.showRecordingButton(true);
692 717
         } else {
693 718
             console.log('invite', jid, 'into conference');
@@ -809,6 +834,14 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
809 834
     if (focus !== null && info.displayName !== null) {
810 835
         focus.setEndpointDisplayName(jid, info.displayName);
811 836
     }
837
+
838
+    //check if the video bridge is available
839
+    if($(pres).find(">bridgeIsDown").length > 0 && !bridgeIsDown) {
840
+        bridgeIsDown = true;
841
+        messageHandler.showError("Error",
842
+            "The video bridge is currently unavailable.");
843
+    }
844
+
812 845
 });
813 846
 
814 847
 $(document).bind('presence.status.muc', function (event, jid, info, pres) {
@@ -821,40 +854,36 @@ $(document).bind('presence.status.muc', function (event, jid, info, pres) {
821 854
 $(document).bind('passwordrequired.muc', function (event, jid) {
822 855
     console.log('on password required', jid);
823 856
 
824
-    $.prompt('<h2>Password required</h2>' +
825
-        '<input id="lockKey" type="text" placeholder="shared key" autofocus>', {
826
-        persistent: true,
827
-        buttons: { "Ok": true, "Cancel": false},
828
-        defaultButton: 1,
829
-        loaded: function (event) {
830
-            document.getElementById('lockKey').focus();
831
-        },
832
-        submit: function (e, v, m, f) {
857
+    messageHandler.openTwoButtonDialog(null,
858
+        '<h2>Password required</h2>' +
859
+        '<input id="lockKey" type="text" placeholder="shared key" autofocus>',
860
+        true,
861
+        "Ok",
862
+        function (e, v, m, f) {
833 863
             if (v) {
834 864
                 var lockKey = document.getElementById('lockKey');
835
-
836 865
                 if (lockKey.value !== null) {
837 866
                     setSharedKey(lockKey.value);
838 867
                     connection.emuc.doJoin(jid, lockKey.value);
839 868
                 }
840 869
             }
870
+        },
871
+        function (event) {
872
+            document.getElementById('lockKey').focus();
841 873
         }
842
-    });
874
+    );
843 875
 });
844 876
 
845 877
 $(document).bind('passwordrequired.main', function (event) {
846 878
     console.log('password is required');
847 879
 
848
-    $.prompt('<h2>Password required</h2>' +
849
-        '<input id="passwordrequired.username" type="text" placeholder="user@domain.net" autofocus>' +
850
-        '<input id="passwordrequired.password" type="password" placeholder="user password">', {
851
-        persistent: true,
852
-        buttons: { "Ok": true, "Cancel": false},
853
-        defaultButton: 1,
854
-        loaded: function (event) {
855
-            document.getElementById('passwordrequired.username').focus();
856
-        },
857
-        submit: function (e, v, m, f) {
880
+    messageHandler.openTwoButtonDialog(null,
881
+        '<h2>Password required</h2>' +
882
+            '<input id="passwordrequired.username" type="text" placeholder="user@domain.net" autofocus>' +
883
+            '<input id="passwordrequired.password" type="password" placeholder="user password">',
884
+        true,
885
+        "Ok",
886
+        function (e, v, m, f) {
858 887
             if (v) {
859 888
                 var username = document.getElementById('passwordrequired.username');
860 889
                 var password = document.getElementById('passwordrequired.password');
@@ -863,8 +892,11 @@ $(document).bind('passwordrequired.main', function (event) {
863 892
                     connect(username.value, password.value);
864 893
                 }
865 894
             }
895
+        },
896
+        function (event) {
897
+            document.getElementById('passwordrequired.username').focus();
866 898
         }
867
-    });
899
+    );
868 900
 });
869 901
 
870 902
 /**
@@ -981,25 +1013,23 @@ function toggleRecording() {
981 1013
 
982 1014
     if (!recordingToken)
983 1015
     {
984
-        $.prompt('<h2>Enter recording token</h2>' +
1016
+        messageHandler.openTwoButtonDialog(null,
1017
+            '<h2>Enter recording token</h2>' +
985 1018
                 '<input id="recordingToken" type="text" placeholder="token" autofocus>',
986
-            {
987
-                persistent: false,
988
-                buttons: { "Save": true, "Cancel": false},
989
-                defaultButton: 1,
990
-                loaded: function (event) {
991
-                    document.getElementById('recordingToken').focus();
992
-                },
993
-                submit: function (e, v, m, f) {
994
-                    if (v) {
995
-                        var token = document.getElementById('recordingToken');
996
-
997
-                        if (token.value) {
998
-                            setRecordingToken(Util.escapeHtml(token.value));
999
-                            toggleRecording();
1000
-                        }
1019
+            false,
1020
+            "Save",
1021
+            function (e, v, m, f) {
1022
+                if (v) {
1023
+                    var token = document.getElementById('recordingToken');
1024
+
1025
+                    if (token.value) {
1026
+                        setRecordingToken(Util.escapeHtml(token.value));
1027
+                        toggleRecording();
1001 1028
                     }
1002 1029
                 }
1030
+            },
1031
+            function (event) {
1032
+                document.getElementById('recordingToken').focus();
1003 1033
             }
1004 1034
         );
1005 1035
 
@@ -1259,6 +1289,16 @@ function dump(elem, filename) {
1259 1289
     elem = elem.parentNode;
1260 1290
     elem.download = filename || 'meetlog.json';
1261 1291
     elem.href = 'data:application/json;charset=utf-8,\n';
1292
+    var data = populateData();
1293
+    elem.href += encodeURIComponent(JSON.stringify(data, null, '  '));
1294
+    return false;
1295
+}
1296
+
1297
+
1298
+/**
1299
+ * Populates the log data
1300
+ */
1301
+function populateData() {
1262 1302
     var data = {};
1263 1303
     if (connection.jingle) {
1264 1304
         Object.keys(connection.jingle.sessions).forEach(function (sid) {
@@ -1273,7 +1313,7 @@ function dump(elem, filename) {
1273 1313
             }
1274 1314
         });
1275 1315
     }
1276
-    metadata = {};
1316
+    var metadata = {};
1277 1317
     metadata.time = new Date();
1278 1318
     metadata.url = window.location.href;
1279 1319
     metadata.ua = navigator.userAgent;
@@ -1281,8 +1321,7 @@ function dump(elem, filename) {
1281 1321
         metadata.xmpp = connection.logger.log;
1282 1322
     }
1283 1323
     data.metadata = metadata;
1284
-    elem.href += encodeURIComponent(JSON.stringify(data, null, '  '));
1285
-    return false;
1324
+    return data;
1286 1325
 }
1287 1326
 
1288 1327
 /**
@@ -1292,21 +1331,6 @@ function buttonClick(id, classname) {
1292 1331
     $(id).toggleClass(classname); // add the class to the clicked element
1293 1332
 }
1294 1333
 
1295
-/**
1296
- * Shows a message to the user.
1297
- *
1298
- * @param titleString the title of the message
1299
- * @param messageString the text of the message
1300
- */
1301
-function openMessageDialog(titleString, messageString) {
1302
-    $.prompt(messageString,
1303
-        {
1304
-            title: titleString,
1305
-            persistent: false
1306
-        }
1307
-    );
1308
-}
1309
-
1310 1334
 /**
1311 1335
  * Locks / unlocks the room.
1312 1336
  */
@@ -1417,7 +1441,7 @@ $(document).bind('fatalError.jingle',
1417 1441
     {
1418 1442
         sessionTerminated = true;
1419 1443
         connection.emuc.doLeave();
1420
-        openMessageDialog(  "Sorry",
1444
+        messageHandler.showError(  "Sorry",
1421 1445
             "Your browser version is too old. Please update and try again...");
1422 1446
     }
1423 1447
 );
@@ -1435,28 +1459,23 @@ $(document).bind("video.selected", function(event, isPresentation, userJid) {
1435 1459
 
1436 1460
 function callSipButtonClicked()
1437 1461
 {
1438
-    $.prompt('<h2>Enter SIP number</h2>' +
1439
-        '<input id="sipNumber" type="text" value="" autofocus>',
1440
-        {
1441
-            persistent: false,
1442
-            buttons: { "Dial": true, "Cancel": false},
1443
-            defaultButton: 2,
1444
-            loaded: function (event)
1445
-            {
1446
-                document.getElementById('sipNumber').focus();
1447
-            },
1448
-            submit: function (e, v, m, f)
1449
-            {
1450
-                if (v)
1451
-                {
1452
-                    var numberInput = document.getElementById('sipNumber');
1453
-                    if (numberInput.value && numberInput.value.length)
1454
-                    {
1455
-                        connection.rayo.dial(
1456
-                            numberInput.value, 'fromnumber', roomName);
1457
-                    }
1462
+    messageHandler.openTwoButtonDialog(null,
1463
+        '<h2>Enter SIP number</h2>' +
1464
+            '<input id="sipNumber" type="text"' +
1465
+            ' value="' + config.defaultSipNumber + '" autofocus>',
1466
+        false,
1467
+        "Dial",
1468
+        function (e, v, m, f) {
1469
+            if (v) {
1470
+                var numberInput = document.getElementById('sipNumber');
1471
+                if (numberInput.value) {
1472
+                    connection.rayo.dial(
1473
+                        numberInput.value, 'fromnumber', roomName);
1458 1474
                 }
1459 1475
             }
1476
+        },
1477
+        function (event) {
1478
+            document.getElementById('sipNumber').focus();
1460 1479
         }
1461 1480
     );
1462 1481
 }

+ 7
- 0
desktopsharing.js Просмотреть файл

@@ -86,6 +86,8 @@ function isUpdateRequired(minVersion, extVersion)
86 86
     catch (e)
87 87
     {
88 88
         console.error("Failed to parse extension version", e);
89
+        messageHandler.showError('Error',
90
+            'Error when trying to detect desktopsharing extension.');
89 91
         return true;
90 92
     }
91 93
 }
@@ -166,6 +168,8 @@ function obtainScreenFromExtension(streamCallback, failCallback) {
166 168
                     function (arg) {
167 169
                         console.log("Failed to install the extension", arg);
168 170
                         failCallback(arg);
171
+                        messageHandler.showError('Error',
172
+                            'Failed to install desktop sharing extension');
169 173
                     }
170 174
                 );
171 175
             }
@@ -236,6 +240,7 @@ function initInlineInstalls()
236 240
 
237 241
 function getSwitchStreamFailed(error) {
238 242
     console.error("Failed to obtain the stream to switch to", error);
243
+    messageHandler.showError('Error', 'Failed to get video stream');
239 244
     switchInProgress = false;
240 245
 }
241 246
 
@@ -262,6 +267,8 @@ function newStreamCreated(stream) {
262 267
     } else {
263 268
         // We are done immediately
264 269
         console.error("No conference handler");
270
+        messageHandler.showError('Error',
271
+            'Unable to switch video stream.');
265 272
         streamSwitchDone();
266 273
     }
267 274
 }

+ 8
- 7
index.html Просмотреть файл

@@ -19,7 +19,7 @@
19 19
     <script src="libs/strophe/strophe.jingle.sessionbase.js?v=1"></script>
20 20
     <script src="libs/strophe/strophe.jingle.session.js?v=1"></script>
21 21
     <script src="libs/strophe/strophe.util.js"></script>
22
-    <script src="libs/colibri/colibri.focus.js?v=8"></script><!-- colibri focus implementation -->
22
+    <script src="libs/colibri/colibri.focus.js?v=9"></script><!-- colibri focus implementation -->
23 23
     <script src="libs/colibri/colibri.session.js?v=1"></script>
24 24
     <script src="libs/jquery-ui.js"></script>
25 25
     <script src="libs/rayo.js?v=1"></script>
@@ -27,25 +27,25 @@
27 27
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
28 28
     <script src="config.js?v=5"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
29 29
     <script src="brand.js?v=1"></script>
30
-    <script src="muc.js?v=13"></script><!-- simple MUC library -->
30
+    <script src="muc.js?v=14"></script><!-- simple MUC library -->
31 31
     <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
32
-    <script src="desktopsharing.js?v=2"></script><!-- desktop sharing -->
32
+    <script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
33 33
     <script src="data_channels.js?v=3"></script><!-- data channels -->
34
-    <script src="app.js?v=9"></script><!-- application logic -->
34
+    <script src="app.js?v=10"></script><!-- application logic -->
35 35
     <script src="commands.js?v=1"></script><!-- application logic -->
36 36
     <script src="chat.js?v=10"></script><!-- chat logic -->
37 37
     <script src="contact_list.js?v=2"></script><!-- contact list logic -->
38 38
     <script src="util.js?v=6"></script><!-- utility functions -->
39 39
     <script src="etherpad.js?v=9"></script><!-- etherpad plugin -->
40
-    <script src="prezi.js?v=5"></script><!-- prezi plugin -->
40
+    <script src="prezi.js?v=6"></script><!-- prezi plugin -->
41 41
     <script src="smileys.js?v=2"></script><!-- smiley images -->
42 42
     <script src="replacement.js?v=6"></script><!-- link and smiley replacement -->
43
-    <script src="moderatemuc.js?v=3"></script><!-- moderator plugin -->
43
+    <script src="moderatemuc.js?v=4"></script><!-- moderator plugin -->
44 44
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
45 45
     <script src="rtp_sts.js?v=1"></script><!-- RTP stats processing -->
46 46
     <script src="local_sts.js?v=1"></script><!-- Local stats processing -->
47 47
     <script src="videolayout.js?v=9"></script><!-- video ui -->
48
-    <script src="toolbar.js?v=5"></script><!-- toolbar ui -->
48
+    <script src="toolbar.js?v=6"></script><!-- toolbar ui -->
49 49
     <script src="toolbar_toggler.js?v=1"></script>
50 50
     <script src="canvas_util.js?v=1"></script><!-- canvas drawing utils -->
51 51
     <script src="audio_levels.js?v=1"></script><!-- audio levels plugin -->
@@ -54,6 +54,7 @@
54 54
     <script src="roomname_generator.js?v=1"></script><!-- generator for random room names -->
55 55
     <script src="keyboard_shortcut.js?v=2"></script>
56 56
     <script src="tracking.js?v=1"></script><!-- tracking -->
57
+    <script src="message_handler.js?v=1"></script>
57 58
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
58 59
     <link rel="stylesheet" href="css/font.css?v=4"/>
59 60
     <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=23"/>

+ 4
- 3
libs/colibri/colibri.focus.js Просмотреть файл

@@ -93,7 +93,7 @@ function ColibriFocus(connection, bridgejid) {
93 93
 }
94 94
 
95 95
 // creates a conferences with an initial set of peers
96
-ColibriFocus.prototype.makeConference = function (peers) {
96
+ColibriFocus.prototype.makeConference = function (peers, errorCallback) {
97 97
     var self = this;
98 98
     if (this.confid !== null) {
99 99
         console.error('makeConference called twice? Ignoring...');
@@ -155,7 +155,7 @@ ColibriFocus.prototype.makeConference = function (peers) {
155 155
         }
156 156
         self.sendIceCandidate(event.candidate);
157 157
     };
158
-    this._makeConference();
158
+    this._makeConference(errorCallback);
159 159
     /*
160 160
     this.peerconnection.createOffer(
161 161
         function (offer) {
@@ -275,7 +275,7 @@ ColibriFocus.prototype.updateEndpoints = function() {
275 275
     );
276 276
 };
277 277
 
278
-ColibriFocus.prototype._makeConference = function () {
278
+ColibriFocus.prototype._makeConference = function (errorCallback) {
279 279
     var self = this;
280 280
     var elem = $iq({ to: this.bridgejid, type: 'get' });
281 281
     elem.c('conference', { xmlns: 'http://jitsi.org/protocol/colibri' });
@@ -360,6 +360,7 @@ ColibriFocus.prototype._makeConference = function () {
360 360
         },
361 361
         function (error) {
362 362
             console.warn(error);
363
+            errorCallback(error);
363 364
         }
364 365
     );
365 366
 };

+ 87
- 0
message_handler.js Просмотреть файл

@@ -0,0 +1,87 @@
1
+var messageHandler = (function(my) {
2
+
3
+    /**
4
+     * Shows a message to the user.
5
+     *
6
+     * @param titleString the title of the message
7
+     * @param messageString the text of the message
8
+     */
9
+    my.openMessageDialog = function(titleString, messageString) {
10
+        $.prompt(messageString,
11
+            {
12
+                title: titleString,
13
+                persistent: false
14
+            }
15
+        );
16
+    };
17
+
18
+    /**
19
+     * Shows a message to the user with two buttons: first is given as a parameter and the second is Cancel.
20
+     *
21
+     * @param titleString the title of the message
22
+     * @param msgString the text of the message
23
+     * @param persistent boolean value which determines whether the message is persistent or not
24
+     * @param leftButton the fist button's text
25
+     * @param submitFunction function to be called on submit
26
+     * @param loadedFunction function to be called after the prompt is fully loaded
27
+     */
28
+    my.openTwoButtonDialog = function(titleString, msgString, persistent, leftButton, submitFunction, loadedFunction) {
29
+        var buttons = {};
30
+        buttons[leftButton] = true;
31
+        buttons.Cancel = false;
32
+        $.prompt(msgString, {
33
+            title: titleString,
34
+            persistent: false,
35
+            buttons: buttons,
36
+            defaultButton: 1,
37
+            loaded: loadedFunction,
38
+            submit: submitFunction
39
+        });
40
+    };
41
+
42
+    /**
43
+     * Shows a dialog with different states to the user.
44
+     *
45
+     * @param statesObject object containing all the states of the dialog
46
+     * @param loadedFunction function to be called after the prompt is fully loaded
47
+     * @param stateChangedFunction function to be called when the state of the dialog is changed
48
+     */
49
+    my.openDialogWithStates = function(statesObject, loadedFunction, stateChangedFunction) {
50
+
51
+
52
+        var myPrompt = $.prompt(statesObject);
53
+
54
+        myPrompt.on('impromptu:loaded', loadedFunction);
55
+        myPrompt.on('impromptu:statechanged', stateChangedFunction);
56
+    };
57
+
58
+    /**
59
+     * Shows a dialog prompting the user to send an error report.
60
+     *
61
+     * @param titleString the title of the message
62
+     * @param msgString the text of the message
63
+     * @param error the error that is being reported
64
+     */
65
+    my.openReportDialog = function(titleString, msgString, error) {
66
+        my.openMessageDialog(titleString, msgString);
67
+        console.log(error);
68
+        //FIXME send the error to the server
69
+    };
70
+
71
+    /**
72
+     *  Shows an error dialog to the user.
73
+     * @param title the title of the message
74
+     * @param message the text of the messafe
75
+     */
76
+    my.showError = function(title, message) {
77
+        if(!(title || message)) {
78
+            title = title || "Oops!";
79
+            message = message || "There was some kind of error";
80
+        }
81
+        messageHandler.openMessageDialog(title, message);
82
+    };
83
+
84
+    return my;
85
+}(messageHandler || {}));
86
+
87
+

+ 3
- 0
moderatemuc.js Просмотреть файл

@@ -34,6 +34,9 @@ Strophe.addConnectionPlugin('moderate', {
34 34
                 },
35 35
                 function (error) {
36 36
                     console.log('set mute error', error);
37
+                    messageHandler.openReportDialog(null, 'Failed to mute ' +
38
+                        $("#participant_" + jid).find(".displayname").text() ||
39
+                        "participant" + '.', error);
37 40
                 });
38 41
     },
39 42
     onMute: function(iq) {

+ 25
- 3
muc.js Просмотреть файл

@@ -170,12 +170,17 @@ Strophe.addConnectionPlugin('emuc', {
170 170
                 // we are connected with anonymous domain and only non anonymous users can create rooms
171 171
                 // we must authorize the user
172 172
                 $(document).trigger('passwordrequired.main');
173
-            }
174
-            else
173
+            } else {
175 174
                 console.warn('onPresError ', pres);
176
-
175
+                messageHandler.openReportDialog(null,
176
+                    'Oops! Something went wrong and we couldn`t connect to the conference.',
177
+                pres);
178
+            }
177 179
         } else {
178 180
             console.warn('onPresError ', pres);
181
+            messageHandler.openReportDialog(null,
182
+                'Oops! Something went wrong and we couldn`t connect to the conference.',
183
+                pres);
179 184
         }
180 185
         return true;
181 186
     },
@@ -241,14 +246,23 @@ Strophe.addConnectionPlugin('emuc', {
241 246
                         },
242 247
                         function (err) {
243 248
                             console.warn('setting password failed', err);
249
+                            messageHandler.showError('Lock failed',
250
+                                'Failed to lock conference.',
251
+                                err);
244 252
                         }
245 253
                     );
246 254
                 } else {
247 255
                     console.warn('room passwords not supported');
256
+                    messageHandler.showError('Warning',
257
+                        'Room passwords are currently not supported.');
258
+
248 259
                 }
249 260
             },
250 261
             function (err) {
251 262
                 console.warn('setting password failed', err);
263
+                messageHandler.showError('Lock failed',
264
+                    'Failed to lock conference.',
265
+                    err);
252 266
             }
253 267
         );
254 268
     },
@@ -277,6 +291,10 @@ Strophe.addConnectionPlugin('emuc', {
277 291
 
278 292
         pres.up();
279 293
 
294
+        if(this.presMap['bridgeIsDown']) {
295
+            pres.c('bridgeIsDown').up();
296
+        }
297
+
280 298
         if (this.presMap['displayName']) {
281 299
             // XEP-0172
282 300
             pres.c('nick', {xmlns: 'http://jabber.org/protocol/nick'})
@@ -324,6 +342,7 @@ Strophe.addConnectionPlugin('emuc', {
324 342
                     ).up();
325 343
                 }
326 344
         }
345
+
327 346
         pres.up();
328 347
         connection.send(pres);
329 348
     },
@@ -381,5 +400,8 @@ Strophe.addConnectionPlugin('emuc', {
381 400
             return Strophe.getResourceFromJid(jid) === resourceJid;
382 401
         });
383 402
         return peerJid;
403
+    },
404
+    addBridgeIsDownToPresence: function() {
405
+        this.presMap['bridgeIsDown'] = true;
384 406
     }
385 407
 });

+ 67
- 75
prezi.js Просмотреть файл

@@ -56,104 +56,96 @@ var Prezi = (function (my) {
56 56
     my.openPreziDialog = function() {
57 57
         var myprezi = connection.emuc.getPrezi(connection.emuc.myroomjid);
58 58
         if (myprezi) {
59
-            $.prompt("Are you sure you would like to remove your Prezi?",
60
-                    {
61
-                    title: "Remove Prezi",
62
-                    buttons: { "Remove": true, "Cancel": false},
63
-                    defaultButton: 1,
64
-                    submit: function(e,v,m,f){
65
-                    if(v)
66
-                    {
59
+            messageHandler.openTwoButtonDialog("Remove Prezi",
60
+                "Are you sure you would like to remove your Prezi?",
61
+                false,
62
+                "Remove",
63
+                function(e,v,m,f) {
64
+                    if(v) {
67 65
                         connection.emuc.removePreziFromPresence();
68 66
                         connection.emuc.sendPresence();
69 67
                     }
70 68
                 }
71
-            });
69
+            );
72 70
         }
73 71
         else if (preziPlayer != null) {
74
-            $.prompt("Another participant is already sharing a Prezi." +
72
+            messageHandler.openTwoButtonDialog("Share a Prezi",
73
+                "Another participant is already sharing a Prezi." +
75 74
                     "This conference allows only one Prezi at a time.",
76
-                     {
77
-                     title: "Share a Prezi",
78
-                     buttons: { "Ok": true},
79
-                     defaultButton: 0,
80
-                     submit: function(e,v,m,f){
81
-                        $.prompt.close();
82
-                     }
83
-                     });
75
+                false,
76
+                "Ok",
77
+                function(e,v,m,f) {
78
+                    $.prompt.close();
79
+                }
80
+            );
84 81
         }
85 82
         else {
86 83
             var openPreziState = {
87
-            state0: {
88
-                html:   '<h2>Share a Prezi</h2>' +
89
-                        '<input id="preziUrl" type="text" ' +
90
-                        'placeholder="e.g. ' +
91
-                        'http://prezi.com/wz7vhjycl7e6/my-prezi" autofocus>',
92
-                persistent: false,
93
-                buttons: { "Share": true , "Cancel": false},
94
-                defaultButton: 1,
95
-                submit: function(e,v,m,f){
96
-                    e.preventDefault();
97
-                    if(v)
98
-                    {
99
-                        var preziUrl = document.getElementById('preziUrl');
100
-
101
-                        if (preziUrl.value)
84
+                state0: {
85
+                    html:   '<h2>Share a Prezi</h2>' +
86
+                            '<input id="preziUrl" type="text" ' +
87
+                            'placeholder="e.g. ' +
88
+                            'http://prezi.com/wz7vhjycl7e6/my-prezi" autofocus>',
89
+                    persistent: false,
90
+                    buttons: { "Share": true , "Cancel": false},
91
+                    defaultButton: 1,
92
+                    submit: function(e,v,m,f){
93
+                        e.preventDefault();
94
+                        if(v)
102 95
                         {
103
-                            var urlValue
104
-                                = encodeURI(Util.escapeHtml(preziUrl.value));
96
+                            var preziUrl = document.getElementById('preziUrl');
105 97
 
106
-                            if (urlValue.indexOf('http://prezi.com/') != 0
107
-                                && urlValue.indexOf('https://prezi.com/') != 0)
98
+                            if (preziUrl.value)
108 99
                             {
109
-                                $.prompt.goToState('state1');
110
-                                return false;
111
-                            }
112
-                            else {
113
-                                var presIdTmp = urlValue.substring(
114
-                                        urlValue.indexOf("prezi.com/") + 10);
115
-                                if (!isAlphanumeric(presIdTmp)
116
-                                        || presIdTmp.indexOf('/') < 2) {
100
+                                var urlValue
101
+                                    = encodeURI(Util.escapeHtml(preziUrl.value));
102
+
103
+                                if (urlValue.indexOf('http://prezi.com/') != 0
104
+                                    && urlValue.indexOf('https://prezi.com/') != 0)
105
+                                {
117 106
                                     $.prompt.goToState('state1');
118 107
                                     return false;
119 108
                                 }
120 109
                                 else {
121
-                                    connection.emuc
122
-                                        .addPreziToPresence(urlValue, 0);
123
-                                    connection.emuc.sendPresence();
124
-                                    $.prompt.close();
110
+                                    var presIdTmp = urlValue.substring(
111
+                                            urlValue.indexOf("prezi.com/") + 10);
112
+                                    if (!isAlphanumeric(presIdTmp)
113
+                                            || presIdTmp.indexOf('/') < 2) {
114
+                                        $.prompt.goToState('state1');
115
+                                        return false;
116
+                                    }
117
+                                    else {
118
+                                        connection.emuc
119
+                                            .addPreziToPresence(urlValue, 0);
120
+                                        connection.emuc.sendPresence();
121
+                                        $.prompt.close();
122
+                                    }
125 123
                                 }
126 124
                             }
127 125
                         }
126
+                        else
127
+                            $.prompt.close();
128
+                    }
129
+                },
130
+                state1: {
131
+                    html:   '<h2>Share a Prezi</h2>' +
132
+                            'Please provide a correct prezi link.',
133
+                    persistent: false,
134
+                    buttons: { "Back": true, "Cancel": false },
135
+                    defaultButton: 1,
136
+                    submit:function(e,v,m,f) {
137
+                        e.preventDefault();
138
+                        if(v==0)
139
+                            $.prompt.close();
140
+                        else
141
+                            $.prompt.goToState('state0');
128 142
                     }
129
-                    else
130
-                        $.prompt.close();
131
-                }
132
-            },
133
-            state1: {
134
-                html:   '<h2>Share a Prezi</h2>' +
135
-                        'Please provide a correct prezi link.',
136
-                persistent: false,
137
-                buttons: { "Back": true, "Cancel": false },
138
-                defaultButton: 1,
139
-                submit:function(e,v,m,f) {
140
-                    e.preventDefault();
141
-                    if(v==0)
142
-                        $.prompt.close();
143
-                    else
144
-                        $.prompt.goToState('state0');
145 143
                 }
146
-            }
147 144
             };
148
-
149
-            var myPrompt = jQuery.prompt(openPreziState);
150
-
151
-            myPrompt.on('impromptu:loaded', function(e) {
152
-                        document.getElementById('preziUrl').focus();
153
-                        });
154
-            myPrompt.on('impromptu:statechanged', function(e) {
155
-                        document.getElementById('preziUrl').focus();
156
-                        });
145
+            var focusPreziUrl =  function(e) {
146
+                    document.getElementById('preziUrl').focus();
147
+                };
148
+            messageHandler.openDialogWithStates(openPreziState, focusPreziUrl, focusPreziUrl);
157 149
         }
158 150
     };
159 151
 

+ 103
- 112
toolbar.js Просмотреть файл

@@ -6,59 +6,51 @@ var Toolbar = (function (my) {
6 6
     my.openLockDialog = function () {
7 7
         // Only the focus is able to set a shared key.
8 8
         if (focus === null) {
9
-            if (sharedKey)
10
-                $.prompt("This conversation is currently protected by"
11
-                        + " a shared secret key.",
12
-                    {
13
-                        title: "Secret key",
14
-                        persistent: false
15
-                    }
16
-                );
17
-            else
18
-                $.prompt("This conversation isn't currently protected by"
19
-                        + " a secret key. Only the owner of the conference"
20
-                        + " could set a shared key.",
21
-                    {
22
-                        title: "Secret key",
23
-                        persistent: false
24
-                    }
25
-                );
9
+            if (sharedKey) {
10
+                messageHandler.openMessageDialog(null,
11
+                        "This conversation is currently protected by" +
12
+                        " a shared secret key.",
13
+                    false,
14
+                    "Secret key");
15
+            } else {
16
+                messageHandler.openMessageDialog(null,
17
+                    "This conversation isn't currently protected by" +
18
+                        " a secret key. Only the owner of the conference" +
19
+                        " could set a shared key.",
20
+                    false,
21
+                    "Secret key");
22
+            }
26 23
         } else {
27 24
             if (sharedKey) {
28
-                $.prompt("Are you sure you would like to remove your secret key?",
29
-                    {
30
-                        title: "Remove secret key",
31
-                        persistent: false,
32
-                        buttons: { "Remove": true, "Cancel": false},
33
-                        defaultButton: 1,
34
-                        submit: function (e, v, m, f) {
35
-                            if (v) {
36
-                                setSharedKey('');
37
-                                lockRoom(false);
38
-                            }
25
+                messageHandler.openTwoButtonDialog(null,
26
+                    "Are you sure you would like to remove your secret key?",
27
+                    false,
28
+                    "Remove",
29
+                    function (e, v) {
30
+                        if (v) {
31
+                            setSharedKey('');
32
+                            lockRoom(false);
39 33
                         }
40
-                    }
41
-                );
34
+                    });
42 35
             } else {
43
-                $.prompt('<h2>Set a secret key to lock your room</h2>' +
44
-                         '<input id="lockKey" type="text" placeholder="your shared key" autofocus>',
45
-                    {
46
-                        persistent: false,
47
-                        buttons: { "Save": true, "Cancel": false},
48
-                        defaultButton: 1,
49
-                        loaded: function (event) {
50
-                            document.getElementById('lockKey').focus();
51
-                        },
52
-                        submit: function (e, v, m, f) {
53
-                            if (v) {
54
-                                var lockKey = document.getElementById('lockKey');
55
-    
56
-                                if (lockKey.value) {
57
-                                    setSharedKey(Util.escapeHtml(lockKey.value));
58
-                                    lockRoom(true);
59
-                                }
36
+                messageHandler.openTwoButtonDialog(null,
37
+                    '<h2>Set a secret key to lock your room</h2>' +
38
+                        '<input id="lockKey" type="text"' +
39
+                        'placeholder="your shared key" autofocus>',
40
+                    false,
41
+                    "Save",
42
+                    function (e, v) {
43
+                        if (v) {
44
+                            var lockKey = document.getElementById('lockKey');
45
+
46
+                            if (lockKey.value) {
47
+                                setSharedKey(Util.escapeHtml(lockKey.value));
48
+                                lockRoom(true);
60 49
                             }
61 50
                         }
51
+                    },
52
+                    function () {
53
+                        document.getElementById('lockKey').focus();
62 54
                     }
63 55
                 );
64 56
             }
@@ -70,34 +62,33 @@ var Toolbar = (function (my) {
70 62
      */
71 63
     my.openLinkDialog = function () {
72 64
         var inviteLink;
73
-        if (roomUrl == null)
65
+        if (roomUrl == null) {
74 66
             inviteLink = "Your conference is currently being created...";
75
-        else
67
+        } else {
76 68
             inviteLink = encodeURI(roomUrl);
77
-
78
-        $.prompt('<input id="inviteLinkRef" type="text" value="' +
69
+        }
70
+        messageHandler.openTwoButtonDialog(
71
+            "Share this link with everyone you want to invite",
72
+            '<input id="inviteLinkRef" type="text" value="' +
79 73
                 inviteLink + '" onclick="this.select();" readonly>',
80
-                {
81
-                    title: "Share this link with everyone you want to invite",
82
-                    persistent: false,
83
-                    buttons: { "Invite": true, "Cancel": false},
84
-                    defaultButton: 1,
85
-                    loaded: function (event) {
86
-                        if (roomUrl)
87
-                            document.getElementById('inviteLinkRef').select();
88
-                        else
89
-                            document.getElementById('jqi_state0_buttonInvite')
90
-                                .disabled = true;
91
-                    },
92
-                    submit: function (e, v, m, f) {
93
-                        if (v) {
94
-                            if (roomUrl) {
95
-                                inviteParticipants();
96
-                            }
97
-                        }
74
+            false,
75
+            "Invite",
76
+            function (e, v) {
77
+                if (v) {
78
+                    if (roomUrl) {
79
+                        inviteParticipants();
98 80
                     }
99 81
                 }
100
-            );
82
+            },
83
+            function () {
84
+                if (roomUrl) {
85
+                    document.getElementById('inviteLinkRef').select();
86
+                } else {
87
+                    document.getElementById('jqi_state0_buttonInvite')
88
+                        .disabled = true;
89
+                }
90
+            }
91
+        );
101 92
     };
102 93
 
103 94
     /**
@@ -108,11 +99,12 @@ var Toolbar = (function (my) {
108 99
             return;
109 100
 
110 101
         var sharedKeyText = "";
111
-        if (sharedKey && sharedKey.length > 0)
112
-            sharedKeyText
113
-                = "This conference is password protected. Please use the "
114
-                    + "following pin when joining:%0D%0A%0D%0A"
115
-                    + sharedKey + "%0D%0A%0D%0A";
102
+        if (sharedKey && sharedKey.length > 0) {
103
+            sharedKeyText =
104
+                "This conference is password protected. Please use the " +
105
+                "following pin when joining:%0D%0A%0D%0A" +
106
+                sharedKey + "%0D%0A%0D%0A";
107
+        }
116 108
 
117 109
         var conferenceName = roomUrl.substring(roomUrl.lastIndexOf('/') + 1);
118 110
         var subject = "Invitation to a Jitsi Meet (" + conferenceName + ")";
@@ -128,8 +120,9 @@ var Toolbar = (function (my) {
128 120
                     " to be using one of these browsers.%0D%0A%0D%0A" +
129 121
                     "Talk to you in a sec!";
130 122
 
131
-        if (window.localStorage.displayname)
123
+        if (window.localStorage.displayname) {
132 124
             body += "%0D%0A%0D%0A" + window.localStorage.displayname;
125
+        }
133 126
 
134 127
         window.open("mailto:?subject=" + subject + "&body=" + body, '_blank');
135 128
     }
@@ -138,36 +131,38 @@ var Toolbar = (function (my) {
138 131
      * Opens the settings dialog.
139 132
      */
140 133
     my.openSettingsDialog = function () {
141
-        $.prompt('<h2>Configure your conference</h2>' +
142
-            '<input type="checkbox" id="initMuted"> Participants join muted<br/>' +
143
-            '<input type="checkbox" id="requireNicknames"> Require nicknames<br/><br/>' +
144
-            'Set a secret key to lock your room: <input id="lockKey" type="text" placeholder="your shared key" autofocus>',
145
-            {
146
-                persistent: false,
147
-                buttons: { "Save": true, "Cancel": false},
148
-                defaultButton: 1,
149
-                loaded: function (event) {
150
-                    document.getElementById('lockKey').focus();
151
-                },
152
-                submit: function (e, v, m, f) {
153
-                    if (v) {
154
-                        if ($('#initMuted').is(":checked")) {
155
-                            // it is checked
156
-                        }
157
-    
158
-                        if ($('#requireNicknames').is(":checked")) {
159
-                            // it is checked
160
-                        }
161
-                        /*
162
-                        var lockKey = document.getElementById('lockKey');
163
-    
164
-                        if (lockKey.value)
165
-                        {
166
-                            setSharedKey(lockKey.value);
167
-                            lockRoom(true);
168
-                        }
169
-                        */
134
+        messageHandler.openTwoButtonDialog(
135
+            '<h2>Configure your conference</h2>' +
136
+                '<input type="checkbox" id="initMuted">' +
137
+                'Participants join muted<br/>' +
138
+                '<input type="checkbox" id="requireNicknames">' +
139
+                'Require nicknames<br/><br/>' +
140
+                'Set a secret key to lock your room:' +
141
+                '<input id="lockKey" type="text" placeholder="your shared key"' +
142
+                'autofocus>',
143
+            null,
144
+            false,
145
+            "Save",
146
+            function () {
147
+                document.getElementById('lockKey').focus();
148
+            },
149
+            function (e, v) {
150
+                if (v) {
151
+                    if ($('#initMuted').is(":checked")) {
152
+                        // it is checked
153
+                    }
154
+
155
+                    if ($('#requireNicknames').is(":checked")) {
156
+                        // it is checked
170 157
                     }
158
+                    /*
159
+                    var lockKey = document.getElementById('lockKey');
160
+
161
+                    if (lockKey.value) {
162
+                        setSharedKey(lockKey.value);
163
+                        lockRoom(true);
164
+                    }
165
+                    */
171 166
                 }
172 167
             }
173 168
         );
@@ -224,14 +219,10 @@ var Toolbar = (function (my) {
224 219
     };
225 220
 
226 221
     // Shows or hides SIP calls button
227
-    my.showSipCallButton = function (show)
228
-    {
229
-        if (config.hosts.call_control && show)
230
-        {
222
+    my.showSipCallButton = function(show){
223
+        if (config.hosts.call_control && show) {
231 224
             $('#sipCallButton').css({display: "inline"});
232
-        }
233
-        else
234
-        {
225
+        } else {
235 226
             $('#sipCallButton').css({display: "none"});
236 227
         }
237 228
     };

Загрузка…
Отмена
Сохранить