Browse Source

Video thumbnails redesign

j8
yanas 8 years ago
parent
commit
0013745783

+ 1
- 1
css/_font.scss View File

16
     font-weight: normal;
16
     font-weight: normal;
17
     font-variant: normal;
17
     font-variant: normal;
18
     text-transform: none;
18
     text-transform: none;
19
-    line-height: 0.75em;
19
+    line-height: 1.22em;
20
     font-size: 1.22em;
20
     font-size: 1.22em;
21
 
21
 
22
     /* Better Font Rendering =========== */
22
     /* Better Font Rendering =========== */

+ 13
- 0
css/_mixins.scss View File

36
   }
36
   }
37
 }
37
 }
38
 
38
 
39
+@mixin circle($diameter) {
40
+    width: $diameter;
41
+    height: $diameter;
42
+    border-radius: 50%;
43
+}
44
+
45
+@mixin absoluteAligning($sizeX, $sizeY) {
46
+    top: 50%;
47
+    left: 50%;
48
+    position: absolute;
49
+    @include transform(translate(-#{$sizeX / 2}, -#{$sizeY / 2}))
50
+}
51
+
39
 @mixin transform($func) {
52
 @mixin transform($func) {
40
     -moz-transform: $func;
53
     -moz-transform: $func;
41
     -ms-transform: $func;
54
     -ms-transform: $func;

+ 22
- 5
css/_variables.scss View File

10
  */
10
  */
11
 $defaultToolbarSize: 50px;
11
 $defaultToolbarSize: 50px;
12
 
12
 
13
+// Video layout.
14
+$thumbnailIndicatorSize: 23px;
15
+$thumbnailIndicatorBorder: 0px;
16
+$thumbnailVideoMargin: 2px;
17
+
13
 /**
18
 /**
14
  * Color variables.
19
  * Color variables.
15
  */
20
  */
17
 $defaultSemiDarkColor: #ACACAC;
22
 $defaultSemiDarkColor: #ACACAC;
18
 $defaultDarkColor: #4F4F4F;
23
 $defaultDarkColor: #4F4F4F;
19
 $defaultBackground: #474747;
24
 $defaultBackground: #474747;
25
+
26
+// Toolbar
20
 $toolbarSelectBackground: rgba(0, 0, 0, .6);
27
 $toolbarSelectBackground: rgba(0, 0, 0, .6);
28
+
29
+// Main controls
21
 $inputBackground: rgba(132, 132, 132, .5);
30
 $inputBackground: rgba(132, 132, 132, .5);
22
 $inputSemiBackground: rgba(132, 132, 132, .8);
31
 $inputSemiBackground: rgba(132, 132, 132, .8);
23
 $inputLightBackground: #EBEBEB;
32
 $inputLightBackground: #EBEBEB;
24
 $inputBorderColor: #EBEBEB;
33
 $inputBorderColor: #EBEBEB;
25
 $buttonBackground: #44A5FF;
34
 $buttonBackground: #44A5FF;
26
 
35
 
36
+// Video layout.
37
+$videoThumbnailHovered: #44A5FF;
38
+$videoThumbnailSelected: #165ecc;
39
+$participantNameColor: #fff;
40
+$thumbnailPictogramColor: #fff;
41
+$dominantSpeakerBg: #165ecc;
42
+$raiseHandBg: #D6D61E;
43
+
44
+$rateStarDefault: #ccc;
45
+$rateStarActivity: #165ecc;
46
+$rateStarLabelColor: #333;
47
+
27
 /**
48
 /**
28
  * Misc.
49
  * Misc.
29
  */
50
  */
34
  * Z-indexes. TODO: Replace this by a function.
55
  * Z-indexes. TODO: Replace this by a function.
35
  */
56
  */
36
 $toolbarZ: 900;
57
 $toolbarZ: 900;
37
-$overlayZ: 800;
38
-
39
-$rateStarDefault: #ccc;
40
-$rateStarActivity: #f6c342;
41
-$rateStarLabelColor: #333;
58
+$overlayZ: 800;

+ 62
- 44
css/_videolayout_default.scss View File

13
     display: -ms-flexbox;
13
     display: -ms-flexbox;
14
     display: -webkit-flex;
14
     display: -webkit-flex;
15
     display: flex;
15
     display: flex;
16
-    flex-direction: row;
16
+    flex-direction: row-reverse;
17
     flex-wrap: nowrap;
17
     flex-wrap: nowrap;
18
-    justify-content: flex-end;
18
+    justify-content: flex-start;
19
 
19
 
20
     position:absolute;
20
     position:absolute;
21
     text-align:right;
21
     text-align:right;
22
     height:196px;
22
     height:196px;
23
-    padding: 18px;
23
+    padding: 10px 10px 10px 5px;
24
     bottom: 0;
24
     bottom: 0;
25
     left: 0;
25
     left: 0;
26
-    right: 20px;
26
+    right: 0;
27
     width:auto;
27
     width:auto;
28
     border:1px solid transparent;
28
     border:1px solid transparent;
29
     z-index: 5;
29
     z-index: 5;
43
 
43
 
44
 #remoteVideos .videocontainer {
44
 #remoteVideos .videocontainer {
45
     display: none;
45
     display: none;
46
+    position: relative;
46
     background-color: black;
47
     background-color: black;
47
     background-size: contain;
48
     background-size: contain;
48
     border-radius:1px;
49
     border-radius:1px;
49
-    border: 1px solid #212425;
50
+    margin: 0 $thumbnailVideoMargin;
51
+    border: 1px solid $defaultDarkColor;
52
+}
53
+
54
+.videocontainer__toolbar {
55
+    position: absolute;
56
+    bottom: 0;
57
+    left: 0;
58
+    z-index: 1;
59
+    width: 100%;
60
+    height: 25px;
61
+    max-height: 100%;
62
+    background-color: rgba(0, 0, 0, 0.5);
50
 }
63
 }
51
 
64
 
52
 #remoteVideos .videocontainer.videoContainerFocused {
65
 #remoteVideos .videocontainer.videoContainerFocused {
58
     -webkit-animation-iteration-count: 1;
71
     -webkit-animation-iteration-count: 1;
59
 }
72
 }
60
 
73
 
