Browse Source

Fixes issues with invalid avatars and problems with switching between videos.

master
paweldomas 10 years ago
parent
commit
c3548eb866

+ 1
- 1
index.html View File

@@ -22,7 +22,7 @@
22 22
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
23 23
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
24 24
     <script src="interface_config.js?v=5"></script>
25
-    <script src="libs/app.bundle.js?v=106"></script>
25
+    <script src="libs/app.bundle.js?v=107"></script>
26 26
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
27 27
     <link rel="stylesheet" href="css/font.css?v=7"/>
28 28
     <link rel="stylesheet" href="css/toastr.css?v=1">

+ 22534
- 22502
libs/app.bundle.js
File diff suppressed because it is too large
View File


+ 10
- 2
modules/UI/UI.js View File

@@ -449,8 +449,12 @@ function onMucJoined(jid, info) {
449 449
     $("#localNick").html(Strophe.getResourceFromJid(jid) + " (" + meHTML + ")");
450 450
 
451 451
     var settings = Settings.getSettings();
452
+
453
+    // Make sure we configure our avatar id, before creating avatar for us
454
+    Avatar.setUserAvatar(jid, settings.email || settings.uid);
455
+
452 456
     // Add myself to the contact list.
453
-    ContactList.addContact(jid, settings.email || settings.uid);
457
+    ContactList.addContact(jid);
454 458
 
455 459
     // Once we've joined the muc show the toolbar
456 460
     ToolbarToggler.showToolbar();
@@ -572,8 +576,12 @@ function onMucMemberJoined(jid, id, displayName) {
572 576
     if(!config.startAudioMuted ||
573 577
         config.startAudioMuted > APP.members.size())
574 578
         UIUtil.playSoundNotification('userJoined');
579
+
580
+    // Configure avatar
581
+    Avatar.setUserAvatar(jid, id);
582
+
575 583
     // Add Peer's container
576
-    VideoLayout.ensurePeerContainerExists(jid,id);
584
+    VideoLayout.ensurePeerContainerExists(jid);
577 585
 }
578 586
 
579 587
 function onMucPresenceStatus(jid, info) {

+ 33
- 5
modules/UI/avatar/Avatar.js View File

@@ -17,15 +17,43 @@ var Avatar = {
17 17
             }
18 18
             users[jid] = id;
19 19
         }
20
-        var thumbUrl = this.getGravatarUrl(users[jid] || jid, 100);
21
-        var contactListUrl = this.getGravatarUrl(users[jid] || jid);
20
+        var thumbUrl = this.getThumbUrl(jid);
21
+        var contactListUrl = this.getContactListUrl(jid);
22 22
         var resourceJid = Strophe.getResourceFromJid(jid);
23 23
 
24 24
         APP.UI.userAvatarChanged(resourceJid, thumbUrl, contactListUrl);
25 25
     },
