Quellcode durchsuchen

Adds a side panel toggler, settings menu, avatars, uuids.

j8
fo vor 11 Jahren
Ursprung
Commit
1d4177faeb
23 geänderte Dateien mit 785 neuen und 370 gelöschten Zeilen
  1. 53
    11
      app.js
  2. 138
    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. 49
    40
      videolayout.js

+ 53
- 11
app.js Datei anzeigen

@@ -11,7 +11,7 @@ var recordingToken ='';
11 11
 var roomUrl = null;
12 12
 var roomName = null;
13 13
 var ssrc2jid = {};
14
-var mediaStreams = [];
14
+var mediaStreams = {};
15 15
 var bridgeIsDown = false;
16 16
 
17 17
 /**
@@ -99,9 +99,16 @@ function connect(jid, password) {
99 99
         localVideo = connection.jingle.localVideo;
100 100
     }
101 101
     connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind');
102
-
103
-    if (nickname) {
104
-        connection.emuc.addDisplayNameToPresence(nickname);
102
+    
103
+    var email = SettingsMenu.getEmail();
104
+    var displayName = SettingsMenu.getDisplayName();
105
+    if(email) {
106
+        connection.emuc.addEmailToPresence(email);
107
+    } else {
108
+        connection.emuc.addUserIdToPresence(SettingsMenu.getUID());
109
+    }
110
+    if(displayName) {
111
+        connection.emuc.addDisplayNameToPresence(displayName);
105 112
     }
106 113
 
107 114
     if (connection.disco) {
@@ -335,7 +342,12 @@ function waitForPresence(data, sid) {
335 342
     // NOTE(gp) now that we have simulcast, a media stream can have more than 1
336 343
     // ssrc. We should probably take that into account in our MediaStream
337 344
     // wrapper.
338
-    mediaStreams.push(new MediaStream(data, sid, thessrc));
345
+    var mediaStream = new MediaStream(data, sid, thessrc);
346
+    var jid = data.peerjid || connection.emuc.myroomjid;
347
+    if(!mediaStreams[jid]) {
348
+        mediaStreams[jid] = {};
349
+    }
350
+    mediaStreams[jid][mediaStream.type] = mediaStream;
339 351
 
340 352
     var container;
341 353
     var remotes = document.getElementById('remoteVideos');
@@ -369,6 +381,8 @@ function waitForPresence(data, sid) {
369 381
                                             data.stream,
370 382
                                             data.peerjid,
371 383
                                             thessrc);
384
+        if(isVideo && container.id !== 'mixedstream')
385
+             videoSrcToSsrc[$(container).find('>video')[0].src] = thessrc;
372 386
     }
373 387
 
374 388
     // an attempt to work around https://github.com/jitsi/jitmeet/issues/32
@@ -699,7 +713,7 @@ $(document).bind('joined.muc', function (event, jid, info) {
699 713
     VideoLayout.showFocusIndicator();
700 714
 
701 715
     // Add myself to the contact list.
702
-    ContactList.addContact(jid);
716
+    ContactList.addContact(jid, SettingsMenu.getEmail() || SettingsMenu.getUID());
703 717
 
704 718
     // Once we've joined the muc show the toolbar
705 719
     ToolbarToggler.showToolbar();
@@ -721,7 +735,12 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
721 735
     console.log('is focus? ' + (focus ? 'true' : 'false'));
722 736
 
723 737
     // Add Peer's container
724
-    VideoLayout.ensurePeerContainerExists(jid);
738
+    var id = $(pres).find('>userID').text();
739
+    var email = $(pres).find('>email');
740
+    if(email.length > 0) {
741
+        id = email.text();
742
+    }
743
+    VideoLayout.ensurePeerContainerExists(jid,id);
725 744
 
726 745
     if(APIConnector.isEnabled() && APIConnector.isEventEnabled("participantJoined"))
727 746
     {
@@ -879,6 +898,13 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
879 898
             "Jitsi Videobridge is currently unavailable. Please try again later!");
880 899
     }
881 900
 
901
+    var id = $(pres).find('>userID').text();
902
+    var email = $(pres).find('>email');
903
+    if(email.length > 0) {
904
+        id = email.text();
905
+    }
906
+    Avatar.setUserAvatar(jid, id);
907
+
882 908
 });
883 909
 
884 910
 $(document).bind('presence.status.muc', function (event, jid, info, pres) {
@@ -1358,15 +1384,20 @@ $(document).ready(function () {
1358 1384
         "showMethod": "fadeIn",
1359 1385
         "hideMethod": "fadeOut",
1360 1386
         "reposition": function() {
1361
-            if(Chat.isVisible() || ContactList.isVisible()) {
1362
-                $("#toast-container").addClass("toast-bottom-right-center");
1387
+            if(PanelToggler.isVisible()) {
1388
+                $("#toast-container").addClass("notification-bottom-right-center");
1363 1389
             } else {
1364
-                $("#toast-container").removeClass("toast-bottom-right-center");
1390
+                $("#toast-container").removeClass("notification-bottom-right-center");
1365 1391
             }
1366 1392
         },
1367 1393
         "newestOnTop": false
1368
-    }
1394
+    };
1369 1395
 
1396
+    $('#settingsmenu>input').keyup(function(event){
1397
+        if(event.keyCode === 13) {//enter
1398
+            SettingsMenu.update();
1399
+        }
1400
+    })
1370 1401
 
1371 1402
 });
1372 1403
 
@@ -1661,3 +1692,14 @@ function hangup() {
1661 1692
     );
1662 1693
 
1663 1694
 }
1695
+
1696
+$(document).on('videomuted.muc', function(event, jid, value) {
1697
+    if(mediaStreams[jid] && mediaStreams[jid][MediaStream.VIDEO_TYPE]) {
1698
+        var stream = mediaStreams[jid][MediaStream.VIDEO_TYPE];
1699
+        var isMuted = (value === "true");
1700
+        if (isMuted != stream.muted) {
1701
+            stream.muted = isMuted;
1702
+            Avatar.showUserAvatar(jid, isMuted);
1703
+        }
1704
+    }
1705
+});

+ 138
- 0
avatar.js Datei anzeigen

@@ -0,0 +1,138 @@
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]);
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
+        if(!mediaStreams[jid] || !mediaStreams[jid][MediaStream.VIDEO_TYPE]) {
126
+            return null;
127
+        }
128
+        return mediaStreams[jid][MediaStream.VIDEO_TYPE].muted;
129
+    }
130
+
131
+    function getGravatarUrl(email, size) {
132
+        return 'https://www.gravatar.com/avatar/' +
133
+            (email ? MD5.hexdigest(email.trim().toLowerCase()) : SettingsMenu.getUID()) +
134
+            "?d=retro&size=" + (size || "30");
135
+    }
136
+
137
+    return my;
138
+}(Avatar || {}));

+ 2
- 22
bottom_toolbar.js Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen


+ 1
- 0
fonts/jitsi.svg Datei anzeigen

@@ -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 Datei anzeigen


BIN
fonts/jitsi.woff Datei anzeigen


+ 42
- 7
fonts/selection.json Datei anzeigen

@@ -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 Datei anzeigen

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

+ 3
- 1
interface_config.js Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -335,6 +335,14 @@ Strophe.addConnectionPlugin('emuc', {
335 335
             pres.c('bridgeIsDown').up();
336 336
         }
337 337
 
338
+        if(this.presMap['email']) {
339
+            pres.c('email').t(this.presMap['email']).up();
340
+        }
341
+
342
+        if(this.presMap['userId']) {
343
+            pres.c('userId').t(this.presMap['userId']).up();
344
+        }
345
+
338 346
         if (this.presMap['displayName']) {
339 347
             // XEP-0172
340 348
             pres.c('nick', {xmlns: 'http://jabber.org/protocol/nick'})
@@ -456,5 +464,11 @@ Strophe.addConnectionPlugin('emuc', {
456 464
     },
457 465
     addBridgeIsDownToPresence: function() {
458 466
         this.presMap['bridgeIsDown'] = true;
467
+    },
468
+    addEmailToPresence: function(email) {
469
+        this.presMap['email'] = email;
470
+    },
471
+    addUserIdToPresence: function(userId) {
472
+        this.presMap['userId'] = userId;
459 473
     }
460 474
 });

+ 83
- 0
settings_menu.js Datei anzeigen

@@ -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 Datei anzeigen

@@ -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 Datei anzeigen

@@ -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) {

+ 49
- 40
videolayout.js Datei anzeigen

@@ -123,6 +123,7 @@ var VideoLayout = (function (my) {
123 123
 
124 124
         if ($('#largeVideo').attr('src') != newSrc) {
125 125
 
126
+            $('#activeSpeakerAvatar').css('visibility', 'hidden');
126 127
             // Due to the simulcast the localVideoSrc may have changed when the
127 128
             // fadeOut event triggers. In that case the getJidFromVideoSrc and
128 129
             // isVideoSrcDesktop methods will not function correctly.
@@ -155,6 +156,8 @@ var VideoLayout = (function (my) {
155 156
 
156 157
                 var doUpdate = function () {
157 158
 
159
+                    Avatar.updateActiveSpeakerAvatarSrc(largeVideoState.userJid);
160
+
158 161
                     if (!userChanged && largeVideoState.preload
159 162
                         && largeVideoState.preload != null
160 163
                         && $(largeVideoState.preload).attr('src') == newSrc) {
@@ -227,6 +230,10 @@ var VideoLayout = (function (my) {
227 230
                         $(this).fadeIn(300);
228 231
                     }
229 232
 
233
+                    if(userChanged) {
234
+                        Avatar.showUserAvatar(largeVideoState.oldJid);
235
+                    }
236
+
230 237
                     largeVideoState.updateInProgress = false;
231 238
                 };
232 239
 
@@ -368,12 +375,13 @@ var VideoLayout = (function (my) {
368 375
      * in the document and creates it eventually.
369 376
      * 
370 377
      * @param peerJid peer Jid to check.
378
+     * @param userId user email or id for setting the avatar
371 379
      * 
372 380
      * @return Returns <tt>true</tt> if the peer container exists,
373 381
      * <tt>false</tt> - otherwise
374 382
      */
