Bladeren bron

Merge branch 'master' into ssfocus

Conflicts:
	index.html
	muc.js
	videolayout.js
j8
paweldomas 11 jaren geleden
bovenliggende
commit
b035bfc9aa
23 gewijzigde bestanden met toevoegingen van 810 en 375 verwijderingen
  1. 53
    11
      app.js
  2. 150
    0
      avatar.js
  3. 2
    22
      bottom_toolbar.js
  4. 12
    130
      chat.js
  5. 31
    123
      contact_list.js
  6. 1
    0
      css/contact_list.css
  7. 4
    0
      css/font.css
  8. 1
    6
      css/main.css
  9. 45
    0
      css/settingsmenu.css
  10. 19
    5
      css/videolayout_default.css
  11. BIN
      fonts/jitsi.eot
  12. 1
    0
      fonts/jitsi.svg
  13. BIN
      fonts/jitsi.ttf
  14. BIN
      fonts/jitsi.woff
  15. 42
    7
      fonts/selection.json
  16. 33
    16
      index.html
  17. 3
    1
      interface_config.js
  18. 6
    4
      media_stream.js
  19. 14
    0
      muc.js
  20. 83
    0
      settings_menu.js
  21. 245
    0
      side_panel_toggler.js
  22. 3
    5
      util.js
  23. 62
    45
      videolayout.js

+ 53
- 11
app.js Bestand weergeven

@@ -10,7 +10,7 @@ var focusJid = null;
10 10
 var roomUrl = null;
11 11
 var roomName = null;
12 12
 var ssrc2jid = {};
13
-var mediaStreams = [];
13
+var mediaStreams = {};
14 14
 var bridgeIsDown = false;
15 15
 
16 16
 /**
@@ -108,9 +108,16 @@ function connect(jid, password) {
108 108
         localVideo = connection.jingle.localVideo;
109 109
     }
110 110
     connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind');
111
-
112
-    if (nickname) {
113
-        connection.emuc.addDisplayNameToPresence(nickname);
111
+    
112
+    var email = SettingsMenu.getEmail();
113
+    var displayName = SettingsMenu.getDisplayName();
114
+    if(email) {
115
+        connection.emuc.addEmailToPresence(email);
116
+    } else {
117
+        connection.emuc.addUserIdToPresence(SettingsMenu.getUID());
118
+    }
119
+    if(displayName) {
120
+        connection.emuc.addDisplayNameToPresence(displayName);
114 121
     }
115 122
 
116 123
     if (connection.disco) {
@@ -355,7 +362,12 @@ function waitForPresence(data, sid) {
355 362
     // NOTE(gp) now that we have simulcast, a media stream can have more than 1
356 363
     // ssrc. We should probably take that into account in our MediaStream
357 364
     // wrapper.
358
-    mediaStreams.push(new MediaStream(data, sid, thessrc));
365
+    var mediaStream = new MediaStream(data, sid, thessrc);
366
+    var jid = data.peerjid || connection.emuc.myroomjid;
367
+    if(!mediaStreams[jid]) {
368
+        mediaStreams[jid] = {};
369
+    }
370
+    mediaStreams[jid][mediaStream.type] = mediaStream;
359 371
 
360 372
     var container;
361 373
     var remotes = document.getElementById('remoteVideos');
@@ -392,6 +404,8 @@ function waitForPresence(data, sid) {
392 404
                                             data.stream,
393 405
                                             data.peerjid,
394 406
                                             thessrc);
407
+        if(isVideo && container.id !== 'mixedstream')
408
+             videoSrcToSsrc[$(container).find('>video')[0].src] = thessrc;
395 409
     }
396 410
 
397 411
     // an attempt to work around https://github.com/jitsi/jitmeet/issues/32
@@ -691,7 +705,7 @@ $(document).bind('joined.muc', function (event, jid, info) {
691 705
     );
692 706
 
693 707
     // Add myself to the contact list.
694
-    ContactList.addContact(jid);
708
+    ContactList.addContact(jid, SettingsMenu.getEmail() || SettingsMenu.getUID());
695 709
 
696 710
     // Once we've joined the muc show the toolbar
697 711
     ToolbarToggler.showToolbar();
@@ -718,7 +732,12 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
718 732
     }
719 733
 
720 734
     // Add Peer's container
721
-    VideoLayout.ensurePeerContainerExists(jid);
735
+    var id = $(pres).find('>userID').text();
736
+    var email = $(pres).find('>email');
737
+    if(email.length > 0) {
738
+        id = email.text();
739
+    }
740
+    VideoLayout.ensurePeerContainerExists(jid,id);
722 741
 
723 742
     if(APIConnector.isEnabled() && APIConnector.isEventEnabled("participantJoined"))
724 743
     {
@@ -845,6 +864,13 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
845 864
             "Jitsi Videobridge is currently unavailable. Please try again later!");
846 865
     }
847 866
 
867
+    var id = $(pres).find('>userID').text();
868
+    var email = $(pres).find('>email');
869
+    if(email.length > 0) {
870
+        id = email.text();
871
+    }
872
+    Avatar.setUserAvatar(jid, id);
873
+
848 874
 });
849 875
 
850 876
 $(document).bind('presence.status.muc', function (event, jid, info, pres) {
@@ -1310,15 +1336,20 @@ $(document).ready(function () {
1310 1336
         "showMethod": "fadeIn",
1311 1337
         "hideMethod": "fadeOut",
1312 1338
         "reposition": function() {
1313
-            if(Chat.isVisible() || ContactList.isVisible()) {
1314
-                $("#toast-container").addClass("toast-bottom-right-center");
1339
+            if(PanelToggler.isVisible()) {
1340
+                $("#toast-container").addClass("notification-bottom-right-center");
1315 1341
             } else {
1316
-                $("#toast-container").removeClass("toast-bottom-right-center");
1342
+                $("#toast-container").removeClass("notification-bottom-right-center");
1317 1343
             }
1318 1344
         },
1319 1345
         "newestOnTop": false
1320
-    }
1346
+    };
1321 1347
 
1348
+    $('#settingsmenu>input').keyup(function(event){
1349
+        if(event.keyCode === 13) {//enter
1350
+            SettingsMenu.update();
1351
+        }
1352
+    })
1322 1353
 
1323 1354
 });
1324 1355
 
@@ -1617,3 +1648,14 @@ function hangup() {
1617 1648
     );
1618 1649
 
1619 1650
 }
1651
+
1652
+$(document).on('videomuted.muc', function(event, jid, value) {
1653
+    if(mediaStreams[jid] && mediaStreams[jid][MediaStream.VIDEO_TYPE]) {
1654
+        var stream = mediaStreams[jid][MediaStream.VIDEO_TYPE];
1655
+        var isMuted = (value === "true");
1656
+        if (isMuted != stream.muted) {
1657
+            stream.muted = isMuted;
1658
+            Avatar.showUserAvatar(jid, isMuted);
1659
+        }
1660
+    }
1661
+});

+ 150
- 0
avatar.js Bestand weergeven

@@ -0,0 +1,150 @@
1
+var Avatar = (function(my) {
2
+    var users = {};
3
+    var activeSpeakerJid;
4
+    /**
5
+     * Sets the user's avatar in the settings menu(if local user), contact list
6
+     * and thumbnail
7
+     * @param jid jid of the user
8
+     * @param id email or userID to be used as a hash
9
+     */
10
+    my.setUserAvatar = function(jid, id) {
11
+        if(id) {
12
+            if(users[jid] === id) {
13
+                return;
14
+            }
15
+            users[jid] = id;
16
+        }
17
+        var url = getGravatarUrl(users[jid] || jid);
18
+        var resourceJid = Strophe.getResourceFromJid(jid);
19
+        var thumbnail = $('#participant_' + resourceJid);
20
+        var avatar = $('#avatar_' + resourceJid);
21
+
22
+        // set the avatar in the settings menu if it is local user and get the
23
+        // local video container
24
+        if(jid === connection.emuc.myroomjid) {
25
+            $('#avatar').get(0).src = url;
26
+            thumbnail = $('#localVideoContainer');
27
+        }
28
+
29
+        // set the avatar in the contact list
30
+        var contact = $('#' + resourceJid + '>img');
31
+        if(contact && contact.length > 0) {
32
+            contact.get(0).src = url;
33
+        }
34
+
35
+        // set the avatar in the thumbnail
36
+        if(avatar && avatar.length > 0) {
37
+            avatar[0].src = url;
38
+        } else {
39
+            if (thumbnail && thumbnail.length > 0) {
40
+                avatar = document.createElement('img');
41
+                avatar.id = 'avatar_' + resourceJid;
42
+                avatar.className = 'userAvatar';
43
+                avatar.src = url;
44
+                thumbnail.append(avatar);
45
+            }
46
+        }
47
+
48
+        //if the user is the current active speaker - update the active speaker
49
+        // avatar
50
+        if(jid === activeSpeakerJid) {
51
+            Avatar.updateActiveSpeakerAvatarSrc(jid);
52
+        }
53
+    };
54
+
55
+    /**
56
+     * Hides or shows the user's avatar
57
+     * @param jid jid of the user
58
+     * @param show whether we should show the avatar or not
59
+     * video because there is no dominant speaker and no focused speaker
60
+     */
61
+    my.showUserAvatar = function(jid, show) {
62
+        if(users[jid]) {
63
+            var resourceJid = Strophe.getResourceFromJid(jid);
64
+            var video = $('#participant_' + resourceJid + '>video');
65
+            var avatar = $('#avatar_' + resourceJid);
66
+
67
+            if(jid === connection.emuc.myroomjid) {
68
+                video = $('#localVideoWrapper>video');
69
+            }
70
+            if(show === undefined || show === null) {
71
+                show = isUserMuted(jid);
72
+            }
73
+
74
+            //if the user is the currently focused, the dominant speaker or if
75
+            //there is no focused and no dominant speaker
76
+            if (activeSpeakerJid === jid) {
77
+                setVisibility($("#largeVideo"), !show);
78
+                setVisibility($('#activeSpeakerAvatar'), show);
79
+                setVisibility(avatar, false);
80
+                setVisibility(video, false);
81
+            } else {
82
+                if (video && video.length > 0) {
83
+                    setVisibility(video, !show);
84
+                    setVisibility(avatar, show);
85
+                }
86
+            }
87
+        }
88
+    };
89
+
90
+    /**
91
+     * Updates the src of the active speaker avatar
92
+     * @param jid of the current active speaker
93
+     */
94
+    my.updateActiveSpeakerAvatarSrc = function(jid) {
95
+        if(!jid) {
96
+            if (focusedVideoSrc) {
97
+                jid = getJidFromVideoSrc(focusedVideoSrc);
98
+            } else {
99
+                jid = connection.emuc.findJidFromResource(
100
+                    VideoLayout.getDominantSpeakerResourceJid());
101
+            }
102
+        }
103
+        var avatar = $("#activeSpeakerAvatar")[0];
104
+        var url = getGravatarUrl(users[jid],
105
+            interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE);
106
+        if(jid === activeSpeakerJid && avatar.src === url) {
107
+            return;
108
+        }
109
+        activeSpeakerJid = jid;
110
+        var isMuted = isUserMuted(jid);
111
+        if(jid && isMuted !== null) {
112
+            avatar.src = url;
113
+            setVisibility($("#largeVideo"), !isMuted);
114
+            Avatar.showUserAvatar(jid, isMuted);
115
+        }
116
+    };
117
+
118
+    function setVisibility(selector, show) {
119
+        if (selector && selector.length > 0) {
120
+            selector.css("visibility", show ? "visible" : "hidden");
121
+        }
122
+    }
123
+
124
+    function isUserMuted(jid) {
125
+        // XXX(gp) we may want to rename this method to something like
126
+        // isUserStreaming, for example.
127
+        if (jid && jid != connection.emuc.myroomjid) {
128
+            var resource = Strophe.getResourceFromJid(jid);
129
+            if (!VideoLayout.isInLastN(resource)) {
130
+                return true;
131
+            }
132
+        }
133
+
134
+        if (!mediaStreams[jid] || !mediaStreams[jid][MediaStream.VIDEO_TYPE]) {
135
+            return null;
136
+        }
137
+        return mediaStreams[jid][MediaStream.VIDEO_TYPE].muted;
138
+    }
139
+
140
+    function getGravatarUrl(id, size) {
141
+        if(id === connection.emuc.myroomjid || !id) {
142
+            id = SettingsMenu.getUID();
143
+        }
144
+        return 'https://www.gravatar.com/avatar/' +
145
+            MD5.hexdigest(id.trim().toLowerCase()) +
146
+            "?d=retro&size=" + (size || "30");
147
+    }
148
+
149
+    return my;
150
+}(Avatar || {}));

