Преглед изворни кода

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

master
fo пре 10 година
родитељ
комит
1d4177faeb
23 измењених фајлова са 785 додато и 370 уклоњено
  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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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
+}


+ 1
- 0
fonts/jitsi.svg Прегледај датотеку

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



+ 42
- 7
fonts/selection.json Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

@@ -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 Прегледај датотеку

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

Loading…
Откажи
Сачувај