375
-    my.ensurePeerContainerExists = function(peerJid) {
376
-        ContactList.ensureAddContact(peerJid);
383
+    my.ensurePeerContainerExists = function(peerJid, userId) {
384
+        ContactList.ensureAddContact(peerJid, userId);
377 385
 
378 386
         var resourceJid = Strophe.getResourceFromJid(peerJid);
379 387
 
@@ -382,14 +390,15 @@ var VideoLayout = (function (my) {
382 390
         if ($('#' + videoSpanId).length > 0) {
383 391
             // If there's been a focus change, make sure we add focus related
384 392
             // interface!!
385
-            if (focus && $('#remote_popupmenu_' + resourceJid).length <= 0)
386
-                addRemoteVideoMenu( peerJid,
387
-                                    document.getElementById(videoSpanId));
393
+            if (focus && $('#remote_popupmenu_' + resourceJid).length <= 0) {
394
+                addRemoteVideoMenu(peerJid,
395
+                    document.getElementById(videoSpanId));
396
+            }
388 397
         }
389 398
         else {
390
-            var container
391
-                = VideoLayout.addRemoteVideoContainer(peerJid, videoSpanId);
392
-
399
+            var container =
400
+                VideoLayout.addRemoteVideoContainer(peerJid, videoSpanId, userId);
401
+            Avatar.setUserAvatar(peerJid, userId);
393 402
             // Set default display name.
394 403
             setDisplayName(videoSpanId);
395 404
 
@@ -468,8 +477,10 @@ var VideoLayout = (function (my) {
468 477
                 var videoStream = simulcast.getReceivingVideoStream(stream);
469 478
                 RTC.attachMediaStream(sel, videoStream);
470 479
 
471
-                if (isVideo)
480
+                if (isVideo) {
472 481
                     waitForRemoteVideo(sel, thessrc, stream);
482
+                }
483
+
473 484
             }
474 485
 
475 486
             stream.onended = function () {
@@ -619,7 +630,7 @@ var VideoLayout = (function (my) {
619 630
      */
620 631
     function setDisplayName(videoSpanId, displayName) {
621 632
         var nameSpan = $('#' + videoSpanId + '>span.displayname');
622
-        var defaultLocalDisplayName = "Me";
633
+        var defaultLocalDisplayName = interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME;
623 634
 
624 635
         // If we already have a display name for this video.
625 636
         if (nameSpan.length > 0) {
@@ -680,6 +691,7 @@ var VideoLayout = (function (my) {
680 691
                     .bind("click", function (e) {
681 692
 
682 693
                     e.preventDefault();
694
+                    e.stopPropagation();
683 695
                     $('#localDisplayName').hide();
684 696
                     $('#editDisplayName').show();
685 697
                     $('#editDisplayName').focus();
@@ -698,7 +710,7 @@ var VideoLayout = (function (my) {
698 710
                 });
699 711
             }
700 712
         }
701
-    };
713
+    }
702 714
 
703 715
     my.inputDisplayNameHandler = function (name) {
704 716
         if (nickname !== name) {
@@ -715,7 +727,7 @@ var VideoLayout = (function (my) {
715 727
                 $('#localDisplayName').text(nickname + " (me)");
716 728
             else
717 729
                 $('#localDisplayName')
718
-                    .text(defaultLocalDisplayName);
730
+                    .text(interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME);
719 731
             $('#localDisplayName').show();
720 732
         }
721 733
 
@@ -911,6 +923,10 @@ var VideoLayout = (function (my) {
911 923
         $('#largeVideoContainer').width(availableWidth);
912 924
         $('#largeVideoContainer').height(availableHeight);
913 925
 
926
+
927
+        $('#activeSpeakerAvatar').css('top',
928
+            (availableHeight - interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE) / 2);
929
+
914 930
         VideoLayout.resizeThumbnails();
915 931
     };
916 932
 
@@ -930,6 +946,8 @@ var VideoLayout = (function (my) {
930 946
         $('#remoteVideos>span').width(width);
931 947
         $('#remoteVideos>span').height(height);
932 948
 
949
+        $('.userAvatar').css('left', (width - height) / 2);
950
+
933 951
         $(document).trigger("remotevideo.resized", [width, height]);
934 952
     };
935 953
 
@@ -1527,36 +1545,27 @@ var VideoLayout = (function (my) {
1527 1545
                 if (!isVisible) {
1528 1546
                     console.log("Add to last N", resourceJid);
1529 1547
 
1530
-                    mediaStreams.some(function (mediaStream) {
1531
-                        if (mediaStream.peerjid
1532
-                            && Strophe.getResourceFromJid(mediaStream.peerjid)
1533
-                                === resourceJid
1534
-                            && mediaStream.type === mediaStream.VIDEO_TYPE) {
1535
-                            var sel = $('#participant_' + resourceJid + '>video');
1536
-
1537
-                            var videoStream = simulcast.getReceivingVideoStream(mediaStream.stream);
1538
-                            RTC.attachMediaStream(sel, videoStream);
1539
-                            videoSrcToSsrc[sel.attr('src')] = mediaStream.ssrc;
1540
-                            if (lastNPickupJid == mediaStream.peerjid) {
1541
-                                // Clean up the lastN pickup jid.
1542
-                                lastNPickupJid = null;
1543
-
1544
-                                // Don't fire the events again, they've already
1545
-                                // been fired in the contact list click handler.
1546
-                                VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false);
1547
-
1548
-                                updateLargeVideo = false;
1549
-                            }
1548
+                    var jid = connection.emuc.findJidFromResource(resourceJid);
1549
+                    var mediaStream = mediaStreams[jid][MediaStream.VIDEO_TYPE];
1550
+                    var sel = $('#participant_' + resourceJid + '>video');
1550 1551
 
1551
-                            waitForRemoteVideo(
1552
-                                    sel,
1553
-                                    mediaStream.ssrc,
1554
-                                    mediaStream.stream);
1555
-                            return true;
1556
-                        }
1557
-                    });
1552
+                    var videoStream = simulcast.getReceivingVideoStream(
1553
+                        mediaStream.stream);
1554
+                    RTC.attachMediaStream(sel, videoStream);
1555
+                    videoSrcToSsrc[sel.attr('src')] = mediaStream.ssrc;
1556
+                    if (lastNPickupJid == mediaStream.peerjid) {
1557
+                        // Clean up the lastN pickup jid.
1558
+                        lastNPickupJid = null;
1559
+
1560
+                        // Don't fire the events again, they've already
1561
+                        // been fired in the contact list click handler.
1562
+                        VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false);
1563
+
1564
+                        updateLargeVideo = false;
1565
+                    }
1566
+                    waitForRemoteVideo(sel, mediaStream.ssrc, mediaStream.stream);
1558 1567
                 }
1559
-            });
1568
+            })
1560 1569
         }
1561 1570
 
1562 1571
         // The endpoint that was being shown in the large video has dropped out

Laden…
Abbrechen
Speichern