61
-#remoteVideos .videocontainer:hover {
62
-    border: 1px solid #c1c1c1;
63
-}
64
-
65
 #remoteVideos .videocontainer.videoContainerFocused {
74
 #remoteVideos .videocontainer.videoContainerFocused {
66
-    box-shadow: inset 0 0 28px #006d91;
67
-    border: 1px solid #006d91;
75
+    border: 1px solid $videoThumbnailSelected;
68
 }
76
 }
69
 
77
 
78
+#remoteVideos .videocontainer:hover,
70
 #remoteVideos .videocontainer.videoContainerFocused:hover {
79
 #remoteVideos .videocontainer.videoContainerFocused:hover {
71
-    box-shadow: inset 0 0 5px #c1c1c1, 0 0 10px #c1c1c1, inset 0 0 60px #006d91;
72
-    border: 1px solid #c1c1c1;
80
+    border: 1px solid $videoThumbnailHovered;
73
 }
81
 }
74
 
82
 
75
 #localVideoWrapper {
83
 #localVideoWrapper {
145
 #remoteVideos .videocontainer>div.remotevideomenu {
153
 #remoteVideos .videocontainer>div.remotevideomenu {
146
     position: absolute;
154
     position: absolute;
147
     color: #FFFFFF;
155
     color: #FFFFFF;
148
-    top: 0;
149
-    left: 0;
156
+    bottom: 0;
157
+    right: 0;
150
     padding: 5px 0px;
158
     padding: 5px 0px;
151
     width: 25px;
159
     width: 25px;
152
-    font-size: 11pt;
160
+    font-size: 9pt;
153
     text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
161
     text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
154
     border: 0px;
162
     border: 0px;
155
     z-index: 2;
163
     z-index: 2;
166
 
174
 
167
 .videocontainer>span.displayname,
175
 .videocontainer>span.displayname,
168
 .videocontainer>input.displayname {
176
 .videocontainer>input.displayname {
169
-    display: none;
177
+    display: inline-block;
170
     position: absolute;
178
     position: absolute;
171
-    color: #FFFFFF;
172
-    background: rgba(0,0,0,.7);
179
+    bottom: 4px;
180
+    left: 25%;
181
+    color: $participantNameColor;
173
     text-align: center;
182
     text-align: center;
174
     text-overflow: ellipsis;
183
     text-overflow: ellipsis;
175
-    width: 70%;
176
-    height: 20%;
177
-    left: 15%;
178
-    top: 40%;
179
-    padding: 5px;
180
-    font-size: 11pt;
184
+    width: 50%;
185
+    font-size: 12px;
186
+    font-weight: 100;
187
+    letter-spacing: 1px;
181
     overflow: hidden;
188
     overflow: hidden;
182
     white-space: nowrap;
189
     white-space: nowrap;
183
     z-index: 2;
190
     z-index: 2;
184
-    border-radius:3px;
191
+}
192
+
193
+.videocontainer>input.displayname {
194
+    outline: none;
195
+    border: none;
196
+    background: none;
197
+    box-shadow: none;
198
+    padding: 0;
185
 }
199
 }
186
 
200
 
187
 .videocontainer>span.status {
201
 .videocontainer>span.status {
291
     display: inline-block;
305
     display: inline-block;
292
     position: absolute;
306
     position: absolute;
293
     color: #FFFFFF;
307
     color: #FFFFFF;
294
-    top: 0;
308
+    bottom: 0;
309
+    left: 0;
295
     padding: 8px 5px;
310
     padding: 8px 5px;
296
     width: 25px;
311
     width: 25px;
297
     font-size: 8pt;
312
     font-size: 8pt;
305
     display: inline-block;
320
     display: inline-block;
306
     position: absolute;
321
     position: absolute;
307
     color: #FFFFFF;
322
     color: #FFFFFF;
308
-    top: 0;
309
-    right: 0;
323
+    bottom: 0;
310
     padding: 8px 5px;
324
     padding: 8px 5px;
311
     width: 25px;
325
     width: 25px;
312
     font-size: 8pt;
326
     font-size: 8pt;
316
 }
330
 }
317
 
331
 
318
 .videocontainer>span.indicator {
332
 .videocontainer>span.indicator {
319
-    bottom: 0px;
333
+    position: absolute;
334
+    top: 0px;
320
     left: 0px;
335
     left: 0px;
321
-    width: 25px;
322
-    height: 25px;
336
+    @include circle($thumbnailIndicatorSize);
337
+    box-sizing: border-box;
338
+    line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
323
     z-index: 3;
339
     z-index: 3;
324
     text-align: center;
340
     text-align: center;
325
-    border-radius: 50%;
326
-    background: #21B9FC;
327
-    margin: 5px;
341
+    background: $dominantSpeakerBg;
342
+    margin: 7px;
328
     display: inline-block;
343
     display: inline-block;
329
-    position: absolute;
330
-    color: #FFFFFF;
331
-    font-size: 11pt;
332
-    border: 0px;
344
+    color: $thumbnailPictogramColor;
345
+    font-size: 8pt;
346
+    border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor;
347
+}
348
+
349
+.videocontainer>#raisehandindicator {
350
+    background: $raiseHandBg;
333
 }
351
 }
334
 
352
 
335
 #indicatoricon {
353
 #indicatoricon {
336
-    padding-top: 5px;
354
+    width: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
355
+    height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
356
+    line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
337
 }
357
 }
338
 
358
 
339
 #reloadPresentation {
359
 #reloadPresentation {
395
 }
415
 }
396
 
416
 
397
 .userAvatar {
417
 .userAvatar {
398
-    height: 100%;
399
-    position: absolute;
400
-    left: 0;
401
-    border-radius: 2px;
418
+    @include circle(60px);
419
+    @include absoluteAligning(60px, 60px);
402
 }
420
 }
403
 
421
 
