瀏覽代碼

added some documentation (jsdocs)

j8
isymchych 9 年之前
父節點
當前提交
6b98fd52ea

+ 66
- 11
conference.js 查看文件

@@ -17,6 +17,9 @@ const ConferenceErrors = JitsiMeetJS.errors.conference;
17 17
 
18 18
 let room, connection, localTracks, localAudio, localVideo, roomLocker;
19 19
 
20
+/**
21
+ * Known custom conference commands.
22
+ */
20 23
 const Commands = {
21 24
     CONNECTION_QUALITY: "stats",
22 25
     EMAIL: "email",
@@ -26,6 +29,10 @@ const Commands = {
26 29
     STOP_PREZI: "stop-prezi"
27 30
 };
28 31
 
32
+/**
33
+ * Open Connection. When authentication failed it shows auth dialog.
34
+ * @returns Promise<JitsiConnection>
35
+ */
29 36
 function connect() {
30 37
     return openConnection({retry: true}).catch(function (err) {
31 38
         if (err === ConnectionErrors.PASSWORD_REQUIRED) {
@@ -37,8 +44,14 @@ function connect() {
37 44
     });
38 45
 }
39 46
 
40
-const addTrack = (track) => {
47
+/**
48
+ * Add local track to the conference and shares
49
+ * video type with other users if its video track.
50
+ * @param {JitsiLocalTrack} track local track
51
+ */
52
+function addTrack (track) {
41 53
     room.addTrack(track);
54
+
42 55
     if (track.isAudioTrack()) {
43 56
         return;
44 57
     }
@@ -50,25 +63,35 @@ const addTrack = (track) => {
50 63
             xmlns: 'http://jitsi.org/jitmeet/video'
51 64
         }
52 65
     });
53
-};
66
+}
54 67
 
55
-// share email with other users
56
-const sendEmail = (email) => {
68
+/**
69
+ * Share email with other users.
70
+ * @param {string} email new email
71
+ */
72
+function sendEmail (email) {
57 73
     room.sendCommand(Commands.EMAIL, {
58 74
         value: email,
59 75
         attributes: {
60 76
             id: room.myUserId()
61 77
         }
62 78
     });
63
-};
64
-
79
+}
65 80
 
66
-const unload = () => {
81
+/**
82
+ * Leave the conference and close connection.
83
+ */
84
+function unload () {
67 85
     room.leave();
68 86
     connection.disconnect();
69
-};
87
+}
70 88
 
71
-const getDisplayName = (id) => {
89
+/**
90
+ * Get user nickname by user id.
91
+ * @param {string} id user id
92
+ * @returns {string?} user nickname or undefined if user is unknown.
93
+ */
94
+function getDisplayName (id) {
72 95
     if (APP.conference.isLocalId(id)) {
73 96
         return APP.settings.getDisplayName();
74 97
     }
@@ -77,7 +100,7 @@ const getDisplayName = (id) => {
77 100
     if (participant && participant.getDisplayName()) {
78 101
         return participant.getDisplayName();
79 102
     }
80
-};
103
+}
81 104
 
82 105
 class ConferenceConnector {
83 106
     constructor(resolve, reject) {
@@ -151,6 +174,12 @@ export default {
151 174
     isModerator: false,
152 175
     audioMuted: false,
153 176
     videoMuted: false,
177
+    /**
178
+     * Open new connection and join to the conference.
179
+     * @param {object} options
180
+     * @param {string} roomName name of the conference
181
+     * @returns {Promise}
182
+     */
154 183
     init(options) {
155 184
         this.roomName = options.roomName;
156 185
         JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.TRACE);
@@ -173,6 +202,12 @@ export default {
173 202
             });
174 203
         });
175 204
     },
205
+    /**
206
+     * Create local tracks of specified types.
207
+     * If we cannot obtain required tracks it will return empty array.
208
+     * @param {string[]} devices required track types ('audio', 'video' etc.)
209
+     * @returns {Promise<JitsiLocalTrack[]>}
210
+     */
176 211
     createLocalTracks (...devices) {
177 212
         return JitsiMeetJS.createLocalTracks({
178 213
             // copy array to avoid mutations inside library
@@ -184,6 +219,11 @@ export default {
184 219
             return Promise.reject(err);
185 220
         });
186 221
     },
222
+    /**
223
+     * Check if id is id of the local user.
224
+     * @param {string} id id to check
225
+     * @returns {boolean}
226
+     */
187 227
     isLocalId (id) {
188 228
         return this.localId === id;
189 229
     },
@@ -217,12 +257,24 @@ export default {
217 257
     toggleVideoMuted () {
218 258
         this.muteVideo(!this.videoMuted);
219 259
     },
260
+    /**
261
+     * Retrieve list of conference participants (without local user).
262
+     * @returns {JitsiParticipant[]}
263
+     */
220 264
     listMembers () {
221 265
         return room.getParticipants();
222 266
     },
267
+    /**
268
+     * Retrieve list of ids of conference participants (without local user).
269
+     * @returns {string[]}
270
+     */
223 271
     listMembersIds () {
224 272
         return room.getParticipants().map(p => p.getId());
225 273
     },
274
+    /**
275
+     * Check if SIP is supported.
276
+     * @returns {boolean}
277
+     */
226 278
     sipGatewayEnabled () {
227 279
         return room.isSIPCallingSupported();
228 280
     },
@@ -279,7 +331,7 @@ export default {
279 331
     /**
280 332
      * Will check for number of remote particiapnts that have at least one
281 333
      * remote track.
282
-     * @return boolean whether we have enough participants with remote streams
334
+     * @return {boolean} whether we have enough participants with remote streams
283 335
      */
284 336
     checkEnoughParticipants (number) {
285 337
         var participants = this._room.getParticipants();
@@ -336,6 +388,9 @@ export default {
336 388
         }
337 389
         return options;
338 390
     },
391
+    /**
392
+     * Setup interaction between conference and UI.
393
+     */
339 394
     _setupListeners () {
340 395
         // add local streams when joined to the conference
341 396
         room.on(ConferenceEvents.CONFERENCE_JOINED, () => {

+ 25
- 0
connection.js 查看文件

@@ -5,6 +5,13 @@ import LoginDialog from './modules/UI/authentication/LoginDialog';
5 5
 const ConnectionEvents = JitsiMeetJS.events.connection;
6 6
 const ConnectionErrors = JitsiMeetJS.errors.connection;
7 7
 
8
+/**
9
+ * Try to open connection using provided credentials.
10
+ * @param {string} [id]
11
+ * @param {string} [password]
12
+ * @returns {Promise<JitsiConnection>} connection if
13
+ * everything is ok, else error.
14
+ */
8 15
 function connect(id, password) {
9 16
     let connection = new JitsiMeetJS.JitsiConnection(null, null, config);
10 17
 
@@ -42,6 +49,12 @@ function connect(id, password) {
42 49
     });
43 50
 }
44 51
 
52
+/**
53
+ * Show Authentication Dialog and try to connect with new credentials.
54
+ * If failed to connect because of PASSWORD_REQUIRED error
55
+ * then ask for password again.
56
+ * @returns {Promise<JitsiConnection>}
57
+ */
45 58
 function requestAuth() {
46 59
     return new Promise(function (resolve, reject) {
47 60
         let authDialog = LoginDialog.showAuthDialog(
@@ -62,6 +75,18 @@ function requestAuth() {
62 75
     });
63 76
 }
64 77
 
78
+/**
79
+ * Open JitsiConnection using provided credentials.
80
+ * If retry option is true it will show auth dialog on PASSWORD_REQUIRED error.
81
+ *
82
+ * @param {object} options
83
+ * @param {string} [options.id]
84
+ * @param {string} [options.password]
85
+ * @param {boolean} [retry] if we should show auth dialog
86
+ * on PASSWORD_REQUIRED error.
87
+ *
88
+ * @returns {Promise<JitsiConnection>}
89
+ */
65 90
 export function openConnection({id, password, retry}) {
66 91
     return connect(id, password).catch(function (err) {
67 92
         if (!retry) {

+ 175
- 3
modules/UI/UI.js 查看文件

@@ -31,6 +31,9 @@ UI.eventEmitter = eventEmitter;
31 31
 let preziManager;
32 32
 let etherpadManager;
33 33
 
34
+/**
35
+ * Prompt user for nickname.
36
+ */
34 37
 function promptDisplayName() {
35 38
     let nickRequiredMsg = APP.translation.translateString("dialog.displayNameRequired");
36 39
     let defaultNickMsg = APP.translation.translateString(
@@ -76,6 +79,9 @@ function promptDisplayName() {
76 79
     );
77 80
 }
78 81
 
82
+/**
83
+ * Initialize chat.
84
+ */
79 85
 function setupChat() {
80 86
     Chat.init(eventEmitter);
81 87
     $("#toggle_smileys").click(function() {
@@ -83,6 +89,9 @@ function setupChat() {
83 89
     });
84 90
 }
85 91
 
92
+/**
93
+ * Initialize toolbars.
94
+ */
86 95
 function setupToolbars() {
87 96
     Toolbar.init(eventEmitter);
88 97
     Toolbar.setupButtonsFromConfig();
@@ -113,6 +122,9 @@ function toggleFullScreen () {
113 122
     }
114 123
 }
115 124
 
125
+/**
126
+ * Notify user that server has shut down.
127
+ */
116 128
 UI.notifyGracefulShudown = function () {
117 129
     messageHandler.openMessageDialog(
118 130
         'dialog.serviceUnavailable',
@@ -120,6 +132,9 @@ UI.notifyGracefulShudown = function () {
120 132
     );
121 133
 };
122 134
 
135
+/**
136
+ * Notify user that reservation error happened.
137
+ */
123 138
 UI.notifyReservationError = function (code, msg) {
124 139
     var title = APP.translation.generateTranslationHTML(
125 140
         "dialog.reservationError");
@@ -135,14 +150,25 @@ UI.notifyReservationError = function (code, msg) {
135 150
     );
136 151
 };
137 152
 
153
+/**
154
+ * Notify user that he has been kicked from the server.
155
+ */
138 156
 UI.notifyKicked = function () {
139 157
     messageHandler.openMessageDialog("dialog.sessTerminated", "dialog.kickMessage");
140 158
 };
141 159
 
160
+/**
161
+ * Notify user that Jitsi Videobridge is not accessible.
162
+ */
142 163
 UI.notifyBridgeDown = function () {
143 164
     messageHandler.showError("dialog.error", "dialog.bridgeUnavailable");
144 165
 };
145 166
 
167
+/**
168
+ * Change nickname for the user.
169
+ * @param {string} id user id
170
+ * @param {string} displayName new nickname
171
+ */
146 172
 UI.changeDisplayName = function (id, displayName) {
147 173
     ContactList.onDisplayNameChange(id, displayName);
148 174
     SettingsMenu.onDisplayNameChange(id, displayName);
@@ -153,6 +179,9 @@ UI.changeDisplayName = function (id, displayName) {
153 179
     }
154 180
 };
155 181
 
182
+/**
183
+ * Intitialize conference UI.
184
+ */
156 185
 UI.initConference = function () {
157 186
     var id = APP.conference.localId;
158 187
     Toolbar.updateRoomUrl(window.location.href);
@@ -186,6 +215,9 @@ UI.mucJoined = function () {
186 215
     VideoLayout.mucJoined();
187 216
 };
188 217
 
218
+/**
219
+ * Setup some UI event listeners.
220
+ */
189 221
 function registerListeners() {
190 222
     UI.addListener(UIEvents.EMAIL_CHANGED, function (email) {
191 223
         UI.setUserAvatar(APP.conference.localId, email);
@@ -214,6 +246,9 @@ function registerListeners() {
214 246
     UI.addListener(UIEvents.TOGGLE_FILM_STRIP, UI.toggleFilmStrip);
215 247
 }
216 248
 
249
+/**
250
+ * Setup some DOM event listeners.
251
+ */
217 252
 function bindEvents() {
218 253
     function onResize() {
219 254
         PanelToggler.resizeChat();
@@ -341,6 +376,10 @@ UI.start = function () {
341 376
 };
342 377
 
343 378
 
379
+/**
380
+ * Show local stream on UI.
381
+ * @param {JitsiTrack} track stream to show
382
+ */
344 383
 UI.addLocalStream = function (track) {
345 384
     switch (track.getType()) {
346 385
     case 'audio':
@@ -356,18 +395,30 @@ UI.addLocalStream = function (track) {
356 395
 };
357 396
 
358 397
 
359
-UI.addRemoteStream = function (stream) {
360
-    VideoLayout.onRemoteStreamAdded(stream);
398
+/**
399
+ * Show remote stream on UI.
400
+ * @param {JitsiTrack} track stream to show
401
+ */
402
+UI.addRemoteStream = function (track) {
403
+    VideoLayout.onRemoteStreamAdded(track);
361 404
 };
362 405
 
363 406
 function chatAddError(errorMessage, originalText) {
364 407
     return Chat.chatAddError(errorMessage, originalText);
365 408
 }
366 409
 
410
+/**
411
+ * Update chat subject.
412
+ * @param {string} subject new chat subject
413
+ */
367 414
 UI.setSubject = function (subject) {
368 415
     Chat.setSubject(subject);
369 416
 };
370 417
 
418
+/**
419
+ * Setup and show Etherpad.
420
+ * @param {string} name etherpad id
421
+ */
371 422
 UI.initEtherpad = function (name) {
372 423
     if (etherpadManager || !config.etherpad_base || !name) {
373 424
         return;
@@ -377,6 +428,11 @@ UI.initEtherpad = function (name) {
377 428
     Toolbar.showEtherpadButton();
378 429
 };
379 430
 
431
+/**
432
+ * Show user on UI.
433
+ * @param {string} id user id
434
+ * @param {string} displayName user nickname
435
+ */
380 436
 UI.addUser = function (id, displayName) {
381 437
     ContactList.addContact(id);
382 438
 
@@ -395,6 +451,11 @@ UI.addUser = function (id, displayName) {
395 451
     VideoLayout.addParticipantContainer(id);
396 452
 };
397 453
 
454
+/**
455
+ * Remove user from UI.
456
+ * @param {string} id   user id
457
+ * @param {string} displayName user nickname
458
+ */
398 459
 UI.removeUser = function (id, displayName) {
399 460
     ContactList.removeContact(id);
400 461
 
@@ -415,10 +476,19 @@ UI.removeUser = function (id, displayName) {
415 476
 //     VideoLayout.setPresenceStatus(Strophe.getResourceFromJid(jid), info.status);
416 477
 // }
417 478
 
479
+/**
480
+ * Update videotype for specified user.
481
+ * @param {string} id user id
482
+ * @param {string} newVideoType new videotype
483
+ */
418 484
 UI.onPeerVideoTypeChanged = (id, newVideoType) => {
419 485
     VideoLayout.onVideoTypeChanged(id, newVideoType);
420 486
 };
421 487
 
488
+/**
489
+ * Update local user role and show notification if user is moderator.
490
+ * @param {boolean} isModerator if local user is moderator or not
491
+ */
422 492
 UI.updateLocalRole = function (isModerator) {
423 493
     VideoLayout.showModeratorIndicator();
424 494
 
@@ -462,22 +532,38 @@ UI.updateUserRole = function (user) {
462 532
 };
463 533
 
464 534
 
535
+/**
536
+ * Toggles smileys in the chat.
537
+ */
465 538
 UI.toggleSmileys = function () {
466 539
     Chat.toggleSmileys();
467 540
 };
468 541
 
542
+/**
543
+ * Get current settings.
544
+ * @returns {object} settings
545
+ */
469 546
 UI.getSettings = function () {
470 547
     return Settings.getSettings();
471 548
 };
472 549
 
550
+/**
551
+ * Toggles film strip.
552
+ */
473 553
 UI.toggleFilmStrip = function () {
474 554
     BottomToolbar.toggleFilmStrip();
475 555
 };
476 556
 
557
+/**
558
+ * Toggles chat panel.
559
+ */
477 560
 UI.toggleChat = function () {
478 561
     PanelToggler.toggleChat();
479 562
 };
480 563
 
564
+/**
565
+ * Toggles contact list panel.
566
+ */
481 567
 UI.toggleContactList = function () {
482 568
     PanelToggler.toggleContactList();
483 569
 };
@@ -499,6 +585,7 @@ UI.connectionIndicatorShowMore = function(jid) {
499 585
     return VideoLayout.showMore(jid);
500 586
 };
501 587
 
588
+// FIXME check if someone user this
502 589
 UI.showLoginPopup = function(callback) {
503 590
     console.log('password is required');
504 591
     var message = '<h2 data-i18n="dialog.passwordRequired">';
@@ -569,6 +656,11 @@ UI.dockToolbar = function (isDock) {
569 656
     ToolbarToggler.dockToolbar(isDock);
570 657
 };
571 658
 
659
+/**
660
+ * Update user avatar.
661
+ * @param {string} id user id
662
+ * @param {stirng} email user email
663
+ */
572 664
 UI.setUserAvatar = function (id, email) {
573 665
     // update avatar
574 666
     Avatar.setUserAvatar(id, email);
@@ -582,6 +674,10 @@ UI.setUserAvatar = function (id, email) {
582 674
     }
583 675
 };
584 676
 
677
+/**
678
+ * Notify user that connection failed.
679
+ * @param {string} stropheErrorMsg raw Strophe error message
680
+ */
585 681
 UI.notifyConnectionFailed = function (stropheErrorMsg) {
586 682
     var title = APP.translation.generateTranslationHTML(
587 683
         "dialog.error");
@@ -600,6 +696,10 @@ UI.notifyConnectionFailed = function (stropheErrorMsg) {
600 696
     );
601 697
 };
602 698
 
699
+/**
700
+ * Notify user that he need to install Firefox extension to share screen.
701
+ * @param {stirng} url extension url
702
+ */
603 703
 UI.notifyFirefoxExtensionRequired = function (url) {
604 704
     messageHandler.openMessageDialog(
605 705
         "dialog.extensionRequired",
@@ -611,12 +711,19 @@ UI.notifyFirefoxExtensionRequired = function (url) {
611 711
     );
612 712
 };
613 713
 
714
+/**
715
+ * Notify user that he was automatically muted when joned the conference.
716
+ */
614 717
 UI.notifyInitiallyMuted = function () {
615 718
     messageHandler.notify(
616 719
         null, "notify.mutedTitle", "connected", "notify.muted", null, {timeOut: 120000}
617 720
     );
618 721
 };
619 722
 
723
+/**
724
+ * Mark user as dominant speaker.
725
+ * @param {string} id user id
726
+ */
620 727
 UI.markDominantSpeaker = function (id) {
621 728
     VideoLayout.onDominantSpeakerChanged(id);
622 729
 };
@@ -625,26 +732,53 @@ UI.handleLastNEndpoints = function (ids) {
625 732
     VideoLayout.onLastNEndpointsChanged(ids, []);
626 733
 };
627 734
 
735
+/**
736
+ * Update audio level visualization for specified user.
737
+ * @param {string} id user id
738
+ * @param {number} lvl audio level
739
+ */
628 740
 UI.setAudioLevel = function (id, lvl) {
629 741
     VideoLayout.setAudioLevel(id, lvl);
630 742
 };
631 743
 
744
+/**
745
+ * Update state of desktop sharing buttons.
746
+ * @param {boolean} isSharingScreen if user is currently sharing his screen
747
+ */
632 748
 UI.updateDesktopSharingButtons = function (isSharingScreen) {
633 749
     Toolbar.changeDesktopSharingButtonState(isSharingScreen);
634 750
 };
635 751
 
752
+/**
753
+ * Hide connection quality statistics from UI.
754
+ */
636 755
 UI.hideStats = function () {
637 756
     VideoLayout.hideStats();
638 757
 };
639 758
 
759
+/**
760
+ * Update local connection quality statistics.
761
+ * @param {number} percent
762
+ * @param {object} stats
763
+ */
640 764
 UI.updateLocalStats = function (percent, stats) {
641 765
     VideoLayout.updateLocalConnectionStats(percent, stats);
642 766
 };
643 767
 
768
+/**
769
+ * Update connection quality statistics for remote user.
770
+ * @param {string} id user id
771
+ * @param {number} percent
772
+ * @param {object} stats
773
+ */
644 774
 UI.updateRemoteStats = function (id, percent, stats) {
645 775
     VideoLayout.updateConnectionStats(id, percent, stats);
646 776
 };
647 777
 
778
+/**
779
+ * Mark video as interrupted or not.
780
+ * @param {boolean} interrupted if video is interrupted
781
+ */
648 782
 UI.markVideoInterrupted = function (interrupted) {
649 783
     if (interrupted) {
650 784
         VideoLayout.onVideoInterrupted();
@@ -653,6 +787,10 @@ UI.markVideoInterrupted = function (interrupted) {
653 787
     }
654 788
 };
655 789
 
790
+/**
791
+ * Mark room as locked or not.
792
+ * @param {boolean} locked if room is locked.
793
+ */
656 794
 UI.markRoomLocked = function (locked) {
657 795
     if (locked) {
658 796
         Toolbar.lockLockButton();
@@ -661,6 +799,13 @@ UI.markRoomLocked = function (locked) {
661 799
     }
662 800
 };
663 801
 
802
+/**
803
+ * Add chat message.
804
+ * @param {string} from user id
805
+ * @param {string} displayName user nickname
806
+ * @param {string} message message text
807
+ * @param {number} stamp timestamp when message was created
808
+ */
664 809
 UI.addMessage = function (from, displayName, message, stamp) {
665 810
     Chat.updateChatConversation(from, displayName, message, stamp);
666 811
 };
@@ -672,6 +817,10 @@ UI.updateDTMFSupport = function (isDTMFSupported) {
672 817
 
673 818
 /**
674 819
  * Invite participants to conference.
820
+ * @param {string} roomUrl
821
+ * @param {string} conferenceName
822
+ * @param {string} key
823
+ * @param {string} nick
675 824
  */
676 825
 UI.inviteParticipants = function (roomUrl, conferenceName, key, nick) {
677 826
     let keyText = "";
@@ -710,6 +859,10 @@ UI.inviteParticipants = function (roomUrl, conferenceName, key, nick) {
710 859
     window.open(`mailto:?subject=${subject}&body=${body}`, '_blank');
711 860
 };
712 861
 
862
+/**
863
+ * Show user feedback dialog if its required or just show "thank you" dialog.
864
+ * @returns {Promise} when dialog is closed.
865
+ */
713 866
 UI.requestFeedback = function () {
714 867
     return new Promise(function (resolve, reject) {
715 868
         if (Feedback.isEnabled()) {
@@ -736,6 +889,10 @@ UI.requestFeedback = function () {
736 889
     });
737 890
 };
738 891
 
892
+/**
893
+ * Request recording token from the user.
894
+ * @returns {Promise}
895
+ */
739 896
 UI.requestRecordingToken = function () {
740 897
     let msg = APP.translation.generateTranslationHTML("dialog.recordingToken");
741 898
     let token = APP.translation.translateString("dialog.token");
@@ -769,6 +926,11 @@ UI.notifyTokenAuthFailed = function () {
769 926
     messageHandler.showError("dialog.error", "dialog.tokenAuthFailed");
770 927
 };
771 928
 
929
+/**
930
+ * Updates auth info on the UI.
931
+ * @param {boolean} isAuthEnabled if authentication is enabled
932
+ * @param {string} [login] current login
933
+ */
772 934
 UI.updateAuthInfo = function (isAuthEnabled, login) {
773 935
     let loggedIn = !!login;
774 936
 
@@ -782,10 +944,20 @@ UI.updateAuthInfo = function (isAuthEnabled, login) {
782 944
     }
783 945
 };
784 946
 
947
+/**
948
+ * Show Prezi from the user.
949
+ * @param {string} userId user id
950
+ * @param {string} url Prezi url
951
+ * @param {number} slide slide to show
952
+ */
785 953
 UI.showPrezi = function (userId, url, slide) {
786 954
     preziManager.showPrezi(userId, url, slide);
787 955
 };
788 956
 
957
+/**
958
+ * Stop showing Prezi from the user.
959
+ * @param {string} userId user id
960
+ */
789 961
 UI.stopPrezi = function (userId) {
790 962
   if (preziManager.isSharing(userId)) {
791 963
       preziManager.removePrezi(userId);
@@ -798,7 +970,7 @@ UI.onStartMutedChanged = function () {
798 970
 
799 971
 /**
800 972
  * Returns the id of the current video shown on large.
801
- * Currently used by tests (troture).
973
+ * Currently used by tests (torture).
802 974
  */
803 975
 UI.getLargeVideoID = function () {
804 976
     return VideoLayout.getLargeVideoID();

+ 24
- 0
modules/UI/authentication/AuthHandler.js 查看文件

@@ -10,6 +10,13 @@ const ConferenceEvents = JitsiMeetJS.events.conference;
10 10
 let externalAuthWindow;
11 11
 let authRequiredDialog;
12 12
 
13
+/**
14
+ * Authenticate using external service or just focus
15
+ * external auth window if there is one already.
16
+ *
17
+ * @param {JitsiConference} room
18
+ * @param {string} [lockPassword] password to use if the conference is locked
19
+ */
13 20
 function doExternalAuth (room, lockPassword) {
14 21
     if (externalAuthWindow) {
15 22
         externalAuthWindow.focus();
@@ -32,6 +39,11 @@ function doExternalAuth (room, lockPassword) {
32 39
     }
33 40
 }
34 41
 
42
+/**
43
+ * Authenticate on the server.
44
+ * @param {JitsiConference} room
45
+ * @param {string} [lockPassword] password to use if the conference is locked
46
+ */
35 47
 function doXmppAuth (room, lockPassword) {
36 48
     let loginDialog = LoginDialog.showAuthDialog(function (id, password) {
37 49
         // auth "on the fly":
@@ -83,6 +95,12 @@ function doXmppAuth (room, lockPassword) {
83 95
     });
84 96
 }
85 97
 
98
+/**
99
+ * Authenticate for the conference.
100
+ * Uses external service for auth if conference supports that.
101
+ * @param {JitsiConference} room
102
+ * @param {string} [lockPassword] password to use if the conference is locked
103
+ */
86 104
 function authenticate (room, lockPassword) {
87 105
     if (room.isExternalAuthEnabled()) {
88 106
         doExternalAuth(room, lockPassword);
@@ -91,6 +109,9 @@ function authenticate (room, lockPassword) {
91 109
     }
92 110
 }
93 111
 
112
+/**
113
+ * Notify user that authentication is required to create the conference.
114
+ */
94 115
 function requireAuth(roomName) {
95 116
     if (authRequiredDialog) {
96 117
         return;
@@ -101,6 +122,9 @@ function requireAuth(roomName) {
101 122
     );
102 123
 }
103 124
 
125
+/**
126
+ * Close auth-related dialogs if there are any.
127
+ */
104 128
 function closeAuth() {
105 129
     if (externalAuthWindow) {
106 130
         externalAuthWindow.close();

+ 55
- 7
modules/UI/authentication/LoginDialog.js 查看文件

@@ -2,6 +2,10 @@
2 2
 
3 3
 var messageHandler = require('../util/MessageHandler');
4 4
 
5
+/**
6
+ * Build html for "password required" dialog.
7
+ * @returns {string} html string
8
+ */
5 9
 function getPasswordInputHtml() {
6 10
     let placeholder = config.hosts.authdomain
7 11
         ? "user identity"
@@ -13,11 +17,16 @@ function getPasswordInputHtml() {
13 17
         <h2 data-i18n="dialog.passwordRequired">${passRequiredMsg}</h2>
14 18
         <input name="username" type="text" placeholder=${placeholder} autofocus>
15 19
         <input name="password" type="password"
16
-    data-i18n="[placeholder]dialog.userPassword"
17
-    placeholder="user password">
20
+               data-i18n="[placeholder]dialog.userPassword"
21
+               placeholder="user password">
18 22
         `;
19 23
 }
20 24
 
25
+/**
26
+ * Convert provided id to jid if it's not jid yet.
27
+ * @param {string} id user id or jid
28
+ * @returns {string} jid
29
+ */
21 30
 function toJid(id) {
22 31
     if (id.indexOf("@") >= 0) {
23 32
         return id;
@@ -33,6 +42,10 @@ function toJid(id) {
33 42
     return jid;
34 43
 }
35 44
 
45
+/**
46
+ * Generate cancel button config for the dialog.
47
+ * @returns {Object}
48
+ */
36 49
 function cancelButton() {
37 50
     return {
38 51
         title: APP.translation.generateTranslationHTML("dialog.Cancel"),
@@ -40,7 +53,18 @@ function cancelButton() {
40 53
     };
41 54
 }
42 55
 
43
-function Dialog(successCallback, cancelCallback) {
56
+/**
57
+ * Auth dialog for JitsiConnection which supports retries.
58
+ * If no cancelCallback provided then there will be
59
+ * no cancel button on the dialog.
60
+ *
61
+ * @class LoginDialog
62
+ * @constructor
63
+ *
64
+ * @param {function(jid, password)} successCallback
65
+ * @param {function} [cancelCallback] callback to invoke if user canceled.
66
+ */
67
+function LoginDialog(successCallback, cancelCallback) {
44 68
     let loginButtons = [{
45 69
         title: APP.translation.generateTranslationHTML("dialog.Ok"),
46 70
         value: true
@@ -118,6 +142,10 @@ function Dialog(successCallback, cancelCallback) {
118 142
         connDialog.goToState('finished');
119 143
     };
120 144
 
145
+    /**
146
+     *  Show message as connection status.
147
+     * @param {string} message
148
+     */
121 149
     this.displayConnectionStatus = function (message) {
122 150
         let connectingState = connDialog.getState('connecting');
123 151
 
@@ -133,12 +161,26 @@ function Dialog(successCallback, cancelCallback) {
133 161
     };
134 162
 }
135 163
 
136
-const LoginDialog = {
164
+export default {
137 165
 
166
+    /**
167
+     * Show new auth dialog for JitsiConnection.
168
+     *
169
+     * @param {function(jid, password)} successCallback
170
+     * @param {function} [cancelCallback] callback to invoke if user canceled.
171
+     *
172
+     * @returns {LoginDialog}
173
+     */
138 174
     showAuthDialog: function (successCallback, cancelCallback) {
139
-        return new Dialog(successCallback, cancelCallback);
175
+        return new LoginDialog(successCallback, cancelCallback);
140 176
     },
141 177
 
178
+    /**
179
+     * Show notification that external auth is required (using provided url).
180
+     * @param {string} url URL to use for external auth.
181
+     * @param {function} callback callback to invoke when auth popup is closed.
182
+     * @returns auth dialog
183
+     */
142 184
     showExternalAuthDialog: function (url, callback) {
143 185
         var dialog = messageHandler.openCenteredPopup(
144 186
             url, 910, 660,
@@ -153,6 +195,14 @@ const LoginDialog = {
153 195
         return dialog;
154 196
     },
155 197
 
198
+    /**
199
+     * Show notification that authentication is required
200
+     * to create the conference, so he should authenticate or wait for a host.
201
+     * @param {string} roomName name of the conference
202
+     * @param {function} onAuthNow callback to invoke if
203
+     * user want to authenticate.
204
+     * @returns dialog
205
+     */
156 206
     showAuthRequiredDialog: function (roomName, onAuthNow) {
157 207
         var title = APP.translation.generateTranslationHTML(
158 208
             "dialog.WaitingForHost"
@@ -184,5 +234,3 @@ const LoginDialog = {
184 234
         );
185 235
     }
186 236
 };
187
-
188
-export default LoginDialog;

+ 48
- 4
modules/UI/authentication/RoomLocker.js 查看文件

@@ -4,6 +4,10 @@ import UIUtil from '../util/UIUtil';
4 4
 //FIXME:
5 5
 import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
6 6
 
7
+/**
8
+ * Show dialog which asks user for new password for the conference.
9
+ * @returns {Promise<string>} password or nothing if user canceled
10
+ */
7 11
 function askForNewPassword () {
8 12
     let passMsg = APP.translation.generateTranslationHTML("dialog.passwordMsg");
9 13
     let yourPassMsg = APP.translation.translateString("dialog.yourPassword");
@@ -30,6 +34,10 @@ function askForNewPassword () {
30 34
     });
31 35
 }
32 36
 
37
+/**
38
+ * Show dialog which asks for required conference password.
39
+ * @returns {Promise<string>} password or nothing if user canceled
40
+ */
33 41
 function askForPassword () {
34 42
     let passRequiredMsg = APP.translation.translateString(
35 43
         "dialog.passwordRequired"
@@ -58,6 +66,10 @@ function askForPassword () {
58 66
     });
59 67
 }
60 68
 
69
+/**
70
+ * Show dialog which asks if user want remove password from the conference.
71
+ * @returns {Promise}
72
+ */
61 73
 function askToUnlock () {
62 74
     return new Promise(function (resolve, reject) {
63 75
         messageHandler.openTwoButtonDialog(
@@ -74,18 +86,32 @@ function askToUnlock () {
74 86
     });
75 87
 }
76 88
 
77
-function notifyPasswordNotSupported (err) {
78
-    console.warn('setting password failed', err);
89
+/**
90
+ * Show notification that user cannot set password for the conference
91
+ * because server doesn't support that.
92
+ */
93
+function notifyPasswordNotSupported () {
94
+    console.warn('room passwords not supported');
79 95
     messageHandler.showError("dialog.warning", "dialog.passwordNotSupported");
80 96
 }
81 97
 
82
-function notifyPasswordFailed() {
83
-    console.warn('room passwords not supported');
98
+/**
99
+ * Show notification that setting password for the conference failed.
100
+ * @param {Error} err error
101
+ */
102
+function notifyPasswordFailed(err) {
103
+    console.warn('setting password failed', err);
84 104
     messageHandler.showError("dialog.lockTitle", "dialog.lockMessage");
85 105
 }
86 106
 
87 107
 const ConferenceErrors = JitsiMeetJS.errors.conference;
88 108
 
109
+/**
110
+ * Create new RoomLocker for the conference.
111
+ * It allows to set or remove password for the conference,
112
+ * or ask for required password.
113
+ * @returns {RoomLocker}
114
+ */
89 115
 export default function createRoomLocker (room) {
90 116
     let password;
91 117
 
@@ -103,6 +129,9 @@ export default function createRoomLocker (room) {
103 129
         });
104 130
     }
105 131
 
132
+    /**
133
+     * @class RoomLocker
134
+     */
106 135
     return {
107 136
         get isLocked () {
108 137
             return !!password;
@@ -112,6 +141,10 @@ export default function createRoomLocker (room) {
112 141
             return password;
113 142
         },
114 143
 
144
+        /**
145
+         * Allows to remove password from the conference (asks user first).
146
+         * @returns {Promise}
147
+         */
115 148
         askToUnlock () {
116 149
             return askToUnlock().then(function () {
117 150
                 return lock();
@@ -120,6 +153,11 @@ export default function createRoomLocker (room) {
120 153
             });
121 154
         },
122 155
 
156
+        /**
157
+         * Allows to set password for the conference.
158
+         * It asks user for new password and locks the room.
159
+         * @returns {Promise}
160
+         */
123 161
         askToLock () {
124 162
             return askForNewPassword().then(function (newPass) {
125 163
                 return lock(newPass);
@@ -128,12 +166,18 @@ export default function createRoomLocker (room) {
128 166
             });
129 167
         },
130 168
 
169
+        /**
170
+         * Asks user for required conference password.
171
+         */
131 172
         requirePassword () {
132 173
             return askForPassword().then(function (newPass) {
133 174
                 password = newPass;
134 175
             });
135 176
         },
136 177
 
178
+        /**
179
+         * Show notification that to set/remove password user must be moderator.
180
+         */
137 181
         notifyModeratorRequired () {
138 182
             if (password) {
139 183
                 messageHandler.openMessageDialog(null, "dialog.passwordError");

+ 22
- 0
modules/UI/etherpad/Etherpad.js 查看文件

@@ -6,6 +6,9 @@ import UIUtil from "../util/UIUtil";
6 6
 import SidePanelToggler from "../side_pannels/SidePanelToggler";
7 7
 import BottomToolbar from '../toolbars/BottomToolbar';
8 8
 
9
+/**
10
+ * Etherpad options.
11
+ */
9 12
 const options = $.param({
10 13
     showControns: true,
11 14
     showChat: false,
@@ -40,11 +43,20 @@ function bubbleIframeMouseMove(iframe){
40 43
     };
41 44
 }
42 45
 
46
+/**
47
+ * Default Etherpad frame width.
48
+ */
43 49
 const DEFAULT_WIDTH = 640;
50
+/**
51
+ * Default Etherpad frame height.
52
+ */
44 53
 const DEFAULT_HEIGHT = 480;
45 54
 
46 55
 const EtherpadContainerType = "etherpad";
47 56
 
57
+/**
58
+ * Container for Etherpad iframe.
59
+ */
48 60
 class Etherpad extends LargeContainer {
49 61
     constructor (domain, name) {
50 62
         super();
@@ -123,6 +135,9 @@ class Etherpad extends LargeContainer {
123 135
     }
124 136
 }
125 137
 
138
+/**
139
+ * Manager of the Etherpad frame.
140
+ */
126 141
 export default class EtherpadManager {
127 142
     constructor (domain, name) {
128 143
         if (!domain || !name) {
@@ -138,6 +153,9 @@ export default class EtherpadManager {
138 153
         return !!this.etherpad;
139 154
     }
140 155
 
156
+    /**
157
+     * Create new Etherpad frame.
158
+     */
141 159
     openEtherpad () {
142 160
         this.etherpad = new Etherpad(this.domain, this.name);
143 161
         VideoLayout.addLargeVideoContainer(
@@ -146,6 +164,10 @@ export default class EtherpadManager {
146 164
         );
147 165
     }
148 166
 
167
+    /**
168
+     * Toggle Etherpad frame visibility.
169
+     * Open new Etherpad frame if there is no Etherpad frame yet.
170
+     */
149 171
     toggleEtherpad () {
150 172
         if (!this.isOpen) {
151 173
             this.openEtherpad();

+ 71
- 0
modules/UI/prezi/Prezi.js 查看文件

@@ -11,17 +11,31 @@ import ToolbarToggler from "../toolbars/ToolbarToggler";
11 11
 import SidePanelToggler from "../side_pannels/SidePanelToggler";
12 12
 import BottomToolbar from '../toolbars/BottomToolbar';
13 13
 
14
+/**
15
+ * Example of Prezi link.
16
+ */
14 17
 const defaultPreziLink = "http://prezi.com/wz7vhjycl7e6/my-prezi";
15 18
 const alphanumRegex = /^[a-z0-9-_\/&\?=;]+$/i;
19
+/**
20
+ * Default aspect ratio for Prezi frame.
21
+ */
16 22
 const aspectRatio = 16.0 / 9.0;
17 23
 
24
+/**
25
+ * Default Prezi frame width.
26
+ */
18 27
 const DEFAULT_WIDTH = 640;
28
+/**
29
+ * Default Prezi frame height.
30
+ */
19 31
 const DEFAULT_HEIGHT = 480;
20 32
 
21 33
 /**
22 34
  * Indicates if the given string is an alphanumeric string.
23 35
  * Note that some special characters are also allowed (-, _ , /, &, ?, =, ;) for the
24 36
  * purpose of checking URIs.
37
+ * @param {string} unsafeText string to check
38
+ * @returns {boolean}
25 39
  */
26 40
 function isAlphanumeric(unsafeText) {
27 41
     return alphanumRegex.test(unsafeText);
@@ -29,12 +43,19 @@ function isAlphanumeric(unsafeText) {
29 43
 
30 44
 /**
31 45
  * Returns the presentation id from the given url.
46
+ * @param {string} url Prezi link
47
+ * @returns {string} presentation id
32 48
  */
33 49
 function getPresentationId (url) {
34 50
     let presId = url.substring(url.indexOf("prezi.com/") + 10);
35 51
     return presId.substring(0, presId.indexOf('/'));
36 52
 }
37 53
 
54
+/**
55
+ * Checks if given string is Prezi url.
56
+ * @param {string} url string to check.
57
+ * @returns {boolean}
58
+ */
38 59
 function isPreziLink(url) {
39 60
     if (url.indexOf('http://prezi.com/') !== 0 && url.indexOf('https://prezi.com/') !== 0) {
40 61
         return false;
@@ -48,6 +69,9 @@ function isPreziLink(url) {
48 69
     return true;
49 70
 }
50 71
 
72
+/**
73
+ * Notify user that other user if already sharing Prezi.
74
+ */
51 75
 function notifyOtherIsSharingPrezi() {
52 76
     messageHandler.openMessageDialog(
53 77
         "dialog.sharePreziTitle",
@@ -55,6 +79,9 @@ function notifyOtherIsSharingPrezi() {
55 79
     );
56 80
 }
57 81
 
82
+/**
83
+ * Ask user if he want to close Prezi he's sharing.
84
+ */
58 85
 function proposeToClosePrezi() {
59 86
     return new Promise(function (resolve, reject) {
60 87
         messageHandler.openTwoButtonDialog(
@@ -76,6 +103,10 @@ function proposeToClosePrezi() {
76 103
     });
77 104
 }
78 105
 
106
+/**
107
+ * Ask user for Prezi url to share with others.
108
+ * Dialog validates client input to allow only Prezi urls.
109
+ */
79 110
 function requestPreziLink() {
80 111
     const title = APP.translation.generateTranslationHTML("dialog.sharePreziTitle");
81 112
     const cancelButton = APP.translation.generateTranslationHTML("dialog.Cancel");
@@ -154,6 +185,9 @@ function requestPreziLink() {
154 185
 
155 186
 export const PreziContainerType = "prezi";
156 187
 
188
+/**
189
+ * Container for Prezi iframe.
190
+ */
157 191
 class PreziContainer extends LargeContainer {
158 192
 
159 193
     constructor ({preziId, isMy, slide, onSlideChanged}) {
@@ -187,6 +221,10 @@ class PreziContainer extends LargeContainer {
187 221
         });
188 222
     }
189 223
 
224
+    /**
225
+     * Change Prezi slide.
226
+     * @param {number} slide slide to show
227
+     */
190 228
     goToSlide (slide) {
191 229
         if (this.preziPlayer.getCurrentStep() === slide) {
192 230
             return;
@@ -204,6 +242,10 @@ class PreziContainer extends LargeContainer {
204 242
         }
205 243
     }
206 244
 
245
+    /**
246
+     * Show or hide "reload presentation" button.
247
+     * @param {boolean} show
248
+     */
207 249
     showReloadBtn (show) {
208 250
         this.reloadBtn.css('display', show ? 'inline-block' : 'none');
209 251
     }
@@ -256,6 +298,9 @@ class PreziContainer extends LargeContainer {
256 298
         this.$iframe.width(width).height(height);
257 299
     }
258 300
 
301
+    /**
302
+     * Close Prezi frame.
303
+     */
259 304
     close () {
260 305
         this.showReloadBtn(false);
261 306
         this.preziPlayer.destroy();
@@ -263,6 +308,9 @@ class PreziContainer extends LargeContainer {
263 308
     }
264 309
 }
265 310
 
311
+/**
312
+ * Manager of Prezi frames.
313
+ */
266 314
 export default class PreziManager {
267 315
     constructor (emitter) {
268 316
         this.emitter = emitter;
@@ -282,6 +330,10 @@ export default class PreziManager {
282 330
         return this.userId === APP.conference.localId;
283 331
     }
284 332
 
333
+    /**
334
+     * Check if user is currently sharing.
335
+     * @param {string} id user id to check for
336
+     */
285 337
     isSharing (id) {
286 338
         return this.userId === id;
287 339
     }
@@ -302,6 +354,9 @@ export default class PreziManager {
302 354
         }
303 355
     }
304 356
 
357
+    /**
358
+     * Reload current Prezi frame.
359
+     */
305 360
     reloadPresentation () {
306 361
         if (!this.prezi) {
307 362
             return;
@@ -310,6 +365,12 @@ export default class PreziManager {
310 365
         iframe.src = iframe.src;
311 366
     }
312 367
 
368
+    /**
369
+     * Show Prezi. Create new Prezi if there is no Prezi yet.
370
+     * @param {string} id owner id
371
+     * @param {string} url Prezi url
372
+     * @param {number} slide slide to show
373
+     */
313 374
     showPrezi (id, url, slide) {
314 375
         if (!this.isPresenting) {
315 376
             this.createPrezi(id, url, slide);
@@ -324,6 +385,12 @@ export default class PreziManager {
324 385
         }
325 386
     }
326 387
 
388
+    /**
389
+     * Create new Prezi frame..
390
+     * @param {string} id owner id
391
+     * @param {string} url Prezi url
392
+     * @param {number} slide slide to show
393
+     */
327 394
     createPrezi (id, url, slide) {
328 395
         console.log("presentation added", url);
329 396
 
@@ -354,6 +421,10 @@ export default class PreziManager {
354 421
         VideoLayout.showLargeVideoContainer(PreziContainerType, true);
355 422
     }
356 423
 
424
+    /**
425
+     * Close Prezi.
426
+     * @param {string} id owner id
427
+     */
357 428
     removePrezi (id) {
358 429
         if (this.userId !== id) {
359 430
             throw new Error(`cannot close presentation from ${this.userId} instead of ${id}`);

+ 17
- 0
modules/UI/videolayout/LargeContainer.js 查看文件

@@ -1,24 +1,41 @@
1 1
 
2
+/**
3
+ * Base class for all Large containers which we can show.
4
+ */
2 5
 export default class LargeContainer {
3 6
 
4 7
     /**
8
+     * Show this container.
5 9
      * @returns Promise
6 10
      */
7 11
     show () {
8 12
     }
9 13
 
10 14
     /**
15
+     * Hide this container.
11 16
      * @returns Promise
12 17
      */
13 18
     hide () {
14 19
     }
15 20
 
21
+    /**
22
+     * Resize this container.
23
+     * @param {number} containerWidth available width
24
+     * @param {number} containerHeight available height
25
+     * @param {boolean} animate if container should animate it's resize process
26
+     */
16 27
     resize (containerWidth, containerHeight, animate) {
17 28
     }
18 29
 
30
+    /**
31
+     * Handler for "hover in" events.
32
+     */
19 33
     onHoverIn (e) {
20 34
     }
21 35
 
36
+    /**
37
+     * Handler for "hover out" events.
38
+     */
22 39
     onHoverOut (e) {
23 40
     }
24 41
 }

+ 86
- 1
modules/UI/videolayout/LargeVideo.js 查看文件

@@ -11,6 +11,10 @@ const RTCBrowserType = require("../../RTC/RTCBrowserType");
11 11
 
12 12
 const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
13 13
 
14
+/**
15
+ * Get stream id.
16
+ * @param {JitsiTrack?} stream
17
+ */
14 18
 function getStreamId(stream) {
15 19
     if(!stream)
16 20
         return;
@@ -147,6 +151,9 @@ function getDesktopVideoPosition(videoWidth,
147 151
 
148 152
 export const VideoContainerType = "video";
149 153
 
154
+/**
155
+ * Container for user video.
156
+ */
150 157
 class VideoContainer extends LargeContainer {
151 158
     // FIXME: With Temasys we have to re-select everytime
152 159
     get $video () {
@@ -174,6 +181,10 @@ class VideoContainer extends LargeContainer {
174 181
         this.$video.on('play', onPlay);
175 182
     }
176 183
 
184
+    /**
185
+     * Get size of video element.
186
+     * @returns {{width, height}}
187
+     */
177 188
     getStreamSize () {
178 189
         let video = this.$video[0];
179 190
         return {
@@ -182,6 +193,12 @@ class VideoContainer extends LargeContainer {
182 193
         };
183 194
     }
184 195
 
196
+    /**
197
+     * Calculate optimal video size for specified container size.
198
+     * @param {number} containerWidth container width
199
+     * @param {number} containerHeight container height
200
+     * @returns {{availableWidth, availableHeight}}
201
+     */
185 202
     getVideoSize (containerWidth, containerHeight) {
186 203
         let { width, height } = this.getStreamSize();
187 204
         if (this.stream && this.isScreenSharing()) {
@@ -197,6 +214,15 @@ class VideoContainer extends LargeContainer {
197 214
         }
198 215
     }
199 216
 
217
+    /**
218
+     * Calculate optimal video position (offset for top left corner)
219
+     * for specified video size and container size.
220
+     * @param {number} width video width
221
+     * @param {number} height video height
222
+     * @param {number} containerWidth container width
223
+     * @param {number} containerHeight container height
224
+     * @returns {{horizontalIndent, verticalIndent}}
225
+     */
200 226
     getVideoPosition (width, height, containerWidth, containerHeight) {
201 227
         if (this.stream && this.isScreenSharing()) {
202 228
             return getDesktopVideoPosition( width,
@@ -238,6 +264,11 @@ class VideoContainer extends LargeContainer {
238 264
         });
239 265
     }
240 266
 
267
+    /**
268
+     * Update video stream.
269
+     * @param {JitsiTrack?} stream new stream
270
+     * @param {string} videoType video type
271
+     */
241 272
     setStream (stream, videoType) {
242 273
         this.stream = stream;
243 274
         this.videoType = videoType;
@@ -250,10 +281,18 @@ class VideoContainer extends LargeContainer {
250 281
         });
251 282
     }
252 283
 
284
+    /**
285
+     * Check if current video stream is screen sharing.
286
+     * @returns {boolean}
287
+     */
253 288
     isScreenSharing () {
254 289
         return this.videoType === 'desktop';
255 290
     }
256 291
 
292
+    /**
293
+     * Show or hide user avatar.
294
+     * @param {boolean} show
295
+     */
257 296
     showAvatar (show) {
258 297
         this.$avatar.css("visibility", show ? "visible" : "hidden");
259 298
     }
@@ -289,7 +328,9 @@ class VideoContainer extends LargeContainer {
289 328
     }
290 329
 }
291 330
 
292
-
331
+/**
332
+ * Manager for all Large containers.
333
+ */
293 334
 export default class LargeVideoManager {
294 335
     constructor () {
295 336
         this.containers = {};
@@ -356,6 +397,13 @@ export default class LargeVideoManager {
356 397
         return this.videoContainer.id;
357 398
     }
358 399
 
400
+     /**
401
+     * Update large video.
402
+     * Switches to large video even if previously other container was visible.
403
+     * @param {JitsiTrack?} stream new stream
404
+     * @param {string?} videoType new video type
405
+     * @returns {Promise}
406
+     */
359 407
     updateLargeVideo (smallVideo, videoType, largeVideoUpdatedCallBack) {
360 408
         let id = getStreamId(smallVideo.stream);
361 409
 
@@ -380,16 +428,29 @@ export default class LargeVideoManager {
380 428
         });
381 429
     }
382 430
 
431
+    /**
432
+     * Update container size optionally taking side bar size into account.
433
+     * @param {boolean} isSideBarVisible if side bar is visible.
434
+     */
383 435
     updateContainerSize (isSideBarVisible) {
384 436
         this.width = UIUtil.getAvailableVideoWidth(isSideBarVisible);
385 437
         this.height = window.innerHeight;
386 438
     }
387 439
 
440
+    /**
441
+     * Resize Large container of specified type.
442
+     * @param {string} type type of container which should be resized.
443
+     * @param {boolean} [animate=false] if resize process should be animated.
444
+     */
388 445
     resizeContainer (type, animate = false) {
389 446
         let container = this.getContainer(type);
390 447
         container.resize(this.width, this.height, animate);
391 448
     }
392 449
 
450
+    /**
451
+     * Resize all Large containers.
452
+     * @param {boolean} animate if resize process should be animated.
453
+     */
393 454
     resize (animate) {
394 455
         // resize all containers
395 456
         Object.keys(this.containers)
@@ -420,11 +481,20 @@ export default class LargeVideoManager {
420 481
         $("#dominantSpeakerAvatar").attr('src', avatarUrl);
421 482
     }
422 483
 
484
+    /**
485
+     * Show avatar on Large video container or not.
486
+     * @param {boolean} show
487
+     */
423 488
     showAvatar (show) {
424 489
         show ? this.videoContainer.hide() : this.videoContainer.show();
425 490
         this.videoContainer.showAvatar(show);
426 491
     }
427 492
 
493
+    /**
494
+     * Add container of specified type.
495
+     * @param {string} type container type
496
+     * @param {LargeContainer} container container to add.
497
+     */
428 498
     addContainer (type, container) {
429 499
         if (this.containers[type]) {
430 500
             throw new Error(`container of type ${type} already exist`);
@@ -434,6 +504,11 @@ export default class LargeVideoManager {
434 504
         this.resizeContainer(type);
435 505
     }
436 506
 
507
+    /**
508
+     * Get Large container of specified type.
509
+     * @param {string} type container type.
510
+     * @returns {LargeContainer}
511
+     */
437 512
     getContainer (type) {
438 513
         let container = this.containers[type];
439 514
 
@@ -444,6 +519,10 @@ export default class LargeVideoManager {
444 519
         return container;
445 520
     }
446 521
 
522
+    /**
523
+     * Remove Large container of specified type.
524
+     * @param {string} type container type.
525
+     */
447 526
     removeContainer (type) {
448 527
         if (!this.containers[type]) {
449 528
             throw new Error(`container of type ${type} doesn't exist`);
@@ -452,6 +531,12 @@ export default class LargeVideoManager {
452 531
         delete this.containers[type];
453 532
     }
454 533
 
534
+    /**
535
+     * Show Large container of specified type.
536
+     * Does nothing if such container is already visible.
537
+     * @param {string} type container type.
538
+     * @returns {Promise}
539
+     */
455 540
     showContainer (type) {
456 541
         if (this.state === type) {
457 542
             return Promise.resolve();

+ 1
- 1
modules/UI/videolayout/VideoLayout.js 查看文件

@@ -997,7 +997,7 @@ var VideoLayout = {
997 997
                     // update current small video and the old one
998 998
                     smallVideo.updateView();
999 999
                     oldSmallVideo && oldSmallVideo.updateView();
1000
-                });
1000
+            });
1001 1001
 
1002 1002
         } else if (currentId) {
1003 1003
             let currentSmallVideo = this.getSmallVideo(currentId);

Loading…
取消
儲存