26
-    getGravatarUrl: function (id, size) {
27
-        if(id === APP.xmpp.myJid() || !id) {
28
-            id = Settings.getSettings().uid;
26
+    /**
27
+     * Returns image URL for the avatar to be displayed on large video area
28
+     * where current active speaker is presented.
29
+     * @param jid full MUC jid of the user for whom we want to obtain avatar URL
30
+     */
31
+    getActiveSpeakerUrl: function (jid) {
32
+        return this.getGravatarUrl(jid, 100);
33
+    },
34
+    /**
35
+     * Returns image URL for the avatar to be displayed on small video thumbnail
36
+     * @param jid full MUC jid of the user for whom we want to obtain avatar URL
37
+     */
38
+    getThumbUrl: function (jid) {
39
+        return this.getGravatarUrl(jid, 100);
40
+    },
41
+    /**
42
+     * Returns the URL for the avatar to be displayed as contactlist item
43
+     * @param jid full MUC jid of the user for whom we want to obtain avatar URL
44
+     */
45
+    getContactListUrl: function (jid) {
46
+        return this.getGravatarUrl(jid, 30);
47
+    },
48
+    getGravatarUrl: function (jid, size) {
49
+        if (!jid) {
50
+            console.error("Get gravatar - jid is undefined");
51
+            return null;
52
+        }
53
+        var id = users[jid];
54
+        if (!id) {
55
+            console.warn("No avatar stored yet for " + jid);
56
+            return null;
29 57
         }
30 58
         return 'https://www.gravatar.com/avatar/' +
31 59
             MD5.hexdigest(id.trim().toLowerCase()) +

+ 8
- 8
modules/UI/side_pannels/contactlist/ContactList.js View File

@@ -1,4 +1,6 @@
1 1
 
2
+var Avatar = require('../../avatar/Avatar');
3
+
2 4
 var numberOfContacts = 0;
3 5
 var notificationInterval;
4 6
 
@@ -27,10 +29,10 @@ function updateNumberOfParticipants(delta) {
27 29
  *
28 30
  * @return the newly created avatar element
29 31
  */
30
-function createAvatar(id) {
32
+function createAvatar(jid) {
31 33
     var avatar = document.createElement('img');
32 34
     avatar.className = "icon-avatar avatar";
33
-    avatar.src = "https://www.gravatar.com/avatar/" + id + "?d=wavatar&size=30";
35
+    avatar.src = Avatar.getContactListUrl(jid);
34 36
 
35 37
     return avatar;
36 38
 }
@@ -82,24 +84,22 @@ var ContactList = {
82 84
      * Adds a contact for the given peerJid if such doesn't yet exist.
83 85
      *
84 86
      * @param peerJid the peerJid corresponding to the contact
85
-     * @param id the user's email or userId used to get the user's avatar
86 87
      */
87
-    ensureAddContact: function (peerJid, id) {
88
+    ensureAddContact: function (peerJid) {
88 89
         var resourceJid = Strophe.getResourceFromJid(peerJid);
89 90
 
90 91
         var contact = $('#contacts>li[id="' + resourceJid + '"]');
91 92
 
92 93
         if (!contact || contact.length <= 0)
93
-            ContactList.addContact(peerJid, id);
94
+            ContactList.addContact(peerJid);
94 95
     },
95 96
 
96 97
     /**
97 98
      * Adds a contact for the given peer jid.
98 99
      *
99 100
      * @param peerJid the jid of the contact to add
100
-     * @param id the email or userId of the user
101 101
      */
102
-    addContact: function (peerJid, id) {
102
+    addContact: function (peerJid) {
103 103
         var resourceJid = Strophe.getResourceFromJid(peerJid);
104 104
 
105 105
         var contactlist = $('#contacts');
@@ -113,7 +113,7 @@ var ContactList = {
113 113
             }
114 114
         };
115 115
 
116
-        newContact.appendChild(createAvatar(id));
116
+        newContact.appendChild(createAvatar(peerJid));
117 117
         newContact.appendChild(createDisplayNameParagraph("participant"));
118 118
 
119 119
         if (resourceJid === APP.xmpp.myResource()) {

+ 3
- 1
modules/UI/videolayout/ConnectionIndicator.js View File

@@ -155,7 +155,9 @@ ConnectionIndicator.prototype.generateText = function () {
155 155
     if(this.videoContainer.videoSpanId == "localVideoContainer") {
156 156
         result += "<div class=\"jitsipopover_showmore\" " +
157 157
             "onclick = \"APP.UI.connectionIndicatorShowMore('" +
158
-            this.jid + "')\"  data-i18n='connectionindicator." +
158
+            // FIXME: we do not know local jid when this text is generated
159
+            //this.jid + "')\"  data-i18n='connectionindicator." +
160
+            "local')\"  data-i18n='connectionindicator." +
159 161
                 (this.showMoreValue ? "less" : "more") + "'>" +
160 162
             translate("connectionindicator." + (this.showMoreValue ? "less" : "more")) +
161 163
             "</div><br />";

+ 13
- 8
modules/UI/videolayout/LargeVideo.js View File

@@ -185,12 +185,12 @@ function getCameraVideoSize(videoWidth,
185 185
 function updateActiveSpeakerAvatarSrc() {
186 186
     var avatar = $("#activeSpeakerAvatar")[0];
187 187
     var jid = currentSmallVideo.peerJid;
188
-    var url = Avatar.getGravatarUrl(jid);
188
+    var url = Avatar.getActiveSpeakerUrl(jid);
189 189
     if (avatar.src === url)
190 190
         return;
191 191
     var isMuted = null;
192 192
     if (!currentSmallVideo.isLocal &&
193
-       !LargeVideo.VideoLayout.isInLastN(currentSmallVideo.resourceJid)) {
193
+       !LargeVideo.VideoLayout.isInLastN(currentSmallVideo.getResourceJid())) {
194 194
         isMuted = true;
195 195
     }
196 196
     else
@@ -280,6 +280,13 @@ var LargeVideo = {
280 280
     isLargeVideoVisible: function() {
281 281
         return $('#largeVideo').is(':visible');
282 282
     },
283
+    /**
284
+     * Returns <tt>true</tt> if the user is currently displayed on large video.
285
+     */
286
+    isCurrentlyOnLarge: function (resourceJid) {
287
+        return currentSmallVideo && resourceJid &&
288
+            currentSmallVideo.getResourceJid() === resourceJid;
289
+    },
283 290
     /**
284 291
      * Updates the large video with the given new video source.
285 292
      */
@@ -287,8 +294,7 @@ var LargeVideo = {
287 294
         var newSmallVideo = this.VideoLayout.getSmallVideo(resourceJid);
288 295
         console.log('hover in ' + resourceJid + ', video: ', newSmallVideo);
289 296
 
290
-        if ((currentSmallVideo && currentSmallVideo.resourceJid !== resourceJid)
291
-            || forceUpdate) {
297
+        if (!LargeVideo.isCurrentlyOnLarge(resourceJid) || forceUpdate) {
292 298
             $('#activeSpeaker').css('visibility', 'hidden');
293 299
 
294 300
             if(currentSmallVideo) {
@@ -337,7 +343,8 @@ var LargeVideo = {
337 343
         }
338 344
     },
339 345
     onVideoTypeChanged: function (jid) {
340
-        if(jid && currentSmallVideo && jid === currentSmallVideo.peerJid)
346
+        var resourceJid = Strophe.getResourceFromJid(jid);
347
+        if (LargeVideo.isCurrentlyOnLarge(resourceJid))
341 348
         {
342 349
             var isDesktop = APP.RTC.isVideoSrcDesktop(jid);
343 350
             getVideoSize = isDesktop
@@ -438,9 +445,7 @@ var LargeVideo = {
438 445
         this.position(null, null, size[0], size[1], true);
439 446
     },
440 447
     getResourceJid: function () {
441
-        if(!currentSmallVideo)
442
-            return null;
443
-        return currentSmallVideo.resourceJid;
448
+        return currentSmallVideo ? currentSmallVideo.getResourceJid() : null;
444 449
     },
445 450
     updateAvatar: function (resourceJid) {
446 451
         if (resourceJid === this.getResourceJid()) {

+ 12
- 6
modules/UI/videolayout/LocalVideo.js View File

@@ -13,7 +13,6 @@ function LocalVideo(VideoLayout)
13 13
     this.flipX = true;
14 14
     this.isLocal = true;
15 15
     this.peerJid = null;
16
-    this.resourceJid = null;
17 16
 }
18 17
 
19 18
 LocalVideo.prototype = Object.create(SmallVideo.prototype);
@@ -184,8 +183,8 @@ LocalVideo.prototype.changeVideo = function (stream, isMuted) {
184 183
             self.showDisplayName(true);
185 184
         },
186 185
         function() {
187
-            if (!LargeVideo.isLargeVideoVisible()
188
-                || APP.xmpp.myResource() !== LargeVideo.getResourceJid())
186
+            if (!LargeVideo.isLargeVideoVisible() ||
187
+                !LargeVideo.isCurrentlyOnLarge(self.getResourceJid()))
189 188
                 self.showDisplayName(false);
190 189
         }
191 190
     );
@@ -231,11 +230,18 @@ LocalVideo.prototype.changeVideo = function (stream, isMuted) {
231 230
         localVideoContainer.removeChild(localVideo);
232 231
         self.VideoLayout.updateRemovedVideo(APP.xmpp.myResource());
233 232
     };
234
-}
233
+};
235 234
 
236 235
 LocalVideo.prototype.joined = function (jid) {
237 236
     this.peerJid = jid;
238
-    this.resourceJid = Strophe.getResourceFromJid(jid);
239
-}
237
+};
238
+
239
+LocalVideo.prototype.getResourceJid = function () {
240
+    var myResource = APP.xmpp.myResource();
241
+    if (!myResource) {
242
+        console.error("Requested local resource before we're in the MUC");
243
+    }
244
+    return myResource;
245
+};
240 246
 
241 247
 module.exports = LocalVideo;

+ 21
- 28
modules/UI/videolayout/RemoteVideo.js View File

@@ -57,7 +57,7 @@ RemoteVideo.prototype.addRemoteVideoMenu = function () {
57 57
     var popupmenuElement = document.createElement('ul');
58 58
     popupmenuElement.className = 'popupmenu';
59 59
     popupmenuElement.id
60
-        = 'remote_popupmenu_' + this.resourceJid;
60
+        = 'remote_popupmenu_' + this.getResourceJid();
61 61
     spanElement.appendChild(popupmenuElement);
62 62
 
63 63
     var muteMenuItem = document.createElement('li');
@@ -162,7 +162,7 @@ RemoteVideo.prototype.removeRemoteStreamElement = function (stream, isVideo, id)
162 162
     }
163 163
 
164 164
     if (isVideo)
165
-        this.VideoLayout.updateRemovedVideo(this.resourceJid);
165
+        this.VideoLayout.updateRemovedVideo(this.getResourceJid());
166 166
 };
167 167
 
168 168
 RemoteVideo.prototype.waitForPlayback = function (stream) {
@@ -173,7 +173,8 @@ RemoteVideo.prototype.waitForPlayback = function (stream) {
173 173
     }
174 174
 
175 175
     var self = this;
176
-    var sel = this.VideoLayout.getPeerVideoSel(this.resourceJid);
176
+    var resourceJid = this.getResourceJid();
177
+    var sel = this.VideoLayout.getPeerVideoSel(resourceJid);
177 178
 
178 179
     // Register 'onplaying' listener to trigger 'videoactive' on VideoLayout
179 180
     // when video playback starts
@@ -183,9 +184,9 @@ RemoteVideo.prototype.waitForPlayback = function (stream) {
183 184
             APP.RTC.attachMediaStream(sel, stream);
184 185
         }
185 186
         if (RTCBrowserType.isTemasysPluginUsed()) {
186
-            sel = $('#' + newElementId);
187
+            sel = self.VideoLayout.getPeerVideoSel(resourceJid);
187 188
         }
188
-        self.VideoLayout.videoactive(sel, self.resourceJid);
189
+        self.VideoLayout.videoactive(sel, resourceJid);
189 190
         sel[0].onplaying = null;
190 191
         if (RTCBrowserType.isTemasysPluginUsed()) {
191 192
             // 'currentTime' is used to check if the video has started
@@ -229,16 +230,9 @@ RemoteVideo.prototype.addRemoteStreamElement = function (sid, stream, thessrc) {
229 230
 
230 231
     // Add click handler.
231 232
     var onClickHandler = function (event) {
232
-        /*
233
-         * FIXME It turns out that videoThumb may not exist (if there is
234
-         * no actual video).
235
-         */
236
-        var videoThumb = $('#' + self.videoSpanId + '>' + videoElem).get(0);
237
-        if (videoThumb) {
238
-            self.VideoLayout.handleVideoThumbClicked(
239
-                false,
240
-                self.resourceJid);
241
-        }
233
+
234
+        self.VideoLayout.handleVideoThumbClicked(false, self.getResourceJid());
235
+
242 236
         // On IE we need to populate this handler on video <object>
243 237
         // and it does not give event instance as an argument,
244 238
         // so we check here for methods.
@@ -261,16 +255,10 @@ RemoteVideo.prototype.addRemoteStreamElement = function (sid, stream, thessrc) {
261 255
             self.showDisplayName(true);
262 256
         },
263 257
         function() {
264
-            var videoSrc = null;
265
-            var videoSelector = $('#' + self.videoSpanId + '>' + videoElem);
266
-            if (videoSelector && videoSelector.length > 0) {
267
-                videoSrc = APP.RTC.getVideoSrc(videoSelector.get(0));
268
-            }
269
-
270 258
             // If the video has been "pinned" by the user we want to
271 259
             // keep the display name on place.
272
-            if (!LargeVideo.isLargeVideoVisible()
273
-                || videoSrc !== APP.RTC.getVideoSrc($('#largeVideo')[0]))
260
+            if (!LargeVideo.isLargeVideoVisible() ||
261
+                !LargeVideo.isCurrentlyOnLarge(self.getResourceJid()))
274 262
                 self.showDisplayName(false);
275 263
         }
276 264
     );
@@ -330,9 +318,7 @@ RemoteVideo.prototype.hideConnectionIndicator = function () {
330 318
  */
331 319
 RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted) {
332 320
     var muteMenuItem
333
-        = $('#remote_popupmenu_'
334
-        + this.resourceJid
335
-        + '>li>a.mutelink');
321
+        = $('#remote_popupmenu_' + this.getResourceJid() + '>li>a.mutelink');
336 322
 
337 323
     var mutedIndicator = "<i class='icon-mic-disabled'></i>";
338 324
 
@@ -348,7 +334,7 @@ RemoteVideo.prototype.updateRemoteVideoMenu = function (isMuted) {
348 334
             muteLink.className = 'mutelink';
349 335
         }
350 336
     }
351
-}
337
+};
352 338
 
353 339
 /**
354 340
  * Sets the display name for the given video span id.
@@ -407,7 +393,14 @@ RemoteVideo.prototype.removeRemoteVideoMenu = function() {
407 393
     if (menuSpan.length) {
408 394
         menuSpan.remove();
409 395
     }
410
-}
396
+};
397
+
398
+RemoteVideo.prototype.getResourceJid = function () {
399
+    if (!this.resourceJid) {
400
+        console.error("Undefined resource jid");
401
+    }
402
+    return this.resourceJid;
403
+};
411 404
 
412 405
 RemoteVideo.createContainer = function (spanId) {
413 406
     var container = document.createElement('span');

+ 29
- 22
modules/UI/videolayout/SmallVideo.js View File

@@ -1,3 +1,4 @@
1
+var Avatar = require("../avatar/Avatar");
1 2
 var UIUtil = require("../util/UIUtil");
2 3
 var LargeVideo = require("./LargeVideo");
3 4
 var RTCBrowserType = require("../../RTC/RTCBrowserType");
@@ -192,14 +193,15 @@ SmallVideo.prototype.showVideoIndicator = function(isMuted) {
192 193
 
193 194
 SmallVideo.prototype.enableDominantSpeaker = function (isEnable)
194 195
 {
195
-    var displayName = this.resourceJid;
196
+    var resourceJid = this.getResourceJid();
197
+    var displayName = resourceJid;
196 198
     var nameSpan = $('#' + this.videoSpanId + '>span.displayname');
197 199
     if (nameSpan.length > 0)
198 200
         displayName = nameSpan.html();
199 201
 
200 202
     console.log("UI enable dominant speaker",
201 203
         displayName,
202
-        this.resourceJid,
204
+        resourceJid,
203 205
         isEnable);
204 206
 
205 207
 
@@ -207,21 +209,17 @@ SmallVideo.prototype.enableDominantSpeaker = function (isEnable)
207 209
         return;
208 210
     }
209 211
 
210
-    var video = $('#' + this.videoSpanId + '>' + APP.RTC.getVideoElementName());
212
+    if (isEnable) {
213
+        this.showDisplayName(LargeVideo.isLargeVideoOnTop());
211 214
 
212
-    if (video && video.length > 0) {
213
-        if (isEnable) {
214
-            this.showDisplayName(LargeVideo.isLargeVideoOnTop());
215
-
216
-            if (!this.container.classList.contains("dominantspeaker"))
217
-                this.container.classList.add("dominantspeaker");
218
-        }
219
-        else {
220
-            this.showDisplayName(false);
215
+        if (!this.container.classList.contains("dominantspeaker"))
216
+            this.container.classList.add("dominantspeaker");
217
+    }
218
+    else {
219
+        this.showDisplayName(false);
221 220
 
222
-            if (this.container.classList.contains("dominantspeaker"))
223
-                this.container.classList.remove("dominantspeaker");
224
-        }
221
+        if (this.container.classList.contains("dominantspeaker"))
222
+            this.container.classList.remove("dominantspeaker");
225 223
     }
226 224
 
227 225
     this.showAvatar();
@@ -305,16 +303,24 @@ SmallVideo.prototype.hasVideo = function () {
305 303
  * video because there is no dominant speaker and no focused speaker
306 304
  */
307 305
 SmallVideo.prototype.showAvatar = function (show) {
308
-    if (!this.hasAvatar)
309
-        return;
306
+    if (!this.hasAvatar) {
307
+        if (this.peerJid) {
308
+            // Init avatar
309
+            this.avatarChanged(Avatar.getThumbUrl(this.peerJid));
310
+        } else {
311
+            console.error("Unable to init avatar - no peerjid", this);
312
+            return;
313
+        }
314
+    }
310 315
 
316
+    var resourceJid = this.getResourceJid();
311 317
     var videoElem = APP.RTC.getVideoElementName();
312 318
     var video = $('#' + this.videoSpanId).find(videoElem);
313
-    var avatar = $('#avatar_' + this.resourceJid);
319
+    var avatar = $('#avatar_' + resourceJid);
314 320
 
315 321
     if (show === undefined || show === null) {
316 322
         if (!this.isLocal &&
317
-            !this.VideoLayout.isInLastN(this.resourceJid)) {
323
+            !this.VideoLayout.isInLastN(resourceJid)) {
318 324
             show = true;
319 325
         }
320 326
         else
@@ -324,7 +330,7 @@ SmallVideo.prototype.showAvatar = function (show) {
324 330
 
325 331
     }
326 332
 
327
-    if (LargeVideo.showAvatar(this.resourceJid, show))
333
+    if (LargeVideo.showAvatar(resourceJid, show))
328 334
     {
329 335
         setVisibility(avatar, false);
330 336
         setVisibility(video, false);
@@ -339,7 +345,8 @@ SmallVideo.prototype.showAvatar = function (show) {
339 345
 
340 346
 SmallVideo.prototype.avatarChanged = function (thumbUrl) {
341 347
     var thumbnail = $('#' + this.videoSpanId);
342
-    var avatar = $('#avatar_' + this.resourceJid);
348
+    var resourceJid = this.getResourceJid();
349
+    var avatar = $('#avatar_' + resourceJid);
343 350
     this.hasAvatar = true;
344 351
 
345 352
     // set the avatar in the thumbnail
@@ -348,7 +355,7 @@ SmallVideo.prototype.avatarChanged = function (thumbUrl) {
348 355
     } else {
349 356
         if (thumbnail && thumbnail.length > 0) {
350 357
             avatar = document.createElement('img');
351
-            avatar.id = 'avatar_' + this.resourceJid;
358
+            avatar.id = 'avatar_' + resourceJid;
352 359
             avatar.className = 'userAvatar';
353 360
             avatar.src = thumbUrl;
354 361
             thumbnail.append(avatar);

+ 49
- 59
modules/UI/videolayout/VideoLayout.js View File

@@ -72,11 +72,10 @@ var VideoLayout = (function (my) {
72 72
 
73 73
         localVideoThumbnail.changeVideo(stream, isMuted);
74 74
 
75
-        LargeVideo.updateLargeVideo(
76
-            APP.xmpp.myResource(),
77
-            /* force update only before conference starts */
78
-            !APP.xmpp.isConferenceInProgress());
79
-
75
+        /* force update if we're currently being displayed */
76
+        if (LargeVideo.isCurrentlyOnLarge(APP.xmpp.myResource())) {
77
+            LargeVideo.updateLargeVideo(APP.xmpp.myResource(), true);
78
+        }
80 79
     };
81 80
 
82 81
     my.mucJoined = function () {
@@ -116,53 +115,39 @@ var VideoLayout = (function (my) {
116 115
      */
117 116
     my.updateRemovedVideo = function(resourceJid) {
118 117
 
119
-        var videoElem = RTC.getVideoElementName();
120
-
121 118
         if (resourceJid === LargeVideo.getResourceJid()) {
122
-            // this is currently displayed as large
123
-            // pick the last visible video in the row
124
-            // if nobody else is left, this picks the local video
125
-            var pick
126
-                = $('#remoteVideos>' +
127
-                    'span[id!="mixedstream"]:visible:last>' + videoElem).get(0);
128
-
129
-            if (!pick) {
130
-                console.info("Last visible video no longer exists");
131
-                pick = $('#remoteVideos>' +
132
-                    'span[id!="mixedstream"]>' + videoElem).get(0);
133
-
134
-                if (!pick || !APP.RTC.getVideoSrc(pick)) {
135
-                    // Try local video
136
-                    console.info("Fallback to local video...");
137
-                    pick = $('#remoteVideos>span>span>' + videoElem).get(0);
138
-                }
139
-            }
140
-
141
-            // mute if localvideo
142
-            if (pick) {
143
-                var container = pick.parentNode;
119
+            var newResourceJid;
120
+            // We'll show user's avatar if he is the dominant speaker or if
121
+            // his video thumbnail is pinned
122
+            if (resourceJid === focusedVideoResourceJid ||
123
+                resourceJid === currentDominantSpeaker) {
124
+                newResourceJid = resourceJid;
144 125
             } else {
145
-                console.warn("Failed to elect large video");
146
-                container = $('#remoteVideos>span[id!="mixedstream"]:visible:last').get(0);
147
-
126
+                // Otherwise select last visible video
127
+                newResourceJid = this.electLastVisibleVideo();
148 128
             }
129
+            LargeVideo.updateLargeVideo(newResourceJid);
130
+        }
131
+    };
149 132
 
150
-            var jid = null;
151
-            if(container)
152
-            {
153
-                if(container.id == "localVideoWrapper")
154
-                {
155
-                    jid = APP.xmpp.myResource();
156
-                }
157
-                else
158
-                {
159
-                    jid = VideoLayout.getPeerContainerResourceJid(container);
160
-                }
133
+    my.electLastVisibleVideo = function() {
134
+        // pick the last visible video in the row
135
+        // if nobody else is left, this picks the local video
136
+        var jid;
137
+        var videoElem = RTC.getVideoElementName();
138
+        var pick = $('#remoteVideos>span[id!="mixedstream"]:visible:last>' + videoElem);
139
+        if (pick.length && APP.RTC.getVideoSrc(pick[0])) {
140
+            return VideoLayout.getPeerContainerResourceJid(pick[0].parentNode);
141
+        } else {
142
+            console.info("Last visible video no longer exists");
143
+            pick = $('#remoteVideos>span[id!="mixedstream"]>' + videoElem);
144
+            if (pick.length && APP.RTC.getVideoSrc(pick[0])) {
145
+                return VideoLayout.getPeerContainerResourceJid(pick[0].parentNode);
146
+            } else {
147
+                // Try local video
148
+                console.info("Fallback to local video...");
149
+                return APP.xmpp.myResource();
161 150
             }
162
-            else
163
-                return;
164
-
165
-            LargeVideo.updateLargeVideo(jid);
166 151
         }
167 152
     };
168 153
     
@@ -224,11 +209,6 @@ var VideoLayout = (function (my) {
224 209
             }
225 210
         }
226 211
 
227
-        if (LargeVideo.getResourceJid() === resourceJid &&
228
-            LargeVideo.isLargeVideoOnTop()) {
229
-            return;
230
-        }
231
-
232 212
         // Triggers a "video.selected" event. The "false" parameter indicates
233 213
         // this isn't a prezi.
234 214
         $(document).trigger("video.selected", [false]);
@@ -250,20 +230,18 @@ var VideoLayout = (function (my) {
250 230
      * in the document and creates it eventually.
251 231
      * 
252 232
      * @param peerJid peer Jid to check.
253
-     * @param userId user email or id for setting the avatar
254 233
      * 
255 234
      * @return Returns <tt>true</tt> if the peer container exists,
256 235
      * <tt>false</tt> - otherwise
257 236
      */
258
-    my.ensurePeerContainerExists = function(peerJid, userId) {
259
-        ContactList.ensureAddContact(peerJid, userId);
237
+    my.ensurePeerContainerExists = function(peerJid) {
238
+        ContactList.ensureAddContact(peerJid);
260 239
 
261 240
         var resourceJid = Strophe.getResourceFromJid(peerJid);
262 241
 
263 242
         if(!remoteVideos[resourceJid])
264 243
         {
265 244
             remoteVideos[resourceJid] = new RemoteVideo(peerJid, VideoLayout);
266
-            Avatar.setUserAvatar(peerJid, userId);
267 245
 
268 246
             // In case this is not currently in the last n we don't show it.
269 247
             if (localLastNCount
@@ -282,6 +260,9 @@ var VideoLayout = (function (my) {
282 260
     };
283 261
 
284 262
     my.videoactive = function (videoelem, resourceJid) {
263
+
264
+        console.info(resourceJid + " video is now active");
265
+
285 266
         videoelem.show();
286 267
         VideoLayout.resizeThumbnails();
287 268
 
@@ -291,6 +272,7 @@ var VideoLayout = (function (my) {
291 272
         if ((!focusedVideoResourceJid &&
292 273
             !currentDominantSpeaker &&
293 274
             !require("../prezi/Prezi").isPresentationVisible()) ||
275
+            focusedVideoResourceJid === resourceJid ||
294 276
             (resourceJid &&
295 277
                 currentDominantSpeaker === resourceJid)) {
296 278
             LargeVideo.updateLargeVideo(resourceJid, true);
@@ -469,7 +451,7 @@ var VideoLayout = (function (my) {
469 451
             return;
470 452
         }
471 453
 
472
-        if (jid == APP.xmpp.myJid()) {
454
+        if (jid === APP.xmpp.myJid()) {
473 455
             $("#localVideoContainer").click();
474 456
             return;
475 457
         }
@@ -824,13 +806,18 @@ var VideoLayout = (function (my) {
824 806
     };
825 807
 
826 808
     my.showMore = function (jid) {
827
-        if(APP.xmpp.myJid = jid)
809
+        if (jid === 'local')
828 810
         {
829 811
             localVideoThumbnail.connectionIndicator.showMore();
830 812
         }
831 813
         else
832 814
         {
833
-            remoteVideos[Strophe.getResourceFromJid(jid)].connectionIndicator.showMore();
815
+            var remoteVideo = remoteVideos[Strophe.getResourceFromJid(jid)];
816
+            if (remoteVideo) {
817
+                remoteVideo.connectionIndicator.showMore();
818
+            } else {
819
+                console.info("Error - no remote video for jid: " + jid);
820
+            }
834 821
         }
835 822
 
836 823
     };
@@ -880,6 +867,9 @@ var VideoLayout = (function (my) {
880 867
         var smallVideo = VideoLayout.getSmallVideo(resourceJid);
881 868
         if(smallVideo)
882 869
             smallVideo.avatarChanged(thumbUrl);
870
+        else
871
+            console.warn(
872
+                "Missed avatar update - no small video yet for " + resourceJid);
883 873
         LargeVideo.updateAvatar(resourceJid, thumbUrl);
884 874
     };
885 875
 

Loading…
Cancel
Save