404
 .sharedVideoAvatar {
422
 .sharedVideoAvatar {

+ 2
- 1
index.html View File

238
             </div>
238
             </div>
239
 
239
 
240
             <div id="remoteVideos">
240
             <div id="remoteVideos">
241
-                <span id="localVideoContainer" class="videocontainer">
241
+                <span id="localVideoContainer" class="videocontainer videocontainer_small">
242
                     <span id="localVideoWrapper">
242
                     <span id="localVideoWrapper">
243
                         <!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
243
                         <!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
244
                     </span>
244
                     </span>
245
                     <audio id="localAudio" autoplay muted></audio>
245
                     <audio id="localAudio" autoplay muted></audio>
246
                     <span class="focusindicator"></span>
246
                     <span class="focusindicator"></span>
247
+                    <div class="videocontainer__toolbar"></div>
247
                 </span>
248
                 </span>
248
                 <audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
249
                 <audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
249
                 <audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
250
                 <audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>

+ 6
- 2
interface_config.js View File

34
     filmStripOnly: false,
34
     filmStripOnly: false,
35
     RANDOM_AVATAR_URL_PREFIX: false,
35
     RANDOM_AVATAR_URL_PREFIX: false,
36
     RANDOM_AVATAR_URL_SUFFIX: false,
36
     RANDOM_AVATAR_URL_SUFFIX: false,
37
-    FILM_STRIP_MAX_HEIGHT: 120
38
-};
37
+    FILM_STRIP_MAX_HEIGHT: 120,
38
+    LOCAL_THUMBNAIL_RATIO_WIDTH: 16,
39
+    LOCAL_THUMBNAIL_RATIO_HEIGHT: 9,
40
+    REMOTE_THUMBNAIL_RATIO_WIDTH: 1,
41
+    REMOTE_THUMBNAIL_RATIO_HEIGHT: 1
42
+};

+ 1
- 0
modules/UI/Feedback.js View File

1
 /* global $, APP, config, interfaceConfig, JitsiMeetJS */
1
 /* global $, APP, config, interfaceConfig, JitsiMeetJS */
2
 import UIEvents from "../../service/UI/UIEvents";
2
 import UIEvents from "../../service/UI/UIEvents";
3
+import UIUtil from "./util/UIUtil";
3
 
4
 
4
 /**
5
 /**
5
  * Constructs the html for the overall feedback window.
6
  * Constructs the html for the overall feedback window.

+ 33
- 21
modules/UI/audio_levels/AudioLevels.js View File

10
 let audioLevelCanvasCache = {};
10
 let audioLevelCanvasCache = {};
11
 let dominantSpeakerAudioElement = null;
11
 let dominantSpeakerAudioElement = null;
12
 
12
 
13
-function initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
13
+function _initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
14
     let ASRadius = dominantSpeakerAvatarSize / 2;
14
     let ASRadius = dominantSpeakerAvatarSize / 2;
15
     let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
15
     let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
16
 
16
 
28
 /**
28
 /**
29
  * Resizes the given audio level canvas to match the given thumbnail size.
29
  * Resizes the given audio level canvas to match the given thumbnail size.
30
  */
30
  */
31
-function resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight) {
31
+function _resizeAudioLevelCanvas(   audioLevelCanvas,
32
+                                    thumbnailWidth,
33
+                                    thumbnailHeight) {
32
     audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
34
     audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
33
     audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
35
     audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
34
 }
36
 }
138
         dominantSpeakerAudioElement.height = dominantSpeakerHeight;
140
         dominantSpeakerAudioElement.height = dominantSpeakerHeight;
139
 
141
 
140
         let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
142
         let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
141
-        initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
143
+        _initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
142
     },
144
     },
143
 
145
 
144
     /**
146
     /**
145
      * Updates the audio level canvas for the given id. If the canvas
147
      * Updates the audio level canvas for the given id. If the canvas
146
      * didn't exist we create it.
148
      * didn't exist we create it.
147
      */
149
      */
148
-    updateAudioLevelCanvas (id, thumbWidth, thumbHeight) {
149
-        let videoSpanId = 'localVideoContainer';
150
-        if (id) {
151
-            videoSpanId = `participant_${id}`;
152
-        }
150
+    createAudioLevelCanvas (id, thumbWidth, thumbHeight) {
151
+
152
+        let videoSpanId = (id === "local")
153
+                        ? "localVideoContainer"
154
+                        : `participant_${id}`;
153
 
155
 
154
         let videoSpan = document.getElementById(videoSpanId);
156
         let videoSpan = document.getElementById(videoSpanId);
155
 
157
 
172
                 = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
174
                 = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
173
             audioLevelCanvas.style.left
175
             audioLevelCanvas.style.left
174
                 = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
176
                 = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
175
-            resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
177
+            _resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
176
 
178
 
177
             videoSpan.appendChild(audioLevelCanvas);
179
             videoSpan.appendChild(audioLevelCanvas);
178
         } else {
180
         } else {
179
             audioLevelCanvas = audioLevelCanvas.get(0);
181
             audioLevelCanvas = audioLevelCanvas.get(0);
180
 
182
 
181
-            resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
183
+            _resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
182
         }
184
         }
183
     },
185
     },
184
 
186
 
242
         ASDrawContext.fill();
244
         ASDrawContext.fill();
243
     },
245
     },
244
 
246
 
245
-    updateCanvasSize (thumbWidth, thumbHeight) {
246
-        let canvasWidth = thumbWidth + interfaceConfig.CANVAS_EXTRA;
247
-        let canvasHeight = thumbHeight + interfaceConfig.CANVAS_EXTRA;
248
-
249
-        FilmStrip.getThumbs().children('canvas').each(function () {
250
-            $(this).attr('width', canvasWidth);
251
-            $(this).attr('height', canvasHeight);
247
+    updateCanvasSize (localVideo, remoteVideo) {
248
+        let localCanvasWidth
249
+            = localVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
250
+        let localCanvasHeight
251
+            = localVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
252
+        let remoteCanvasWidth
253
+            = remoteVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
254
+        let remoteCanvasHeight
255
+            = remoteVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
256
+
257
+        let { remoteThumbs, localThumb } = FilmStrip.getThumbs();
258
+
259
+        remoteThumbs.children('canvas').each(function () {
260
+            $(this).attr('width', remoteCanvasWidth);
261
+            $(this).attr('height', remoteCanvasHeight);
252
         });
262
         });
253
 
263
 
254
-        Object.keys(audioLevelCanvasCache).forEach(function (id) {
255
-            audioLevelCanvasCache[id].width = canvasWidth;
256
-            audioLevelCanvasCache[id].height = canvasHeight;
257
-        });
264
+        if(localThumb) {
265
+            localThumb.children('canvas').each(function () {
266
+                $(this).attr('width', localCanvasWidth);
267
+                $(this).attr('height', localCanvasHeight);
268
+            });
269
+        }
258
     }
270
     }