+ 2
- 22
bottom_toolbar.js Bestand weergeven

@@ -1,30 +1,10 @@
1 1
 var BottomToolbar = (function (my) {
2 2
     my.toggleChat = function() {
3
-        if (ContactList.isVisible()) {
4
-            buttonClick("#contactListButton", "active");
5
-            $('#contactlist').css('z-index', 4);
6
-            setTimeout(function() {
7
-                $('#contactlist').css('display', 'none');
8
-                $('#contactlist').css('z-index', 5);
9
-            }, 500);
10
-        }
11
-
12
-        Chat.toggleChat();
13
-
14
-        buttonClick("#chatBottomButton", "active");
3
+        PanelToggler.toggleChat();
15 4
     };
16 5
 
17 6
     my.toggleContactList = function() {
18
-        if (Chat.isVisible()) {
19
-            buttonClick("#chatBottomButton", "active");
20
-            setTimeout(function() {
21
-                $('#chatspace').css('display', 'none');
22
-            }, 500);
23
-        }
24
-
25
-        buttonClick("#contactListButton", "active");
26
-
27
-        ContactList.toggleContactList();
7
+        PanelToggler.toggleContactList();
28 8
     };
29 9
 
30 10
     my.toggleFilmStrip = function() {

+ 12
- 130
chat.js Bestand weergeven

@@ -57,7 +57,7 @@ var Chat = (function (my) {
57 57
 
58 58
         var onTextAreaResize = function () {
59 59
             resizeChatConversation();
60
-            scrollChatToBottom();
60
+            Chat.scrollChatToBottom();
61 61
         };
62 62
         $('#usermsg').autosize({callback: onTextAreaResize});
63 63
 
@@ -144,112 +144,7 @@ var Chat = (function (my) {
144 144
         }
145 145
     };
146 146
 
147
-    /**
148
-     * Opens / closes the chat area.
149
-     */
150
-    my.toggleChat = function () {
151
-        var chatspace = $('#chatspace');
152
-        var videospace = $('#videospace');
153
-
154
-        var chatSize = (Chat.isVisible()) ? [0, 0] : Chat.getChatSize();
155
-        var videospaceWidth = window.innerWidth - chatSize[0];
156
-        var videospaceHeight = window.innerHeight;
157
-        var videoSize
158
-            = getVideoSize(null, null, videospaceWidth, videospaceHeight);
159
-        var videoWidth = videoSize[0];
160
-        var videoHeight = videoSize[1];
161
-        var videoPosition = getVideoPosition(videoWidth,
162
-                                             videoHeight,
163
-                                             videospaceWidth,
164
-                                             videospaceHeight);
165
-        var horizontalIndent = videoPosition[0];
166
-        var verticalIndent = videoPosition[1];
167
-
168
-        var thumbnailSize = VideoLayout.calculateThumbnailSize(videospaceWidth);
169
-        var thumbnailsWidth = thumbnailSize[0];
170
-        var thumbnailsHeight = thumbnailSize[1];
171
-        var completeFunction = Chat.isVisible() ?
172
-            function() {} : function () {
173
-                                scrollChatToBottom();
174
-                                chatspace.trigger('shown');
175
-                            };
176
-
177
-        videospace.animate({right: chatSize[0],
178
-                            width: videospaceWidth,
179
-                            height: videospaceHeight},
180
-                            {queue: false,
181
-                            duration: 500,
182
-                            complete: completeFunction});
183
-
184
-        $('#remoteVideos').animate({height: thumbnailsHeight},
185
-                                    {queue: false,
186
-                                    duration: 500});
187
-
188
-        $('#remoteVideos>span').animate({height: thumbnailsHeight,
189
-                                        width: thumbnailsWidth},
190
-                                        {queue: false,
191
-                                        duration: 500,
192
-                                        complete: function() {
193
-                                            $(document).trigger(
194
-                                                    "remotevideo.resized",
195
-                                                    [thumbnailsWidth,
196
-                                                     thumbnailsHeight]);
197
-                                        }});
198
-
199
-        $('#largeVideoContainer').animate({ width: videospaceWidth,
200
-                                            height: videospaceHeight},
201
-                                            {queue: false,
202
-                                             duration: 500
203
-                                            });
204
-
205
-        $('#largeVideo').animate({  width: videoWidth,
206
-                                    height: videoHeight,
207
-                                    top: verticalIndent,
208
-                                    bottom: verticalIndent,
209
-                                    left: horizontalIndent,
210
-                                    right: horizontalIndent},
211
-                                    {   queue: false,
212
-                                        duration: 500
213
-                                    }
214
-        );
215
-
216
-        if (Chat.isVisible()) {
217
-            $("#toast-container").animate({right: '5px'},
218
-                                {queue: false,
219
-                                duration: 500});
220
-            chatspace.hide("slide", { direction: "right",
221
-                                            queue: false,
222
-                                            duration: 500});
223 147
 
224
-        }
225
-        else {
226
-            // Undock the toolbar when the chat is shown and if we're in a 
227
-            // video mode.
228
-            if (VideoLayout.isLargeVideoVisible()) {
229
-                ToolbarToggler.dockToolbar(false);
230
-            }
231
-
232
-
233
-            $("#toast-container").animate({right: (chatSize[0] + 5) + 'px'},
234
-                {queue: false,
235
-                    duration: 500});
236
-            chatspace.show("slide", { direction: "right",
237
-                                            queue: false,
238
-                                            duration: 500,
239
-                                            complete: function () {
240
-                                                // Request the focus in the nickname field or the chat input field.
241
-                                                if ($('#nickname').css('visibility') === 'visible') {
242
-                                                    $('#nickinput').focus();
243
-                                                } else {
244
-                                                    $('#usermsg').focus();
245
-                                                }
246
-                                            }
247
-            });
248
-
249
-            Chat.resizeChat();
250
-        }
251
-
252
-    };
253 148
 
254 149
     /**
255 150
      * Sets the chat conversation mode.
@@ -268,7 +163,7 @@ var Chat = (function (my) {
268 163
      * Resizes the chat area.
269 164
      */
270 165
     my.resizeChat = function () {
271
-        var chatSize = Chat.getChatSize();
166
+        var chatSize = PanelToggler.getPanelSize();
272 167
 
273 168
         $('#chatspace').width(chatSize[0]);
274 169
         $('#chatspace').height(chatSize[1]);
@@ -276,20 +171,6 @@ var Chat = (function (my) {
276 171
         resizeChatConversation();
277 172
     };
278 173
 
279
-    /**
280
-     * Returns the size of the chat.
281
-     */
282
-    my.getChatSize = function () {
283
-        var availableHeight = window.innerHeight;
284
-        var availableWidth = window.innerWidth;
285
-
286
-        var chatWidth = 200;
287
-        if (availableWidth * 0.2 < 200)
288
-            chatWidth = availableWidth * 0.2;
289
-
290
-        return [chatWidth, availableHeight];
291
-    };
292
-
293 174
     /**
294 175
      * Indicates if the chat is currently visible.
295 176
      */
@@ -309,6 +190,16 @@ var Chat = (function (my) {
309 190
         $('#usermsg').focus();
310 191
     };
311 192
 
193
+    /**
194
+     * Scrolls chat to the bottom.
195
+     */
196
+    my.scrollChatToBottom = function() {
197
+        setTimeout(function () {
198
+            $('#chatconversation').scrollTop(
199
+                $('#chatconversation')[0].scrollHeight);
200
+        }, 5);
201
+    };
202
+
312 203
     /**
313 204
      * Adds the smileys container to the chat
314 205
      */
@@ -426,15 +317,6 @@ var Chat = (function (my) {
426 317
         }
427 318
     }
428 319
 
429
-    /**
430
-     * Scrolls chat to the bottom.
431
-     */
432
-    function scrollChatToBottom() {
433
-        setTimeout(function () {
434
-            $('#chatconversation').scrollTop(
435
-                    $('#chatconversation')[0].scrollHeight);
436
-        }, 5);
437
-    }
438 320
 
439 321
     /**
440 322
      * Returns the current time in the format it is shown to the user

+ 31
- 123
contact_list.js Bestand weergeven

@@ -20,22 +20,24 @@ var ContactList = (function (my) {
20 20
      * Adds a contact for the given peerJid if such doesn't yet exist.
21 21
      *
22 22
      * @param peerJid the peerJid corresponding to the contact
23
+     * @param id the user's email or userId used to get the user's avatar
23 24
      */
24
-    my.ensureAddContact = function(peerJid) {
25
+    my.ensureAddContact = function(peerJid, id) {
25 26
         var resourceJid = Strophe.getResourceFromJid(peerJid);
26 27
 
27 28
         var contact = $('#contactlist>ul>li[id="' + resourceJid + '"]');
28 29
 
29 30
         if (!contact || contact.length <= 0)
30
-            ContactList.addContact(peerJid);
31
+            ContactList.addContact(peerJid,id);
31 32
     };
32 33
 
33 34
     /**
34 35
      * Adds a contact for the given peer jid.
35 36
      *
36 37
      * @param peerJid the jid of the contact to add
38
+     * @param id the email or userId of the user
37 39
      */
38
-    my.addContact = function(peerJid) {
40
+    my.addContact = function(peerJid, id) {
39 41
         var resourceJid = Strophe.getResourceFromJid(peerJid);
40 42
 
41 43
         var contactlist = $('#contactlist>ul');
@@ -51,7 +53,7 @@ var ContactList = (function (my) {
51 53
             }
52 54
         };
53 55
 
54
-        newContact.appendChild(createAvatar());
56
+        newContact.appendChild(createAvatar(id));
55 57
         newContact.appendChild(createDisplayNameParagraph("Participant"));
56 58
 
57 59
         var clElement = contactlist.get(0);
@@ -87,95 +89,27 @@ var ContactList = (function (my) {
87 89
         }
88 90
     };
89 91
 
90
-    /**
91
-     * Opens / closes the contact list area.
92
-     */
93
-    my.toggleContactList = function () {
94
-        var contactlist = $('#contactlist');
95
-        var videospace = $('#videospace');
96
-
97
-        var chatSize = (ContactList.isVisible()) ? [0, 0] : Chat.getChatSize();
98
-        var videospaceWidth = window.innerWidth - chatSize[0];
99
-        var videospaceHeight = window.innerHeight;
100
-        var videoSize
101
-            = getVideoSize(null, null, videospaceWidth, videospaceHeight);
102
-        var videoWidth = videoSize[0];
103
-        var videoHeight = videoSize[1];
104
-        var videoPosition = getVideoPosition(videoWidth,
105
-                                             videoHeight,
106
-                                             videospaceWidth,
107
-                                             videospaceHeight);
108
-        var horizontalIndent = videoPosition[0];
109
-        var verticalIndent = videoPosition[1];
110
-
111
-        var thumbnailSize = VideoLayout.calculateThumbnailSize(videospaceWidth);
112
-        var thumbnailsWidth = thumbnailSize[0];
113
-        var thumbnailsHeight = thumbnailSize[1];
114
-        var completeFunction = ContactList.isVisible() ?
115
-            function() {} : function () { contactlist.trigger('shown');};
116
-
117
-        videospace.animate({right: chatSize[0],
118
-                            width: videospaceWidth,
119
-                            height: videospaceHeight},
120
-                            {queue: false,
121
-                            duration: 500,
122
-                            complete: completeFunction
123
-                            });
124
-
125
-        $('#remoteVideos').animate({height: thumbnailsHeight},
126
-                                    {queue: false,
127
-                                    duration: 500});
128
-
129
-        $('#remoteVideos>span').animate({height: thumbnailsHeight,
130
-                                        width: thumbnailsWidth},
131
-                                        {queue: false,
132
-                                        duration: 500,
133
-                                        complete: function() {
134
-                                            $(document).trigger(
135
-                                                    "remotevideo.resized",
136
-                                                    [thumbnailsWidth,
137
-                                                     thumbnailsHeight]);
138
-                                        }});
139
-
140
-        $('#largeVideoContainer').animate({ width: videospaceWidth,
141
-                                            height: videospaceHeight},
142
-                                            {queue: false,
143
-                                             duration: 500
144
-                                            });
145
-
146
-        $('#largeVideo').animate({  width: videoWidth,
147
-                                    height: videoHeight,
148
-                                    top: verticalIndent,
149
-                                    bottom: verticalIndent,
150
-                                    left: horizontalIndent,
151
-                                    right: horizontalIndent},
152
-                                    {   queue: false,
153
-                                        duration: 500
154
-                                    });
155
-
156
-        if (ContactList.isVisible()) {
157
-            $("#toast-container").animate({right: '12px'},
158
-                {queue: false,
159
-                    duration: 500});
160
-            $('#contactlist').hide("slide", { direction: "right",
161
-                                            queue: false,
162
-                                            duration: 500});
163
-        } else {
164
-            // Undock the toolbar when the chat is shown and if we're in a 
165
-            // video mode.
166
-            if (VideoLayout.isLargeVideoVisible())
167
-                ToolbarToggler.dockToolbar(false);
168
-
169
-
170
-            $("#toast-container").animate({right: '212px'},
171
-                {queue: false,
172
-                    duration: 500});
173
-            $('#contactlist').show("slide", { direction: "right",
174
-                                            queue: false,
175
-                                            duration: 500});
92
+    my.setVisualNotification = function(show, stopGlowingIn) {
93
+        var glower = $('#contactListButton');
94
+        function stopGlowing() {
95
+            window.clearInterval(notificationInterval);
96
+            notificationInterval = false;
97
+            glower.removeClass('glowing');
98
+            if(!ContactList.isVisible()) {
99
+                glower.removeClass('active');
100
+            }
101
+        }
176 102
 
177
-            //stop the glowing of the contact list icon
178
-            setVisualNotification(false);
103
+        if (show && !notificationInterval) {
104
+            notificationInterval = window.setInterval(function () {
105
+                glower.toggleClass('active glowing');
106
+            }, 800);
107
+        }
108
+        else if (!show && notificationInterval) {
109
+            stopGlowing();
110
+        }
111
+        if(stopGlowingIn) {
112
+            setTimeout(stopGlowing, stopGlowingIn);
179 113
         }
180 114
     };
181 115
 
@@ -191,20 +125,21 @@ var ContactList = (function (my) {
191 125
             $("#numberOfParticipants").text('');
192 126
             numberOfContacts += delta;
193 127
         } else if(numberOfContacts !== 0 && !ContactList.isVisible()) {
194
-            setVisualNotification(true);
128
+            ContactList.setVisualNotification(true);
195 129
             numberOfContacts += delta;
196 130
             $("#numberOfParticipants").text(numberOfContacts);
197 131
         }
198
-    };
132
+    }
199 133
 
200 134
     /**
201 135
      * Creates the avatar element.
202 136
      * 
203 137
      * @return the newly created avatar element
204 138
      */
205
-    function createAvatar() {
206
-        var avatar = document.createElement('i');
139
+    function createAvatar(id) {
140
+        var avatar = document.createElement('img');
207 141
         avatar.className = "icon-avatar avatar";
142
+        avatar.src = "https://www.gravatar.com/avatar/" + id + "?d=retro&size=30";
208 143
 
209 144
         return avatar;
210 145
     }
@@ -221,33 +156,6 @@ var ContactList = (function (my) {
221 156
         return p;
222 157
     }
223 158
 
224
-    /**
225
-     * Shows/hides a visual notification, indicating that a new user has joined
226
-     * the conference.
227
-     */
228
-    function setVisualNotification(show, stopGlowingIn) {
229
-        var glower = $('#contactListButton');
230
-        function stopGlowing() {
231
-            window.clearInterval(notificationInterval);
232
-            notificationInterval = false;
233
-            glower.removeClass('glowing');
234
-            if(!ContactList.isVisible()) {
235
-                glower.removeClass('active');
236
-            }
237
-        }
238
-
239
-        if (show && !notificationInterval) {
240
-            notificationInterval = window.setInterval(function () {
241
-                glower.toggleClass('active glowing');
242
-            }, 800);
243
-        }
244
-        else if (!show && notificationInterval) {
245
-            stopGlowing();
246
-        }
247
-        if(stopGlowingIn) {
248
-            setTimeout(stopGlowing, stopGlowingIn);
249
-        }
250
-    }
251 159
 
252 160
     /**
253 161
      * Indicates that the display name has changed.

+ 1
- 0
css/contact_list.css Bestand weergeven

@@ -34,6 +34,7 @@
34 34
     margin-right: 10px;
35 35
     vertical-align: middle;
36 36
     font-size: 22pt;
37
+    border-radius: 20px;
37 38
 }
38 39
 
39 40
 #contactlist .clickable {

+ 4
- 0
css/font.css Bestand weergeven

@@ -112,4 +112,8 @@
112 112
 .icon-connection:before {
113 113
     line-height: normal;
114 114
     content: "\e61a";
115
+}
116
+
117
+.icon-settings:before {
118
+    content: "\e61b";
115 119
 }

+ 1
- 6
css/main.css Bestand weergeven

@@ -13,8 +13,7 @@ html, body{
13 13
     overflow-x: hidden;
14 14
 }
15 15
 
16
-#chatspace,
17
-#contactlist {
16
+.right-panel {
18 17
     display:none;
19 18
     position:absolute;
20 19
     float: right;
@@ -38,10 +37,6 @@ html, body{
38 37
     display:none;
39 38
 }
40 39
 
41
-#settingsButton {
42
-    visibility: hidden;
43
-}
44
-
45 40
 .toolbar_span {
46 41
     display: inline-block;
47 42
     position: relative;

+ 45
- 0
css/settingsmenu.css Bestand weergeven

@@ -0,0 +1,45 @@
1
+#settingsmenu {
2
+    background: black;
3
+    color: #00ccff;
4
+}
5
+
6
+#settingsmenu input {
7
+    margin-top: 10px;
8
+    margin-left: 10%;
9
+    width: 80%;
10
+    font-size: 14px;
11
+    background: #3a3a3a;
12
+    border: none;
13
+    box-shadow: none;
14
+    color: #a7a7a7;
15
+}
16
+
17
+#settingsmenu .arrow-up {
18
+    width: 0;
19
+    height: 0;
20
+    border-left: 5px solid transparent;
21
+    border-right: 5px solid transparent;
22
+    border-bottom: 5px solid #3a3a3a;
23
+    position: relative;
24
+    top: 10px;
25
+    margin-left: auto;
26
+    margin-right: auto;
27
+}
28
+
29
+#settingsmenu button {
30
+    width: 36%;
31
+    left: 32%;
32
+    padding: 0;
33
+    margin-top: 10px;
34
+}
35
+
36
+#settingsmenu #avatar {
37
+    width: 24%;
38
+    left: 38%;
39
+    border-radius: 25px;
40
+    position: relative;
41
+}
42
+
43
+#settingsmenu .icon-settings {
44
+    padding: 34px;
45
+}

+ 19
- 5
css/videolayout_default.css Bestand weergeven

@@ -35,7 +35,9 @@
35 35
 
36 36
 #remoteVideos .videocontainer {
37 37
     display: inline-block;
38
-    background-image:url(../images/avatar1.png);
38
+    background-color: black;
39
+    background-repeat: no-repeat;
40
+    background-position: 45;
39 41
     background-size: contain;
40 42
     border-radius:8px;
41 43
     border: 2px solid #212425;
@@ -115,10 +117,6 @@
115 117
     height: 100%;
116 118
 }
117 119
 
118
-.dominantspeaker {
119
-    background: #000 !important;
120
-}
121
-
122 120
 #etherpad,
123 121
 #presentation {
124 122
     text-align: center;
@@ -378,3 +376,19 @@
378 376
 #mixedstream {
379 377
     display:none !important;
380 378
 }
379
+
380
+#activeSpeakerAvatar {
381
+    visibility: hidden;
382
+    width: 100px;
383
+    height: 100px;
384
+    margin: auto;
385
+    position: relative;
386
+    border-radius: 50px;
387
+}
388
+
389
+.userAvatar {
390
+    height: 100%;
391
+    position: absolute;
392
+    left: 35px;
393
+    border-radius: 200px;
394
+}

BIN
fonts/jitsi.eot Bestand weergeven


+ 1
- 0
fonts/jitsi.svg Bestand weergeven

@@ -34,4 +34,5 @@
34 34
 <glyph unicode="&#xe618;" d="M797.086 112.301c-0.059 0.163-0.119 0.328-0.16 0.485-71.399-45.638-151.782-69.931-234.023-69.931-0.013 0-0.021 0-0.028 0-122.52 0-237.501 52.772-315.469 144.741-99.778 117.698-134.252 329.954-73.022 427.789 4.004-1.662 7.875-3.233 11.68-4.773 13.585-5.511 26.413-10.716 42.305-19.096 6.063-3.202 12.338-4.812 18.673-4.812 11.714 0 22.6 5.648 29.848 15.486 7.815 10.617 10.313 24.778 6.538 36.951l-3.525 11.41c-10.687 34.59-21.723 70.354-34.211 105.078-9.983 27.765-22.399 62.327-59.226 62.327-12.057 0-26.037-3.656-46.73-12.204-44.294-18.319-71.058-29.961-114.534-49.81-15.102-6.887-25.234-22.698-25.203-39.343 0.028-15.842 8.992-29.337 23.975-36.115 18.208-8.257 30.536-13.716 43.468-19.447l10.687-4.753c-101.938-259.102 24.803-526.458 211.314-639.212 83.497-50.474 178.5-77.14 274.769-77.14h0.041c102.72 0 205.561 31.099 284.501 85.198-31.729 28.803-45.566 69.167-51.671 87.171zM1098.203 210.090c-18.113 8.577-30.356 14.258-43.221 20.244l-10.496 4.892c106.448 257.268-15.569 526.801-200.067 642.788-85.36 53.663-183.123 82.032-282.716 82.032-104.848 0-206.41-30.593-285.967-86.165l-5.385-3.764c31.597-27.564 45.86-66.788 52.917-86.41 72.926 47.94 155.675 73.409 239.895 73.409 125.407 0 242.142-54.785 320.294-150.316 97.683-119.447 128.439-332.255 65.498-429.015-3.989 1.736-7.815 3.385-11.624 4.998-13.471 5.759-26.204 11.18-41.954 19.821-6.203 3.424-12.645 5.155-19.212 5.155-11.585 0-22.399-5.558-29.69-15.267-7.813-10.434-10.478-24.432-6.966-36.515l3.279-11.301c10.096-34.845 20.531-70.857 32.412-105.842 9.588-28.238 21.514-63.382 59.179-63.382 11.843 0 25.577 3.424 45.881 11.399 44.351 17.439 71.319 28.601 115.409 47.777 15.19 6.623 25.601 22.252 25.859 38.894 0.281 15.822-8.445 29.499-23.325 36.569z" horiz-adv-x="1122" />
35 35
 <glyph unicode="&#xe619;" d="M46.993 961.7c461.234 0 553.793 0 1015.024 0 35.919 0 53.356-25.959 53.356-57.959-0.581-303.259-0.325-606.488-0.449-909.809 0-43.984-13.203-57.058-57.703-57.058-443.072-0.126-556.453-0.126-999.553 0-44.534 0-57.799 13.009-57.799 57.058-0.098 303.257 0.485 608.072-0.093 911.329-0.034 26.21 11.301 53.761 47.217 56.439zM311.405 450.298c0-119.045-0.072-172.168 0.057-291.249 0.036-50.043 11.208-61.050 62.12-61.050 233.352 0 137.075 0 370.522 0 47.075 0 59.249 11.982 59.249 58.095 0.126 239.111 0.126 346.338 0 585.389 0 48.138-10.687 58.991-57.768 58.991-235.323 0.101-140.844 0.101-376.157 0-47.044 0-57.93-11.043-57.966-58.89-0.129-119.109-0.057-172.209-0.057-291.287zM153.944 838.566c-74.929-0.062-66.687 5.958-66.845-66.685-0.201-63.95-7.054-63.534 62.528-63.372 72.999 0.194 67.201-3.764 67.302 67.554 0 67.722 4.087 62.595-62.985 62.502zM963.644 838.566c-71.159-0.034-65.56 6.185-65.751-65.364-0.129-67.302-4.508-64.693 64.528-64.693 73.089 0 65.299-2.031 65.299 66.238-0.003 68.646 6.956 63.911-64.076 63.818zM216.828 122.408c0.359 73.094 4.639 66.914-67.358 67.17-68.104 0.191-62.569 2.763-62.407-63.31 0.129-73.476-6.954-66.52 67.074-66.649 66.042-0.065 63.142-6.056 62.691 62.789zM1027.718 124.4c0.134 68.334 6.443 65.304-63.297 65.178-70.132-0.132-66.656 5.793-66.527-65.304 0.129-70.645-4.384-64.721 63.756-64.657 71.995 0.132 66.202-6.698 66.068 64.783zM1027.718 342.077c0 70.55 7.219 66.842-67.485 66.522-0.898 0-1.873 0-2.838 0-59.375 0-59.375 0-59.375-58.023 0-77.922-6.443-69.936 69.293-70.196 66.076-0.387 60.539-3.091 60.405 61.697zM151.307 489.873c68.295-0.163 65.815-5.568 65.624 62.982-0.194 71.128 4.895 64.917-66.014 65.010-69.905 0.101-63.813 4.704-63.885-63.978-0.062-67.431-5.7-64.463 64.275-64.014zM961.263 489.873c72.511-0.258 66.589-4.603 66.455 64.494 0 68.558 6.185 63.537-64.267 63.498-70.196-0.028-65.686 6.053-65.498-65.493 0.132-62.5 0.067-62.5 63.31-62.5zM150.399 280.38c71.004 0 66.659-6.567 66.466 64.528-0.163 63.694-0.036 63.501-65.013 63.756-70.805 0.258-64.822 2.673-64.822-63.756 0.036-69.167-5.919-64.788 63.369-64.528z" horiz-adv-x="1115" />
36 36
 <glyph unicode="&#xe61a;" d="M3.881 146.835h220.26v-210.835h-220.26v210.835zM308.817 350.143h220.27v-414.143h-220.27v414.143zM613.764 553.412h220.268v-617.412h-220.268v617.412zM918.685 756.715h220.265v-820.715h-220.265v820.715zM1223.629 960h220.263v-1024h-220.263v1024z" horiz-adv-x="1444" />
37
+<glyph unicode="&#xe61b;" d="M526.071 234.749c-28.637-30.869-56.465-60.861-84.282-90.859-51.578-55.636-103.047-111.376-154.842-166.832-7.606-8.135-15.958-16.1-25.317-22.012-28.075-17.708-58.31-18.090-88.472-6.492-59.84 23.028-80.004 90.727-59.734 139.234 5.413 12.95 13.721 23.601 23.709 33.173 70.256 67.351 140.506 134.717 210.76 202.077 15.638 14.993 31.264 29.995 47.364 45.45-9.302 9.529-18.386 18.833-27.451 28.137-12.122 12.442-13.234 20.28-5.067 35.498 4.735 8.816 4.789 8.878-2.627 16.198-20.012 19.72-40.168 39.198-63.498 55.188-27.167 18.624-57.161 24.233-89.083 19.849-53.402-7.328-91.609-38.372-121.413-81.046-12.774-18.299-15.365-40.313-17.517-61.875-3.23-32.245-2.415-64.479 2.209-96.597 1.654-11.515-3.863-16.539-13.835-11.175-8.306 4.448-16.095 11.048-22.115 18.353-15.574 18.89-22.223 42.042-27.474 65.395-12.955 57.652-8.86 114.49 12.191 169.495 32.345 84.537 79.743 159.571 145.953 221.932 13.659 12.857 176.841 180.564 202.944 207.021 7.493 7.599 14.895 7.635 22.393 0.028 43.009-43.641 85.985-87.316 128.927-131.029 8.117-8.267 8.019-15.097-0.222-23.49-26.339-26.834-52.726-53.627-79.106-80.419-6.244-6.334-97.34-82.437-73.027-128.816 22.693-25.090 46.196-49.449 69.575-73.904 1.189-1.238 4.686-1.386 6.523-0.632 3.63 1.499 6.848 3.997 10.248 6.066 9.745 5.94 19.545 4.918 27.812-3.083 11.755-11.381 23.405-22.858 35.392-34.59 4.807 4.575 9.939 9.41 15.027 14.294 27.128 26.039 54.272 52.071 81.351 78.146 16.413 15.778 18.652 28.418 11.038 49.658-10.473 29.221-14.356 59.677-13.85 90.624 1.017 61.045 20.438 115.334 61.003 161.416 32.825 37.286 72.054 64.311 121.643 74.325 35.227 7.101 69.139 4.513 100.663-14.026 6.365-3.752 11.908-9.007 17.455-14.005 3.491-3.125 3.153-6.236-0.565-9.98-42.503-42.885-84.772-86.013-127.154-129.035-12.442-12.638-12.356-23.167 0.196-35.914 40.344-40.978 80.597-82.050 120.936-123.052 10.076-10.233 19.537-10.021 29.504 0.134 43.195 44.077 86.449 88.090 129.706 132.118 1.21 1.233 2.572 2.322 5.135 4.624 5.491-5.893 11.895-10.924 15.961-17.406 19.452-30.944 22.608-64.83 17.073-100.25-14.253-91.080-97.188-175.638-197.712-190.123-39.977-5.764-79.372-2.562-118.067 9.031-5.898 1.775-11.541 4.629-17.538 5.829-12.47 2.474-23.872-0.366-32.74-9.877-30.921-33.168-61.674-66.484-92.474-99.758-0.73-0.805-1.349-1.718-0.181-1.099 8.992-10.006 17.354-20.662 27.061-29.94 81.064-77.54 164.91-151.986 250.882-224.063 9.936-8.347 10.274-15.695 1.040-25.1-42.338-43.068-84.689-86.111-127.059-129.154-9.413-9.575-16.846-9.152-25.291 1.295-76.686 94.78-156.8 186.609-239.707 276.002-1.334 1.453-2.562 3.029-4.257 5.042z" horiz-adv-x="1105" />
37 38
 </font></defs></svg>

BIN
fonts/jitsi.ttf Bestand weergeven


BIN
fonts/jitsi.woff Bestand weergeven


+ 42
- 7
fonts/selection.json Bestand weergeven

@@ -1,12 +1,46 @@
1 1
 {
2 2
 	"IcoMoonType": "selection",
3 3
 	"icons": [
4
+		{
5
+			"icon": {
6
+				"paths": [
7
+					"M526.071 725.251c-28.637 30.869-56.465 60.861-84.282 90.859-51.578 55.636-103.047 111.376-154.842 166.832-7.606 8.135-15.958 16.1-25.317 22.012-28.075 17.708-58.31 18.090-88.472 6.492-59.84-23.028-80.004-90.727-59.734-139.234 5.413-12.95 13.721-23.601 23.709-33.173 70.256-67.351 140.506-134.717 210.76-202.077 15.638-14.993 31.264-29.995 47.364-45.45-9.302-9.529-18.386-18.833-27.451-28.137-12.122-12.442-13.234-20.28-5.067-35.498 4.735-8.816 4.789-8.878-2.627-16.198-20.012-19.72-40.168-39.198-63.498-55.188-27.167-18.624-57.161-24.233-89.083-19.849-53.402 7.328-91.609 38.372-121.413 81.046-12.774 18.299-15.365 40.313-17.517 61.875-3.23 32.245-2.415 64.479 2.209 96.597 1.654 11.515-3.863 16.539-13.835 11.175-8.306-4.448-16.095-11.048-22.115-18.353-15.574-18.89-22.223-42.042-27.474-65.395-12.955-57.652-8.86-114.49 12.191-169.495 32.345-84.537 79.743-159.571 145.953-221.932 13.659-12.857 176.841-180.564 202.944-207.021 7.493-7.599 14.895-7.635 22.393-0.028 43.009 43.641 85.985 87.316 128.927 131.029 8.117 8.267 8.019 15.097-0.222 23.49-26.339 26.834-52.726 53.627-79.106 80.419-6.244 6.334-97.34 82.437-73.027 128.816 22.693 25.090 46.196 49.449 69.575 73.904 1.189 1.238 4.686 1.386 6.523 0.632 3.63-1.499 6.848-3.997 10.248-6.066 9.745-5.94 19.545-4.918 27.812 3.083 11.755 11.381 23.405 22.858 35.392 34.59 4.807-4.575 9.939-9.41 15.027-14.294 27.128-26.039 54.272-52.071 81.351-78.146 16.413-15.778 18.652-28.418 11.038-49.658-10.473-29.221-14.356-59.677-13.85-90.624 1.017-61.045 20.438-115.334 61.003-161.416 32.825-37.286 72.054-64.311 121.643-74.325 35.227-7.101 69.139-4.513 100.663 14.026 6.365 3.752 11.908 9.007 17.455 14.005 3.491 3.125 3.153 6.236-0.565 9.98-42.503 42.885-84.772 86.013-127.154 129.035-12.442 12.638-12.356 23.167 0.196 35.914 40.344 40.978 80.597 82.050 120.936 123.052 10.076 10.233 19.537 10.021 29.504-0.134 43.195-44.077 86.449-88.090 129.706-132.118 1.21-1.233 2.572-2.322 5.135-4.624 5.491 5.893 11.895 10.924 15.961 17.406 19.452 30.944 22.608 64.83 17.073 100.25-14.253 91.080-97.188 175.638-197.712 190.123-39.977 5.764-79.372 2.562-118.067-9.031-5.898-1.775-11.541-4.629-17.538-5.829-12.47-2.474-23.872 0.366-32.74 9.877-30.921 33.168-61.674 66.484-92.474 99.758-0.73 0.805-1.349 1.718-0.181 1.099 8.992 10.006 17.354 20.662 27.061 29.94 81.064 77.54 164.91 151.986 250.882 224.063 9.936 8.347 10.274 15.695 1.040 25.1-42.338 43.068-84.689 86.111-127.059 129.154-9.413 9.575-16.846 9.152-25.291-1.295-76.686-94.78-156.8-186.609-239.707-276.002-1.334-1.453-2.562-3.029-4.257-5.042z"
8
+				],
9
+				"attrs": [
10
+					{
11
+						"opacity": 1,
12
+						"visibility": false
13
+					}
14
+				],
15
+				"width": 1105,
16
+				"grid": 0,
17
+				"tags": [
18
+					"settings"
19
+				]
20
+			},
21
+			"attrs": [
22
+				{
23
+					"opacity": 1,
24
+					"visibility": false
25
+				}
26
+			],
27
+			"properties": {
28
+				"order": 1,
29
+				"id": 33,
30
+				"prevSize": 32,
31
+				"code": 58907,
32
+				"name": "settings"
33
+			},
34
+			"setIdx": 0,
35
+			"iconIdx": 0
36
+		},
4 37
 		{
5 38
 			"icon": {
6 39
 				"paths": [
7 40
 					"M1223.129 242.783l-180.128 175.796v-217.716c0-74.673-59.512-135.496-132.599-135.496h-634.716c-73.084 0-132.596 60.823-132.596 135.496v609.237c0 74.673 59.512 135.496 132.596 135.496h634.716c73.084 0 132.599-60.82 132.599-135.496v-172.679l193.45 153.712c48.784 35.558 96.695-5.178 96.695-40.424v-483.533c-0.003-35.248-55.897-71.306-110.017-24.393zM601.169 760.065c-141.111 0-255.524-114.411-255.524-255.521s114.411-255.521 255.524-255.521c141.108 0 255.519 114.411 255.519 255.521-0 141.113-114.408 255.521-255.519 255.521z",
8 41
 					"M599.045 359.751c-80.474 0-145.727 65.253-145.727 145.729 0 80.471 65.25 145.727 145.727 145.727s145.729-65.256 145.729-145.727c0-80.474-65.253-145.729-145.729-145.729z"
9 42
 				],
43
+				"width": 1334,
10 44
 				"attrs": [
11 45
 					{
12 46
 						"opacity": 1,
@@ -17,11 +51,10 @@
17 51
 						"visibility": false
18 52
 					}
19 53
 				],
20
-				"width": 1334,
21
-				"grid": 0,
22 54
 				"tags": [
23 55
 					"webCam"
24
-				]
56
+				],
57
+				"grid": 0
25 58
 			},
26 59
 			"attrs": [
27 60
 				{
@@ -714,7 +747,7 @@
714 747
 				"ligatures": ""
715 748
 			},
716 749
 			"setIdx": 0,
717
-			"iconIdx": 26
750
+			"iconIdx": 25
718 751
 		},
719 752
 		{
720 753
 			"icon": {
@@ -740,7 +773,7 @@
740 773
 				"ligatures": ""
741 774
 			},
742 775
 			"setIdx": 0,
743
-			"iconIdx": 27
776
+			"iconIdx": 26
744 777
 		},
745 778
 		{
746 779
 			"icon": {
@@ -765,7 +798,7 @@
765 798
 				"ligatures": ""
766 799
 			},
767 800
 			"setIdx": 0,
768
-			"iconIdx": 28
801
+			"iconIdx": 27
769 802
 		}
770 803
 	],
771 804
 	"height": 1024,
@@ -775,6 +808,7 @@
775 808
 	"preferences": {
776 809
 		"showGlyphs": true,
777 810
 		"showQuickUse": true,
811
+		"showQuickUse2": true,
778 812
 		"showSVGs": true,
779 813
 		"fontPref": {
780 814
 			"prefix": "icon-",
@@ -791,7 +825,8 @@
791 825
 		},
792 826
 		"imagePref": {
793 827
 			"prefix": "icon-",
794
-			"png": true
828
+			"png": true,
829
+			"useClassSelector": true
795 830
 		},
796 831
 		"historySize": 100,
797 832
 		"showCodes": true,

+ 33
- 16
index.html Bestand weergeven

@@ -29,17 +29,18 @@
29 29
     <script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
30 30
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
31 31
     <script src="libs/pako.bundle.js?v=1"></script><!-- zlib deflate -->
32
-    <script src="interface_config.js?v=3"></script>
33 32
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
34
-    <script src="muc.js?v=16"></script><!-- simple MUC library -->
33
+    <script src="interface_config.js?v=4"></script>
34
+    <script src="muc.js?v=17"></script><!-- simple MUC library -->
35 35
     <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
36 36
     <script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
37 37
     <script src="data_channels.js?v=3"></script><!-- data channels -->
38
-    <script src="app.js?v=20"></script><!-- application logic -->
38
+    <script src="app.js?v=21"></script><!-- application logic -->
39 39
     <script src="commands.js?v=1"></script><!-- application logic -->
40
-    <script src="chat.js?v=14"></script><!-- chat logic -->
41
-    <script src="contact_list.js?v=6"></script><!-- contact list logic -->
42
-    <script src="util.js?v=6"></script><!-- utility functions -->
40
+    <script src="chat.js?v=15"></script><!-- chat logic -->
41
+    <script src="contact_list.js?v=7"></script><!-- contact list logic -->
42
+    <script src="side_panel_toggler.js?v=1"></script>
43
+    <script src="util.js?v=7"></script><!-- utility functions -->
43 44
     <script src="etherpad.js?v=9"></script><!-- etherpad plugin -->
44 45
     <script src="prezi.js?v=6"></script><!-- prezi plugin -->
45 46
     <script src="smileys.js?v=3"></script><!-- smiley images -->
@@ -48,14 +49,14 @@
48 49
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
49 50
     <script src="rtp_sts.js?v=5"></script><!-- RTP stats processing -->
50 51
     <script src="local_sts.js?v=2"></script><!-- Local stats processing -->
51
-    <script src="videolayout.js?v=28"></script><!-- video ui -->
52
+    <script src="videolayout.js?v=29"></script><!-- video ui -->
52 53
     <script src="connectionquality.js?v=1"></script>
53 54
     <script src="toolbar.js?v=6"></script><!-- toolbar ui -->
54 55
     <script src="toolbar_toggler.js?v=2"></script>
55 56
     <script src="canvas_util.js?v=1"></script><!-- canvas drawing utils -->
56 57
     <script src="audio_levels.js?v=2"></script><!-- audio levels plugin -->
57
-    <script src="media_stream.js?v=1"></script><!-- media stream -->
58
-    <script src="bottom_toolbar.js?v=5"></script><!-- media stream -->
58
+    <script src="media_stream.js?v=2"></script><!-- media stream -->
59
+    <script src="bottom_toolbar.js?v=6"></script><!-- media stream -->
59 60
     <script src="moderator.js?v=1"></script><!-- media stream -->
60 61
     <script src="roomname_generator.js?v=1"></script><!-- generator for random room names -->
61 62
     <script src="keyboard_shortcut.js?v=3"></script>
@@ -64,19 +65,22 @@
64 65
     <script src="jitsipopover.js?v=3"></script>
65 66
     <script src="message_handler.js?v=2"></script>
66 67
     <script src="api_connector.js?v=2"></script>
67
-    <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
68
-    <link rel="stylesheet" href="css/font.css?v=5"/>
68
+    <script src="settings_menu.js?v=1"></script>
69
+    <script src="avatar.js?v=1"></script><!-- avatars -->
70
+    <link rel="stylesheet" href="css/font.css?v=6"/>
69 71
     <link rel="stylesheet" href="css/toastr.css?v=1">
70
-    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=29"/>
71
-    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=13" id="videolayout_default"/>
72
+    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=30"/>
73
+    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=14" id="videolayout_default"/>
74
+    <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
72 75
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
73 76
     <link rel="stylesheet" href="css/modaldialog.css?v=3">
74 77
     <link rel="stylesheet" href="css/popup_menu.css?v=4">
75 78
     <link rel="stylesheet" href="css/popover.css?v=2">
76 79
     <link rel="stylesheet" href="css/jitsi_popover.css?v=2">
77
-    <link rel="stylesheet" href="css/contact_list.css?v=3">
80
+    <link rel="stylesheet" href="css/contact_list.css?v=4">
78 81
     <link rel="stylesheet" href="css/chat.css?v=5">
79 82
     <link rel="stylesheet" href="css/welcome_page.css?v=2">
83
+    <link rel="stylesheet" href="css/settingsmenu.css?v=1">
80 84
     <!--
81 85
         Link used for inline installation of chrome desktop streaming extension,
82 86
         is updated automatically from the code with the value defined in config.js -->
@@ -230,6 +234,10 @@
230 234
                             <i class="icon-telephone"></i></a>
231 235
                     </span>
232 236
                     <div class="header_button_separator"></div>
237
+                    <a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Settings" onclick='PanelToggler.toggleSettingsMenu();'>
238
+                        <i id="settingsButton" class="icon-settings"></i>
239
+                    </a>
240
+                    <div class="header_button_separator"></div>
233 241
                     <span id="hangup">
234 242
                         <a class="button" data-container="body" data-toggle="popover" data-placement="bottom" content="Hang Up" onclick='hangup();'>
235 243
                             <i class="icon-hangup" style="color:#ff0000;font-size: 1.4em;"></i>
@@ -256,6 +264,7 @@
256 264
                 <a target="_new"><div class="watermark leftwatermark"></div></a>
257 265
                 <a target="_new"><div class="watermark rightwatermark"></div></a>
258 266
                 <a class="poweredby" href="http://jitsi.org" target="_new" >powered by jitsi.org</a>
267
+                <img id="activeSpeakerAvatar" src=""/>
259 268
                 <video id="largeVideo" autoplay oncontextmenu="return false;"></video>
260 269
             </div>
261 270
             <div id="remoteVideos">
@@ -299,7 +308,7 @@
299 308
                 </span>
300 309
             </span>
301 310
         </div>
302
-        <div id="chatspace">
311
+        <div id="chatspace" class="right-panel">
303 312
             <div id="nickname">
304 313
                 Enter a nickname in the box below
305 314
                 <form>
@@ -317,11 +326,19 @@
317 326
                 </div>
318 327
             </div>
319 328
         </div>
320
-        <div id="contactlist">
329
+        <div id="contactlist" class="right-panel">
321 330
             <ul>
322 331
                 <li class="title"><i class="icon-contact-list"></i> CONTACT LIST</li>
323 332
             </ul>
324 333
         </div>
334
+        <div id="settingsmenu" class="right-panel">
335
+            <div class="icon-settings"> SETTINGS</div>
336
+            <img id="avatar" src="https://www.gravatar.com/avatar/87291c37c25be69a072a4514931b1749?d=retro&size=30"/>
337
+            <div class="arrow-up"></div>
338
+            <input type="text" id="setDisplayName" placeholder="Name">
339
+            <input type="text" id="setEmail" placeholder="E-Mail">
340
+            <button onclick="SettingsMenu.update()" id="updateSettings">Update</button>
341
+        </div>
325 342
         <a id="downloadlog" onclick='dump(event.target);' data-container="body" data-toggle="popover" data-placement="right" data-content="Download logs" ><i class="fa fa-cloud-download"></i></a>
326 343
     </div>
327 344
   </body>

+ 3
- 1
interface_config.js Bestand weergeven

@@ -6,11 +6,13 @@ var interfaceConfig = {
6 6
     TOOLBAR_TIMEOUT: 4000,
7 7
     DEFAULT_REMOTE_DISPLAY_NAME: "Fellow Jitster",
8 8
     DEFAULT_DOMINANT_SPEAKER_DISPLAY_NAME: "Speaker",
9
+    DEFAULT_LOCAL_DISPLAY_NAME: "me",
9 10
     SHOW_JITSI_WATERMARK: true,
10 11
     JITSI_WATERMARK_LINK: "http://jitsi.org",
11 12
     SHOW_BRAND_WATERMARK: false,
12 13
     BRAND_WATERMARK_LINK: "",
13 14
     SHOW_POWERED_BY: false,
14 15
     GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
15
-    APP_NAME: "Jitsi Meet"
16
+    APP_NAME: "Jitsi Meet",
17
+    ACTIVE_SPEAKER_AVATAR_SIZE: 100
16 18
 };

+ 6
- 4
media_stream.js Bestand weergeven

@@ -16,15 +16,17 @@ var MediaStream = (function() {
16 16
      * @constructor
17 17
      */
18 18
     function MediaStreamProto(data, sid, ssrc) {
19
-        this.VIDEO_TYPE = "Video";
20
-        this.AUDIO_TYPE = "Audio";
21 19
         this.stream = data.stream;
22 20
         this.peerjid = data.peerjid;
23 21
         this.ssrc = ssrc;
24 22
         this.session = connection.jingle.sessions[sid];
25 23
         this.type = (this.stream.getVideoTracks().length > 0)
26
-                    ? this.VIDEO_TYPE : this.AUDIO_TYPE;
24
+                    ? MediaStream.VIDEO_TYPE : MediaStream.AUDIO_TYPE;
25
+        this.muted = false;
27 26
     }
28 27
 
29 28
     return MediaStreamProto;
30
-})();
29
+})();
30
+
31
+MediaStream.VIDEO_TYPE = 'Video';
32
+MediaStream.AUDIO_TYPE = 'Audio';

+ 14
- 0
muc.js Bestand weergeven

@@ -357,6 +357,14 @@ Strophe.addConnectionPlugin('emuc', {
357 357
             pres.c('bridgeIsDown').up();
358 358
         }
359 359
 
360
+        if(this.presMap['email']) {
361
+            pres.c('email').t(this.presMap['email']).up();
362
+        }
363
+
364
+        if(this.presMap['userId']) {
365
+            pres.c('userId').t(this.presMap['userId']).up();
366
+        }
367
+
360 368
         if (this.presMap['displayName']) {
361 369
             // XEP-0172
362 370
             pres.c('nick', {xmlns: 'http://jabber.org/protocol/nick'})
@@ -479,6 +487,12 @@ Strophe.addConnectionPlugin('emuc', {
479 487
     addBridgeIsDownToPresence: function() {
480 488
         this.presMap['bridgeIsDown'] = true;
481 489
     },
490
+    addEmailToPresence: function(email) {
491
+        this.presMap['email'] = email;
492
+    },
493
+    addUserIdToPresence: function(userId) {
494
+        this.presMap['userId'] = userId;
495
+    },
482 496
     isModerator: function() {
483 497
         return this.role === 'moderator';
484 498
     }

+ 83
- 0
settings_menu.js Bestand weergeven

@@ -0,0 +1,83 @@
1
+var SettingsMenu = (function(my) {
2
+
3
+    var email = '';
4
+    var displayName = '';
5
+    var userId;
6
+
7
+    if(supportsLocalStorage()) {
8
+        if(!window.localStorage.jitsiMeetId) {
9
+            window.localStorage.jitsiMeetId = generateUniqueId();
10
+            console.log("generated id", window.localStorage.jitsiMeetId);
11
+        }
12
+        userId = window.localStorage.jitsiMeetId || '';
13
+        email = window.localStorage.email || '';
14
+        displayName = window.localStorage.displayname || '';
15
+    } else {
16
+        console.log("local storage is not supported");
17
+        userId = generateUniqueId();
18
+    }
19
+
20
+    my.update = function() {
21
+        var newDisplayName = Util.escapeHtml($('#setDisplayName').get(0).value);
22
+        if(newDisplayName) {
23
+            displayName = newDisplayName;
24
+            connection.emuc.addDisplayNameToPresence(displayName);
25
+            window.localStorage.displayname = displayName;
26
+        }
27
+
28
+        var newEmail = Util.escapeHtml($('#setEmail').get(0).value);
29
+        connection.emuc.addEmailToPresence(newEmail);
30
+        email = newEmail;
31
+        window.localStorage.email = newEmail;
32
+
33
+        connection.emuc.sendPresence();
34
+        Avatar.setUserAvatar(connection.emuc.myroomjid, email);
35
+    };
36
+
37
+    my.isVisible = function() {
38
+        return $('#settingsmenu').is(':visible');
39
+    };
40
+
41
+    my.getUID = function() {
42
+        return userId;
43
+    };
44
+
45
+    my.getEmail = function() {
46
+        return email;
47
+    };
48
+
49
+    my.getDisplayName = function() {
50
+        return displayName;
51
+    };
52
+
53
+    my.setDisplayName = function(newDisplayName) {
54
+        displayName = newDisplayName;
55
+        window.localStorage.displayname = displayName;
56
+        $('#setDisplayName').get(0).value = displayName;
57
+    };
58
+
59
+    function supportsLocalStorage() {
60
+        try {
61
+            return 'localStorage' in window && window.localStorage !== null;
62
+        } catch (e) {
63
+            console.log("localstorage is not supported");
64
+            return false;
65
+        }
66
+    }
67
+
68
+    function generateUniqueId() {
69
+        function _p8() {
70
+            return (Math.random().toString(16)+"000000000").substr(2,8);
71
+        }
72
+        return _p8() + _p8() + _p8() + _p8();
73
+    }
74
+
75
+    $(document).bind('displaynamechanged', function(event, peerJid, newDisplayName) {
76
+       if(peerJid === 'localVideoContainer' ||
77
+           peerJid === connection.emuc.myroomjid) {
78
+           SettingsMenu.setDisplayName(newDisplayName);
79
+       }
80
+    });
81
+
82
+    return my;
83
+}(SettingsMenu || {}));

+ 245
- 0
side_panel_toggler.js Bestand weergeven

@@ -0,0 +1,245 @@
1
+/**
2
+ * Toggler for the chat, contact list, settings menu, etc..
3
+ */
4
+var PanelToggler = (function(my) {
5
+
6
+    var currentlyOpen = null;
7
+    var buttons = {
8
+        '#chatspace': '#chatBottomButton',
9
+        '#contactlist': '#contactListButton',
10
+        '#settingsmenu': '#settingsButton'
11
+    };
12
+
13
+    /**
14
+     * Resizes the video area
15
+     * @param isClosing whether the side panel is going to be closed or is going to open / remain opened
16
+     * @param completeFunction a function to be called when the video space is resized
17
+     */
18
+    var resizeVideoArea = function(isClosing, completeFunction) {
19
+        var videospace = $('#videospace');
20
+
21
+        var panelSize = isClosing ? [0, 0] : PanelToggler.getPanelSize();
22
+        var videospaceWidth = window.innerWidth - panelSize[0];
23
+        var videospaceHeight = window.innerHeight;
24
+        var videoSize
25
+            = getVideoSize(null, null, videospaceWidth, videospaceHeight);
26
+        var videoWidth = videoSize[0];
27
+        var videoHeight = videoSize[1];
28
+        var videoPosition = getVideoPosition(videoWidth,
29
+            videoHeight,
30
+            videospaceWidth,
31
+            videospaceHeight);
32
+        var horizontalIndent = videoPosition[0];
33
+        var verticalIndent = videoPosition[1];
34
+
35
+        var thumbnailSize = VideoLayout.calculateThumbnailSize(videospaceWidth);
36
+        var thumbnailsWidth = thumbnailSize[0];
37
+        var thumbnailsHeight = thumbnailSize[1];
38
+        //for chat
39
+
40
+        videospace.animate({
41
+                right: panelSize[0],
42
+                width: videospaceWidth,
43
+                height: videospaceHeight
44
+            },
45
+            {
46
+                queue: false,
47
+                duration: 500,
48
+                complete: completeFunction
49
+            });
50
+
51
+        $('#remoteVideos').animate({
52
+                height: thumbnailsHeight
53
+            },
54
+            {
55
+                queue: false,
56
+                duration: 500
57
+            });
58
+
59
+        $('#remoteVideos>span').animate({
60
+                height: thumbnailsHeight,
61
+                width: thumbnailsWidth
62
+            },
63
+            {
64
+                queue: false,
65
+                duration: 500,
66
+                complete: function () {
67
+                    $(document).trigger(
68
+                        "remotevideo.resized",
69
+                        [thumbnailsWidth,
70
+                            thumbnailsHeight]);
71
+                }
72
+            });
73
+
74
+        $('#largeVideoContainer').animate({
75
+                width: videospaceWidth,
76
+                height: videospaceHeight
77
+            },
78
+            {
79
+                queue: false,
80
+                duration: 500
81
+            });
82
+
83
+        $('#largeVideo').animate({
84
+                width: videoWidth,
85
+                height: videoHeight,
86
+                top: verticalIndent,
87
+                bottom: verticalIndent,
88
+                left: horizontalIndent,
89
+                right: horizontalIndent
90
+            },
91
+            {
92
+                queue: false,
93
+                duration: 500
94
+            });
95
+    };
96
+
97
+    /**
98
+     * Toggles the windows in the side panel
99
+     * @param object the window that should be shown
100
+     * @param selector the selector for the element containing the panel
101
+     * @param onOpenComplete function to be called when the panel is opened
102
+     * @param onOpen function to be called if the window is going to be opened
103
+     * @param onClose function to be called if the window is going to be closed
104
+     */
105
+    var toggle = function(object, selector, onOpenComplete, onOpen, onClose) {
106
+        buttonClick(buttons[selector], "active");
107
+
108
+        if (object.isVisible()) {
109
+            $("#toast-container").animate({
110
+                    right: '5px'
111
+                },
112
+                {
113
+                    queue: false,
114
+                    duration: 500
115
+                });
116
+            $(selector).hide("slide", {
117
+                direction: "right",
118
+                queue: false,
119
+                duration: 500
120
+            });
121
+            if(typeof onClose === "function") {
122
+                onClose();
123
+            }
124
+
125
+            currentlyOpen = null;
126
+        }
127
+        else {
128
+            // Undock the toolbar when the chat is shown and if we're in a
129
+            // video mode.
130
+            if (VideoLayout.isLargeVideoVisible()) {
131
+                ToolbarToggler.dockToolbar(false);
132
+            }
133
+
134
+            if(currentlyOpen) {
135
+                var current = $(currentlyOpen);
136
+                buttonClick(buttons[currentlyOpen], "active");
137
+                current.css('z-index', 4);
138
+                setTimeout(function () {
139
+                    current.css('display', 'none');
140
+                    current.css('z-index', 5);
141
+                }, 500);
142
+            }
143
+
144
+            $("#toast-container").animate({
145
+                    right: (PanelToggler.getPanelSize()[0] + 5) + 'px'
146
+                },
147
+                {
148
+                    queue: false,
149
+                    duration: 500
150
+                });
151
+            $(selector).show("slide", {
152
+                direction: "right",
153
+                queue: false,
154
+                duration: 500,
155
+                complete: onOpenComplete
156
+            });
157
+            if(typeof onOpen === "function") {
158
+                onOpen();
159
+            }
160
+
161
+            currentlyOpen = selector;
162
+        }
163
+    };
164
+
165
+    /**
166
+     * Opens / closes the chat area.
167
+     */
168
+    my.toggleChat = function() {
169
+        var chatCompleteFunction = Chat.isVisible() ?
170
+            function() {} : function () {
171
+            Chat.scrollChatToBottom();
172
+            $('#chatspace').trigger('shown');
173
+        };
174
+
175
+        resizeVideoArea(Chat.isVisible(), chatCompleteFunction);
176
+
177
+        toggle(Chat,
178
+            '#chatspace',
179
+            function () {
180
+                // Request the focus in the nickname field or the chat input field.
181
+                if ($('#nickname').css('visibility') === 'visible') {
182
+                    $('#nickinput').focus();
183
+                } else {
184
+                    $('#usermsg').focus();
185
+                }
186
+            },
187
+            null,
188
+            Chat.resizeChat,
189
+            null);
190
+    };
191
+
192
+    /**
193
+     * Opens / closes the contact list area.
194
+     */
195
+    my.toggleContactList = function () {
196
+        var completeFunction = ContactList.isVisible() ?
197
+            function() {} : function () { $('#contactlist').trigger('shown');};
198
+        resizeVideoArea(ContactList.isVisible(), completeFunction);
199
+
200
+        toggle(ContactList,
201
+            '#contactlist',
202
+            null,
203
+            function() {
204
+                ContactList.setVisualNotification(false);
205
+            },
206
+            null);
207
+    };
208
+
209
+    /**
210
+     * Opens / closes the settings menu
211
+     */
212
+    my.toggleSettingsMenu = function() {
213
+        resizeVideoArea(SettingsMenu.isVisible(), function (){});
214
+        toggle(SettingsMenu,
215
+            '#settingsmenu',
216
+            null,
217
+            function() {
218
+                $('#setDisplayName').get(0).value = SettingsMenu.getDisplayName();
219
+                $('#setEmail').get(0).value = SettingsMenu.getEmail();
220
+            },
221
+            null);
222
+    };
223
+
224
+    /**
225
+     * Returns the size of the side panel.
226
+     */
227
+    my.getPanelSize = function () {
228
+        var availableHeight = window.innerHeight;
229
+        var availableWidth = window.innerWidth;
230
+
231
+        var panelWidth = 200;
232
+        if (availableWidth * 0.2 < 200) {
233
+            panelWidth = availableWidth * 0.2;
234
+        }
235
+
236
+        return [panelWidth, availableHeight];
237
+    };
238
+
239
+    my.isVisible = function() {
240
+        return (Chat.isVisible() || ContactList.isVisible() || SettingsMenu.isVisible());
241
+    };
242
+
243
+    return my;
244
+
245
+}(PanelToggler || {}));

+ 3
- 5
util.js Bestand weergeven

@@ -51,12 +51,10 @@ var Util = (function (my) {
51 51
      * Returns the available video width.
52 52
      */
53 53
     my.getAvailableVideoWidth = function () {
54
-        var chatspaceWidth
55
-            = (Chat.isVisible() || ContactList.isVisible())
56
-                ? $('#chatspace').width()
57
-                : 0;
54
+        var rightPanelWidth
55
+            = PanelToggler.isVisible() ? PanelToggler.getPanelSize()[0] : 0;
58 56
 
59
-        return window.innerWidth - chatspaceWidth;
57
+        return window.innerWidth - rightPanelWidth;
60 58
     };
61 59
 
62 60
     my.imageToGrayScale = function (canvas) {

+ 62
- 45
videolayout.js Bestand weergeven

@@ -11,6 +11,12 @@ var VideoLayout = (function (my) {
11 11
     };
12 12
     my.connectionIndicators = {};
13 13
 
14
+    my.isInLastN = function(resource) {
15
+        return lastNCount < 0 // lastN is disabled, return true
16
+            || (lastNCount > 0 && lastNEndpointsCache.length == 0) // lastNEndpoints cache not built yet, return true
17
+            || (lastNEndpointsCache && lastNEndpointsCache.indexOf(resource) !== -1);
18
+    };
19
+
14 20
     my.changeLocalAudio = function(stream) {
15 21
         connection.jingle.localAudio = stream;
16 22
 
@@ -127,6 +133,7 @@ var VideoLayout = (function (my) {
127 133
 
128 134
         if ($('#largeVideo').attr('src') != newSrc) {
129 135
 
136
+            $('#activeSpeakerAvatar').css('visibility', 'hidden');
130 137
             // Due to the simulcast the localVideoSrc may have changed when the
131 138
             // fadeOut event triggers. In that case the getJidFromVideoSrc and
132 139
             // isVideoSrcDesktop methods will not function correctly.
@@ -159,6 +166,8 @@ var VideoLayout = (function (my) {
159 166
 
160 167
                 var doUpdate = function () {
161 168
 
169
+                    Avatar.updateActiveSpeakerAvatarSrc(largeVideoState.userJid);
170
+
162 171
                     if (!userChanged && largeVideoState.preload
163 172
                         && largeVideoState.preload != null
164 173
                         && $(largeVideoState.preload).attr('src') == newSrc) {
@@ -231,6 +240,10 @@ var VideoLayout = (function (my) {
231 240
                         $(this).fadeIn(300);
232 241
                     }
233 242
 
243
+                    if(userChanged) {
244
+                        Avatar.showUserAvatar(largeVideoState.oldJid);
245
+                    }
246
+
234 247
                     largeVideoState.updateInProgress = false;
235 248
                 };
236 249
 
@@ -372,29 +385,30 @@ var VideoLayout = (function (my) {
372 385
      * in the document and creates it eventually.
373 386
      * 
374 387
      * @param peerJid peer Jid to check.
388
+     * @param userId user email or id for setting the avatar
375 389
      * 
376 390
      * @return Returns <tt>true</tt> if the peer container exists,
377 391
      * <tt>false</tt> - otherwise
378 392
      */
379
-    my.ensurePeerContainerExists = function(peerJid) {
380
-        ContactList.ensureAddContact(peerJid);
393
+    my.ensurePeerContainerExists = function(peerJid, userId) {
394
+        ContactList.ensureAddContact(peerJid, userId);
381 395
 
382 396
         var resourceJid = Strophe.getResourceFromJid(peerJid);
383 397
 
384 398
         var videoSpanId = 'participant_' + resourceJid;
385 399
 
386 400
         if ($('#' + videoSpanId).length > 0) {
387
-            // If there's been a moderator change, make sure we add moderator
388
-            // related interface!!
389
-            if (Moderator.isModerator() &&
390
-                $('#remote_popupmenu_' + resourceJid).length <= 0)
401
+            // If there's been a focus change, make sure we add focus related
402
+            // interface!!
403
+            if (Moderator.isModerator() && $('#remote_popupmenu_' + resourceJid).length <= 0) {
391 404
                 addRemoteVideoMenu(peerJid,
392
-                                   document.getElementById(videoSpanId));
405
+                    document.getElementById(videoSpanId));
406
+            }
393 407
         }
394 408
         else {
395
-            var container
396
-                = VideoLayout.addRemoteVideoContainer(peerJid, videoSpanId);
397
-
409
+            var container =
410
+                VideoLayout.addRemoteVideoContainer(peerJid, videoSpanId, userId);
411
+            Avatar.setUserAvatar(peerJid, userId);
398 412
             // Set default display name.
399 413
             setDisplayName(videoSpanId);
400 414
 
@@ -473,8 +487,10 @@ var VideoLayout = (function (my) {
473 487
                 var videoStream = simulcast.getReceivingVideoStream(stream);
474 488
                 RTC.attachMediaStream(sel, videoStream);
475 489
 
476
-                if (isVideo)
490
+                if (isVideo) {
477 491
                     waitForRemoteVideo(sel, thessrc, stream);
492
+                }
493
+
478 494
             }
479 495
 
480 496
             stream.onended = function () {
@@ -591,14 +607,17 @@ var VideoLayout = (function (my) {
591 607
                 peerContainer.show();
592 608
             }
593 609
 
594
-            // TODO(gp) add proper avatars handling.
595 610
             if (state == 'show')
596 611
             {
597
-                peerContainer.css('-webkit-filter', '');
612
+                // peerContainer.css('-webkit-filter', '');
613
+                var jid = connection.emuc.findJidFromResource(resourceJid);
614
+                Avatar.showUserAvatar(jid, false);
598 615
             }
599 616
             else // if (state == 'avatar')
600 617
             {
601
-                peerContainer.css('-webkit-filter', 'grayscale(100%)');
618
+                // peerContainer.css('-webkit-filter', 'grayscale(100%)');
619
+                var jid = connection.emuc.findJidFromResource(resourceJid);
620
+                Avatar.showUserAvatar(jid, true);
602 621
             }
603 622
         }
604 623
         else if (peerContainer.is(':visible') && isHide)
@@ -624,7 +643,7 @@ var VideoLayout = (function (my) {
624 643
      */
625 644
     function setDisplayName(videoSpanId, displayName) {
626 645
         var nameSpan = $('#' + videoSpanId + '>span.displayname');
627
-        var defaultLocalDisplayName = "Me";
646
+        var defaultLocalDisplayName = interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME;
628 647
 
629 648
         // If we already have a display name for this video.
630 649
         if (nameSpan.length > 0) {
@@ -685,6 +704,7 @@ var VideoLayout = (function (my) {
685 704
                     .bind("click", function (e) {
686 705
 
687 706
                     e.preventDefault();
707
+                    e.stopPropagation();
688 708
                     $('#localDisplayName').hide();
689 709
                     $('#editDisplayName').show();
690 710
                     $('#editDisplayName').focus();
@@ -703,7 +723,7 @@ var VideoLayout = (function (my) {
703 723
                 });
704 724
             }
705 725
         }
706
-    };
726
+    }
707 727
 
708 728
     my.inputDisplayNameHandler = function (name) {
709 729
         if (nickname !== name) {
@@ -720,7 +740,7 @@ var VideoLayout = (function (my) {
720 740
                 $('#localDisplayName').text(nickname + " (me)");
721 741
             else
722 742
                 $('#localDisplayName')
723
-                    .text(defaultLocalDisplayName);
743
+                    .text(interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME);
724 744
             $('#localDisplayName').show();
725 745
         }
726 746
 
@@ -921,6 +941,10 @@ var VideoLayout = (function (my) {
921 941
         $('#largeVideoContainer').width(availableWidth);
922 942
         $('#largeVideoContainer').height(availableHeight);
923 943
 
944
+
945
+        $('#activeSpeakerAvatar').css('top',
946
+            (availableHeight - interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE) / 2);
947
+
924 948
         VideoLayout.resizeThumbnails();
925 949
     };
926 950
 
@@ -940,6 +964,8 @@ var VideoLayout = (function (my) {
940 964
         $('#remoteVideos>span').width(width);
941 965
         $('#remoteVideos>span').height(height);
942 966
 
967
+        $('.userAvatar').css('left', (width - height) / 2);
968
+
943 969
         $(document).trigger("remotevideo.resized", [width, height]);
944 970
     };
945 971
 
@@ -1545,36 +1571,27 @@ var VideoLayout = (function (my) {
1545 1571
                 if (!isVisible) {
1546 1572
                     console.log("Add to last N", resourceJid);
1547 1573
 
1548
-                    mediaStreams.some(function (mediaStream) {
1549
-                        if (mediaStream.peerjid
1550
-                            && Strophe.getResourceFromJid(mediaStream.peerjid)
1551
-                                === resourceJid
1552
-                            && mediaStream.type === mediaStream.VIDEO_TYPE) {
1553
-                            var sel = $('#participant_' + resourceJid + '>video');
1554
-
1555
-                            var videoStream = simulcast.getReceivingVideoStream(mediaStream.stream);
1556
-                            RTC.attachMediaStream(sel, videoStream);
1557
-                            videoSrcToSsrc[sel.attr('src')] = mediaStream.ssrc;
1558
-                            if (lastNPickupJid == mediaStream.peerjid) {
1559
-                                // Clean up the lastN pickup jid.
1560
-                                lastNPickupJid = null;
1561
-
1562
-                                // Don't fire the events again, they've already
1563
-                                // been fired in the contact list click handler.
1564
-                                VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false);
1565
-
1566
-                                updateLargeVideo = false;
1567
-                            }
1574
+                    var jid = connection.emuc.findJidFromResource(resourceJid);
1575
+                    var mediaStream = mediaStreams[jid][MediaStream.VIDEO_TYPE];
1576
+                    var sel = $('#participant_' + resourceJid + '>video');
1568 1577
 
1569
-                            waitForRemoteVideo(
1570
-                                    sel,
1571
-                                    mediaStream.ssrc,
1572
-                                    mediaStream.stream);
1573
-                            return true;
1574
-                        }
1575
-                    });
1578
+                    var videoStream = simulcast.getReceivingVideoStream(
1579
+                        mediaStream.stream);
1580
+                    RTC.attachMediaStream(sel, videoStream);
1581
+                    videoSrcToSsrc[sel.attr('src')] = mediaStream.ssrc;
1582
+                    if (lastNPickupJid == mediaStream.peerjid) {
1583
+                        // Clean up the lastN pickup jid.
1584
+                        lastNPickupJid = null;
1585
+
1586
+                        // Don't fire the events again, they've already
1587
+                        // been fired in the contact list click handler.
1588
+                        VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false);
1589
+
1590
+                        updateLargeVideo = false;
1591
+                    }
1592
+                    waitForRemoteVideo(sel, mediaStream.ssrc, mediaStream.stream);
1576 1593
                 }
1577
-            });
1594
+            })
1578 1595
         }
1579 1596
 
1580 1597
         // The endpoint that was being shown in the large video has dropped out

Laden…
Annuleren
Opslaan