259
 };
271
 };
260
 
272
 

+ 1
- 2
modules/UI/toolbars/Toolbar.js View File

7
 let roomUrl = null;
7
 let roomUrl = null;
8
 let emitter = null;
8
 let emitter = null;
9
 
9
 
10
-
11
 /**
10
 /**
12
  * Opens the invite link dialog.
11
  * Opens the invite link dialog.
13
  */
12
  */
766
     }
765
     }
767
 };
766
 };
768
 
767
 
769
-export default Toolbar;
768
+export default Toolbar;

+ 126
- 30
modules/UI/videolayout/FilmStrip.js View File

3
 import UIEvents from "../../../service/UI/UIEvents";
3
 import UIEvents from "../../../service/UI/UIEvents";
4
 import UIUtil from "../util/UIUtil";
4
 import UIUtil from "../util/UIUtil";
5
 
5
 
6
-const thumbAspectRatio = 1 / 1;
7
-
8
 const FilmStrip = {
6
 const FilmStrip = {
9
     /**
7
     /**
10
      *
8
      *
66
             - parseInt(this.filmStrip.css('paddingRight'), 10);
64
             - parseInt(this.filmStrip.css('paddingRight'), 10);
67
     },
65
     },
68
 
66
 
67
+    calculateThumbnailSize() {
68
+        let availableSizes = this.calculateAvailableSize();
69
+        let width = availableSizes.availableWidth;
70
+        let height = availableSizes.availableHeight;
71
+
72
+        return this.calculateThumbnailSizeFromAvailable(width, height);
73
+    },
74
+
69
     /**
75
     /**
70
-     * Calculates the thumbnail size.
76
+     * Normalizes local and remote thumbnail ratios
71
      */
77
      */
72
-     calculateThumbnailSize () {
73
-        let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
78
+     normalizeThumbnailRatio () {
79
+        let remoteHeightRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_HEIGHT;
80
+        let remoteWidthRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_WIDTH;
81
+
82
+        let localHeightRatio = interfaceConfig.LOCAL_THUMBNAIL_RATIO_HEIGHT;
83
+        let localWidthRatio = interfaceConfig.LOCAL_THUMBNAIL_RATIO_WIDTH;
84
+
85
+        let commonHeightRatio = remoteHeightRatio * localHeightRatio;
74
 
86
 
75
-        let numvids = this.getThumbs(true).length;
87
+        let localRatioCoefficient = localWidthRatio / localHeightRatio;
88
+        let remoteRatioCoefficient = remoteWidthRatio / remoteHeightRatio;
89
+
90
+        remoteWidthRatio = commonHeightRatio * remoteRatioCoefficient;
91
+        remoteHeightRatio = commonHeightRatio;
92
+
93
+        localWidthRatio = commonHeightRatio * localRatioCoefficient;
94
+        localHeightRatio = commonHeightRatio;
95
+
96
+        let localRatio = {
97
+            widthRatio: localWidthRatio,
98
+            heightRatio: localHeightRatio
99
+        };
100
+
101
+        let remoteRatio = {
102
+            widthRatio: remoteWidthRatio,
103
+            heightRatio: remoteHeightRatio
104
+        };
105
+
106
+        return { localRatio, remoteRatio };
107
+    },
108
+
109
+    calculateAvailableSize() {
110
+        let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
111
+        let thumbs = this.getThumbs(true);
112
+        let numvids = thumbs.remoteThumbs.length;
76
 
113
 
77
         let localVideoContainer = $("#localVideoContainer");
114
         let localVideoContainer = $("#localVideoContainer");
78
 
115
 
92
 
129
 
93
         let availableWidth = videoAreaAvailableWidth;
130
         let availableWidth = videoAreaAvailableWidth;
94
 
131
 
95
-        // If the number of videos is 0 or undefined we don't need to calculate
96
-        // further.
97
-        if (numvids)
132
+        // If local thumb is not hidden
133
+        if(thumbs.localThumb) {
98
             availableWidth = Math.floor(
134
             availableWidth = Math.floor(
99
-                (videoAreaAvailableWidth - numvids * (
135
+                (videoAreaAvailableWidth - (
100
                 UIUtil.parseCssInt(
136
                 UIUtil.parseCssInt(
101
                     localVideoContainer.css('borderLeftWidth'), 10)
137
                     localVideoContainer.css('borderLeftWidth'), 10)
102
                 + UIUtil.parseCssInt(
138
                 + UIUtil.parseCssInt(
109
                     localVideoContainer.css('marginLeft'), 10)
145
                     localVideoContainer.css('marginLeft'), 10)
110
                 + UIUtil.parseCssInt(
146
                 + UIUtil.parseCssInt(
111
                     localVideoContainer.css('marginRight'), 10)))
147
                     localVideoContainer.css('marginRight'), 10)))
112
-                / numvids);
148
+            );
149
+        }
150
+
151
+        // If the number of videos is 0 or undefined we don't need to calculate
152
+        // further.
153
+        if (numvids) {
154
+            let remoteVideoContainer = thumbs.remoteThumbs.eq(0);
155
+            availableWidth = Math.floor(
156
+                (videoAreaAvailableWidth - numvids * (
157
+                UIUtil.parseCssInt(
158
+                    remoteVideoContainer.css('borderLeftWidth'), 10)
159
+                + UIUtil.parseCssInt(
160
+                    remoteVideoContainer.css('borderRightWidth'), 10)
161
+                + UIUtil.parseCssInt(
162
+                    remoteVideoContainer.css('paddingLeft'), 10)
163
+                + UIUtil.parseCssInt(
164
+                    remoteVideoContainer.css('paddingRight'), 10)
165
+                + UIUtil.parseCssInt(
166
+                    remoteVideoContainer.css('marginLeft'), 10)
167
+                + UIUtil.parseCssInt(
168
+                    remoteVideoContainer.css('marginRight'), 10)))
169
+            );
170
+        }
113
 
171
 
114
         let maxHeight
172
         let maxHeight
115
             // If the MAX_HEIGHT property hasn't been specified
173
             // If the MAX_HEIGHT property hasn't been specified
116
             // we have the static value.
174
             // we have the static value.
117
-            = Math.min( interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120,
118
-                        availableHeight);
175
+            = Math.min(interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120,
176
+            availableHeight);
119
 
177
 
120
         availableHeight
178
         availableHeight
121
-            = Math.min( maxHeight, window.innerHeight - 18);
179
+            = Math.min(maxHeight, window.innerHeight - 18);
180
+
181
+        return { availableWidth, availableHeight };
182
+    },
183
+
184
+    calculateThumbnailSizeFromAvailable(availableWidth, availableHeight) {
185
+        let { localRatio, remoteRatio } = this.normalizeThumbnailRatio();
186
+        let { remoteThumbs } = this.getThumbs(true);
187
+        let remoteProportion = remoteRatio.widthRatio * remoteThumbs.length;
188
+        let widthProportion = remoteProportion + localRatio.widthRatio;
122
 
189
 
123
-        if (availableHeight < availableWidth) {
124
-            availableWidth = availableHeight;
190
+        let heightUnit = availableHeight / localRatio.heightRatio;
191
+        let widthUnit = availableWidth / widthProportion;
192
+
193
+        if (heightUnit < widthUnit) {
194
+            widthUnit = heightUnit;
125
         }
195
         }
126
         else
196
         else
127
-            availableHeight = availableWidth;
197
+            heightUnit = widthUnit;
198
+
199
+        let localVideo = {
200
+            thumbWidth: widthUnit * localRatio.widthRatio,
201
+            thumbHeight: heightUnit * localRatio.heightRatio
202
+        };
203
+        let remoteVideo = {
204
+            thumbWidth: widthUnit * remoteRatio.widthRatio,
205
+            thumbHeight: widthUnit * remoteRatio.heightRatio
206
+        };
128
 
207
 
129
         return {
208
         return {
130
-            thumbWidth: availableWidth,
131
-            thumbHeight: availableHeight
209
+            localVideo,
210
+            remoteVideo
132
         };
211
         };
133
     },
212
     },
134
 
213
 
135
-    resizeThumbnails (thumbWidth, thumbHeight,
214
+    resizeThumbnails (local, remote,
136
                       animate = false, forceUpdate = false) {
215
                       animate = false, forceUpdate = false) {
137
 
216
 
138
         return new Promise(resolve => {
217
         return new Promise(resolve => {
139
-            this.getThumbs(!forceUpdate).animate({
140
-                height: thumbHeight,
141
-                width: thumbWidth
218
+            let thumbs = this.getThumbs(!forceUpdate);
219
+
220
+            thumbs.localThumb.animate({
221
+                height: local.thumbHeight,
222
+                width: local.thumbWidth
223
+            }, {
224
+                queue: false,
225
+                duration: animate ? 500 : 0,
226
+                complete:  resolve
227
+            });
228
+
229
+            thumbs.remoteThumbs.animate({
230
+                height: remote.thumbHeight,
231
+                width: remote.thumbWidth
142
             }, {
232
             }, {
143
                 queue: false,
233
                 queue: false,
144
                 duration: animate ? 500 : 0,
234
                 duration: animate ? 500 : 0,
147
 
237
 
148
             this.filmStrip.animate({
238
             this.filmStrip.animate({
149
                 // adds 2 px because of small video 1px border
239
                 // adds 2 px because of small video 1px border
150
-                height: thumbHeight + 2
240
+                height: remote.thumbHeight + 2
151
             }, {
241
             }, {
152
                 queue: false,
242
                 queue: false,
153
                 duration: animate ? 500 : 0
243
                 duration: animate ? 500 : 0
165
             selector += ':visible';
255
             selector += ':visible';
166
         }
256
         }
167
 
257
 
258
+        let localThumb = $("#localVideoContainer");
259
+        let remoteThumbs = this.filmStrip.children(selector)
260
+            .not("#localVideoContainer");
261
+
168
         // Exclude the local video container if it has been hidden.
262
         // Exclude the local video container if it has been hidden.
169
-        if ($("#localVideoContainer").hasClass("hidden"))
170
-            return this.filmStrip.children(selector)
171
-                    .not("#localVideoContainer");
172
-        else
173
-            return this.filmStrip.children(selector);
174
-    }
263
+        if (localThumb.hasClass("hidden")) {
264
+            return { remoteThumbs };
265
+        } else {
266
+            return { remoteThumbs, localThumb };
267
+        }
268
+
269
+    },
270
+
175
 };
271
 };
176
 
272
 
177
 export default FilmStrip;
273
 export default FilmStrip;

+ 13
- 15
modules/UI/videolayout/LocalVideo.js View File

11
     this.videoSpanId = "localVideoContainer";
11
     this.videoSpanId = "localVideoContainer";
12
     this.container = $("#localVideoContainer").get(0);
12
     this.container = $("#localVideoContainer").get(0);
13
     this.localVideoId = null;
13
     this.localVideoId = null;
14
-    this.bindHoverHandler();
15
     if(config.enableLocalVideoFlip)
14
     if(config.enableLocalVideoFlip)
16
         this._buildContextMenu();
15
         this._buildContextMenu();
17
     this.isLocal = true;
16
     this.isLocal = true;
44
     editButton.className = 'displayname';
43
     editButton.className = 'displayname';
45
     UIUtil.setTooltip(editButton,
44
     UIUtil.setTooltip(editButton,
46
         "videothumbnail.editnickname",
45
         "videothumbnail.editnickname",
47
-        "top");
46
+        "left");
48
     editButton.innerHTML = '<i class="icon-edit"></i>';
47
     editButton.innerHTML = '<i class="icon-edit"></i>';
49
 
48
 
50
     return editButton;
49
     return editButton;
72
             if (displayName && displayName.length > 0) {
71
             if (displayName && displayName.length > 0) {
73
                 meHTML = APP.translation.generateTranslationHTML("me");
72
                 meHTML = APP.translation.generateTranslationHTML("me");
74
                 $('#localDisplayName').html(
73
                 $('#localDisplayName').html(
75
-                    UIUtil.escapeHtml(displayName) + ' (' + meHTML + ')'
74
+                    `${UIUtil.escapeHtml(displayName)} (${meHTML})`
76
                 );
75
                 );
77
             } else {
76
             } else {
78
                 $('#localDisplayName').html(defaultLocalDisplayName);
77
                 $('#localDisplayName').html(defaultLocalDisplayName);
80
         }
79
         }
81
         this.updateView();
80
         this.updateView();
82
     } else {
81
     } else {
83
-        var editButton = createEditDisplayNameButton();
84
-
85
         nameSpan = document.createElement('span');
82
         nameSpan = document.createElement('span');
86
         nameSpan.className = 'displayname';
83
         nameSpan.className = 'displayname';
87
-        $('#' + this.videoSpanId)[0].appendChild(nameSpan);
84
+        document.getElementById(this.videoSpanId).appendChild(nameSpan);
88
 
85
 
89
 
86
 
90
         if (displayName && displayName.length > 0) {
87
         if (displayName && displayName.length > 0) {
97
 
94
 
98
 
95
 
99
         nameSpan.id = 'localDisplayName';
96
         nameSpan.id = 'localDisplayName';
100
-        this.container.appendChild(editButton);
101
         //translates popover of edit button
97
         //translates popover of edit button
102
         APP.translation.translateElement($("a.displayname"));
98
         APP.translation.translateElement($("a.displayname"));
103
 
99
 
124
         var self = this;
120
         var self = this;
125
         $('#localVideoContainer .displayname')
121
         $('#localVideoContainer .displayname')
126
             .bind("click", function (e) {
122
             .bind("click", function (e) {
123
+                let $editDisplayName = $('#editDisplayName');
124
+                let $localDisplayName = $('#localDisplayName');
127
 
125
 
128
-                var editDisplayName = $('#editDisplayName');
129
                 e.preventDefault();
126
                 e.preventDefault();
130
                 e.stopPropagation();
127
                 e.stopPropagation();
131
-                $('#localDisplayName').hide();
132
-                editDisplayName.show();
133
-                editDisplayName.focus();
134
-                editDisplayName.select();
128
+                $localDisplayName.hide();
129
+                $editDisplayName.show();
130
+                $editDisplayName.focus();
131
+                $editDisplayName.select();
135
 
132
 
136
-                editDisplayName.one("focusout", function (e) {
133
+                $editDisplayName.one("focusout", function (e) {
137
                     self.emitter.emit(UIEvents.NICKNAME_CHANGED, this.value);
134
                     self.emitter.emit(UIEvents.NICKNAME_CHANGED, this.value);
138
-                    $('#editDisplayName').hide();
135
+                    $editDisplayName.hide();
136
+                    $localDisplayName.show();
139
                 });
137
                 });
140
 
138
 
141
-                editDisplayName.on('keydown', function (e) {
139
+                $editDisplayName.on('keydown', function (e) {
142
                     if (e.keyCode === 13) {
140
                     if (e.keyCode === 13) {
143
                         e.preventDefault();
141
                         e.preventDefault();
144
                         $('#editDisplayName').hide();
142
                         $('#editDisplayName').hide();

+ 10
- 5
modules/UI/videolayout/RemoteVideo.js View File

17
     this.addRemoteVideoContainer();
17
     this.addRemoteVideoContainer();
18
     this.connectionIndicator = new ConnectionIndicator(this, id);
18
     this.connectionIndicator = new ConnectionIndicator(this, id);
19
     this.setDisplayName();
19
     this.setDisplayName();
20
-    this.bindHoverHandler();
21
     this.flipX = false;
20
     this.flipX = false;
22
     this.isLocal = false;
21
     this.isLocal = false;
23
     this.isMuted = false;
22
     this.isMuted = false;
34
     if (APP.conference.isModerator) {
33
     if (APP.conference.isModerator) {
35
         this.addRemoteVideoMenu();
34
         this.addRemoteVideoMenu();
36
     }
35
     }
37
-    let {thumbWidth, thumbHeight} = this.VideoLayout.resizeThumbnails();
38
-    AudioLevels.updateAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
36
+
37
+    let { remoteVideo } = this.VideoLayout.resizeThumbnails();
38
+    let { thumbHeight, thumbWidth } = remoteVideo;
39
+    AudioLevels.createAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
39
 
40
 
40
     return this.container;
41
     return this.container;
41
 };
42
 };
427
 };
428
 };
428
 
429
 
429
 RemoteVideo.createContainer = function (spanId) {
430
 RemoteVideo.createContainer = function (spanId) {
430
-    var container = document.createElement('span');
431
+    let container = document.createElement('span');
431
     container.id = spanId;
432
     container.id = spanId;
432
     container.className = 'videocontainer';
433
     container.className = 'videocontainer';
434
+
435
+    let toolbar = document.createElement('div');
436
+    toolbar.className = "videocontainer__toolbar";
437
+    container.appendChild(toolbar);
438
+
433
     var remotes = document.getElementById('remoteVideos');
439
     var remotes = document.getElementById('remoteVideos');
434
     return remotes.appendChild(container);
440
     return remotes.appendChild(container);
435
 };
441
 };
436
 
442
 
437
-
438
 export default RemoteVideo;
443
 export default RemoteVideo;

+ 19
- 31
modules/UI/videolayout/SmallVideo.js View File

171
     return (isVideo ? 'remoteVideo_' : 'remoteAudio_') + stream.getId();
171
     return (isVideo ? 'remoteVideo_' : 'remoteAudio_') + stream.getId();
172
 };
172
 };
173
 
173
 
174
-/**
175
- * Configures hoverIn/hoverOut handlers.
176
- */
177
-SmallVideo.prototype.bindHoverHandler = function () {
178
-    // Add hover handler
179
-    var self = this;
180
-    $(this.container).hover(
181
-        function () {
182
-            self.showDisplayName(true);
183
-        },
184
-        function () {
185
-            // If the video has been "pinned" by the user we want to
186
-            // keep the display name on place.
187
-            if (!self.VideoLayout.isLargeVideoVisible() ||
188
-                !self.VideoLayout.isCurrentlyOnLarge(self.id))
189
-                self.showDisplayName(false);
190
-        }
191
-    );
192
-};
193
-
194
 /**
174
 /**
195
  * Updates the data for the indicator
175
  * Updates the data for the indicator
196
  * @param id the id of the indicator
176
  * @param id the id of the indicator
219
         if (audioMutedSpan.length > 0) {
199
         if (audioMutedSpan.length > 0) {
220
             audioMutedSpan.popover('hide');
200
             audioMutedSpan.popover('hide');
221
             audioMutedSpan.remove();
201
             audioMutedSpan.remove();
202
+            this.updateIconPositions();
222
         }
203
         }
223
     }
204
     }
224
     else {
205
     else {
230
                 "top");
211
                 "top");
231
 
212
 
232
             this.container.appendChild(audioMutedSpan);
213
             this.container.appendChild(audioMutedSpan);
233
-            APP.translation.translateElement($('#' + this.videoSpanId + " > span"));
214
+            APP.translation
215
+                .translateElement($('#' + this.videoSpanId + " > span"));
234
             var mutedIndicator = document.createElement('i');
216
             var mutedIndicator = document.createElement('i');
235
             mutedIndicator.className = 'icon-mic-disabled';
217
             mutedIndicator.className = 'icon-mic-disabled';
236
             audioMutedSpan.appendChild(mutedIndicator);
218
             audioMutedSpan.appendChild(mutedIndicator);
237
 
219
 
238
         }
220
         }
221
+
239
         this.updateIconPositions();
222
         this.updateIconPositions();
240
     }
223
     }
241
     this.isMuted = isMuted;
224
     this.isMuted = isMuted;
254
     if (isMuted === false) {
237
     if (isMuted === false) {
255
         if (videoMutedSpan.length > 0) {
238
         if (videoMutedSpan.length > 0) {
256
             videoMutedSpan.remove();
239
             videoMutedSpan.remove();
240
+            this.updateIconPositions();
257
         }
241
         }
258
     }
242
     }
259
     else {
243
     else {
270
                 "top");
254
                 "top");
271
             videoMutedSpan.appendChild(mutedIndicator);
255
             videoMutedSpan.appendChild(mutedIndicator);
272
             //translate texts for muted indicator
256
             //translate texts for muted indicator
273
-            APP.translation.translateElement($('#' + this.videoSpanId  + " > span > i"));
257
+            APP.translation
258
+                .translateElement($('#' + this.videoSpanId  + " > span > i"));
274
         }
259
         }
275
 
260
 
276
         this.updateIconPositions();
261
         this.updateIconPositions();
278
 };
263
 };
279
 
264
 
280
 SmallVideo.prototype.updateIconPositions = function () {
265
 SmallVideo.prototype.updateIconPositions = function () {
281
-    var audioMutedSpan = $('#' + this.videoSpanId + '>span.audioMuted');
282
-    var connectionIndicator = $('#' + this.videoSpanId + '>div.connectionindicator');
283
-    var videoMutedSpan = $('#' + this.videoSpanId + '>span.videoMuted');
266
+    let audioMutedSpan = $('#' + this.videoSpanId + '>span.audioMuted');
267
+    let videoMutedSpan = $('#' + this.videoSpanId + '>span.videoMuted');
268
+    audioMutedSpan.css({left: "0px"});
269
+    videoMutedSpan.css({left: (audioMutedSpan.length > 0? 25 : 0) + "px"});
270
+
271
+    var connectionIndicator
272
+        = $('#' + this.videoSpanId + '>div.connectionindicator');
284
     if(connectionIndicator.length > 0 &&
273
     if(connectionIndicator.length > 0 &&
285
         connectionIndicator[0].style.display != "none") {
274
         connectionIndicator[0].style.display != "none") {
286
         audioMutedSpan.css({right: "23px"});
275
         audioMutedSpan.css({right: "23px"});
287
-        videoMutedSpan.css({right: ((audioMutedSpan.length > 0? 23 : 0) + 30) + "px"});
276
+        videoMutedSpan.css({right:
277
+            ((audioMutedSpan.length > 0? 23 : 0) + 30) + "px"});
288
     } else {
278
     } else {
289
         audioMutedSpan.css({right: "0px"});
279
         audioMutedSpan.css({right: "0px"});
290
         videoMutedSpan.css({right: (audioMutedSpan.length > 0? 30 : 0) + "px"});
280
         videoMutedSpan.css({right: (audioMutedSpan.length > 0? 30 : 0) + "px"});
317
         "top");
307
         "top");
318
 
308
 
319
     //translates text in focus indicators
309
     //translates text in focus indicators
320
-    APP.translation.translateElement($('#' + this.videoSpanId + ' .focusindicator'));
310
+    APP.translation
311
+        .translateElement($('#' + this.videoSpanId + ' .focusindicator'));
321
 };
312
 };
322
 
313
 
323
 /**
314
 /**
406
         setVisibility(video, showVideo);
397
         setVisibility(video, showVideo);
407
     }
398
     }
408
     setVisibility(avatar, showAvatar);
399
     setVisibility(avatar, showAvatar);
409
-
410
-    this.showDisplayName(!showVideo && !showAvatar);
411
 };
400
 };
412
 
401
 
413
 SmallVideo.prototype.avatarChanged = function (avatarUrl) {
402
 SmallVideo.prototype.avatarChanged = function (avatarUrl) {
465
     var indicatorSpanId = "raisehandindicator";
454
     var indicatorSpanId = "raisehandindicator";
466
     var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
455
     var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
467
 
456
 
468
-    indicatorSpan.style.background = "#D6D61E";
469
     indicatorSpan.innerHTML
457
     indicatorSpan.innerHTML
470
-        = "<i id='indicatoricon' class='fa fa-hand-paper-o'></i>";
458
+        = "<i id='indicatoricon' class='icon-raised-hand'></i>";
471
 
459
 
472
     // adds a tooltip
460
     // adds a tooltip
473
     UIUtil.setTooltip(indicatorSpan, "raisedHand", "left");
461
     UIUtil.setTooltip(indicatorSpan, "raisedHand", "left");

+ 14
- 12
modules/UI/videolayout/VideoLayout.js View File

105
         localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
105
         localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
106
         // if we do not resize the thumbs here, if there is no video device
106
         // if we do not resize the thumbs here, if there is no video device
107
         // the local video thumb maybe one pixel
107
         // the local video thumb maybe one pixel
108
-        let {thumbWidth, thumbHeight} = this.resizeThumbnails(false, true);
109
-        AudioLevels.updateAudioLevelCanvas(null, thumbWidth, thumbHeight);
108
+        let { localVideo } = this.resizeThumbnails(false, true);
109
+        AudioLevels.createAudioLevelCanvas(
110
+            "local", localVideo.thumbWidth, localVideo.thumbHeight);
110
 
111
 
111
         emitter.addListener(UIEvents.CONTACT_CLICKED, onContactClicked);
112
         emitter.addListener(UIEvents.CONTACT_CLICKED, onContactClicked);
112
         this.lastNCount = config.channelLastN;
113
         this.lastNCount = config.channelLastN;
254
     electLastVisibleVideo () {
255
     electLastVisibleVideo () {
255
         // pick the last visible video in the row
256
         // pick the last visible video in the row
256
         // if nobody else is left, this picks the local video
257
         // if nobody else is left, this picks the local video
257
-        let thumbs = FilmStrip.getThumbs(true).filter('[id!="mixedstream"]');
258
+        let remoteThumbs = FilmStrip.getThumbs(true).remoteThumbs;
259
+        let thumbs = remoteThumbs.filter('[id!="mixedstream"]');
258
 
260
 
259
         let lastVisible = thumbs.filter(':visible:last');
261
         let lastVisible = thumbs.filter(':visible:last');
260
         if (lastVisible.length) {
262
         if (lastVisible.length) {
268
         }
270
         }
269
 
271
 
270
         console.info("Last visible video no longer exists");
272
         console.info("Last visible video no longer exists");
271
-        thumbs = FilmStrip.getThumbs();
273
+        thumbs = FilmStrip.getThumbs().remoteThumbs;
272
         if (thumbs.length) {
274
         if (thumbs.length) {
273
             let id = getPeerContainerResourceId(thumbs[0]);
275
             let id = getPeerContainerResourceId(thumbs[0]);
274
             if (remoteVideos[id]) {
276
             if (remoteVideos[id]) {
401
 
403
 
402
         // In case this is not currently in the last n we don't show it.
404
         // In case this is not currently in the last n we don't show it.
403
         if (localLastNCount && localLastNCount > 0 &&
405
         if (localLastNCount && localLastNCount > 0 &&
404
-            FilmStrip.getThumbs().length >= localLastNCount + 2) {
406
+            FilmStrip.getThumbs().remoteThumbs.length >= localLastNCount + 2) {
405
             remoteVideo.showPeerContainer('hide');
407
             remoteVideo.showPeerContainer('hide');
406
         } else {
408
         } else {
407
             VideoLayout.resizeThumbnails(false, true);
409
             VideoLayout.resizeThumbnails(false, true);
486
                         forceUpdate = false,
488
                         forceUpdate = false,
487
                         onComplete = null) {
489
                         onComplete = null) {
488
 
490
 
489
-        let {thumbWidth, thumbHeight}
491
+        let { localVideo, remoteVideo }
490
             = FilmStrip.calculateThumbnailSize();
492
             = FilmStrip.calculateThumbnailSize();
491
 
493
 
492
-        $('.userAvatar').css('left', (thumbWidth - thumbHeight) / 2);
494
+        let {thumbWidth, thumbHeight} = remoteVideo;
493
 
495
 
494
-        FilmStrip.resizeThumbnails(thumbWidth, thumbHeight,
496
+        FilmStrip.resizeThumbnails(localVideo, remoteVideo,
495
             animate, forceUpdate)
497
             animate, forceUpdate)
496
             .then(function () {
498
             .then(function () {
497
-                AudioLevels.updateCanvasSize(thumbWidth, thumbHeight);
499
+                AudioLevels.updateCanvasSize(localVideo, remoteVideo);
498
                 if (onComplete && typeof onComplete === "function")
500
                 if (onComplete && typeof onComplete === "function")
499
                     onComplete();
501
                     onComplete();
500
-        });
501
-        return {thumbWidth, thumbHeight};
502
+            });
503
+        return { localVideo, remoteVideo };
502
     },
504
     },
503
 
505
 
504
     /**
506
     /**
656
         var updateLargeVideo = false;
658
         var updateLargeVideo = false;
657
 
659
 
658
         // Handle LastN/local LastN changes.
660
         // Handle LastN/local LastN changes.
659
-        FilmStrip.getThumbs().each(( index, element ) => {
661
+        FilmStrip.getThumbs().remoteThumbs.each(( index, element ) => {
660
             var resourceJid = getPeerContainerResourceId(element);
662
             var resourceJid = getPeerContainerResourceId(element);
661
             var smallVideo = remoteVideos[resourceJid];
663
             var smallVideo = remoteVideos[resourceJid];
662
 
664
 

+ 5
- 5
package.json View File

21
     "bootstrap": "3.1.1",
21
     "bootstrap": "3.1.1",
22
     "events": "*",
22
     "events": "*",
23
     "i18next-client": "1.7.7",
23
     "i18next-client": "1.7.7",
24
-    "jquery": "~2.1.1",
25
     "jQuery-Impromptu": "git+https://github.com/trentrichardson/jQuery-Impromptu.git#v6.0.0",
24
     "jQuery-Impromptu": "git+https://github.com/trentrichardson/jQuery-Impromptu.git#v6.0.0",
26
-    "lib-jitsi-meet": "git+https://github.com/jitsi/lib-jitsi-meet.git",
25
+    "jquery": "~2.1.1",
27
     "jquery-contextmenu": "*",
26
     "jquery-contextmenu": "*",
28
     "jquery-ui": "1.10.5",
27
     "jquery-ui": "1.10.5",
29
     "jssha": "1.5.0",
28
     "jssha": "1.5.0",
29
+    "jws": "*",
30
+    "lib-jitsi-meet": "git+https://github.com/jitsi/lib-jitsi-meet.git",
31
+    "postis": "^2.2.0",
30
     "retry": "0.6.1",
32
     "retry": "0.6.1",
31
     "strophe": "^1.2.2",
33
     "strophe": "^1.2.2",
32
     "strophejs-plugins": "^0.0.6",
34
     "strophejs-plugins": "^0.0.6",
33
-    "toastr": "^2.0.3",
34
-    "postis": "^2.2.0",
35
-    "jws": "*"
35
+    "toastr": "^2.0.3"
36
   },
36
   },
37
   "devDependencies": {
37
   "devDependencies": {
38
     "babel-polyfill": "*",
38
     "babel-polyfill": "*",

Loading…
Cancel
Save