Bläddra i källkod

Ongoing work on video thumbnail layout

j8
yanas 8 år sedan
förälder
incheckning
a17a98991c

+ 0
- 4
conference.js Visa fil

@@ -1279,10 +1279,6 @@ export default {
1279 1279
             APP.UI.updateRecordingState(status);
1280 1280
         });
1281 1281
 
1282
-        room.on(ConferenceEvents.USER_STATUS_CHANGED, function (id, status) {
1283
-            APP.UI.updateUserStatus(id, status);
1284
-        });
1285
-
1286 1282
         room.on(ConferenceEvents.KICKED, () => {
1287 1283
             APP.UI.hideStats();
1288 1284
             APP.UI.notifyKicked();

+ 3
- 2
css/_variables.scss Visa fil

@@ -11,10 +11,10 @@ $hangupFontSize: 2em;
11 11
 $defaultToolbarSize: 50px;
12 12
 
13 13
 // Video layout.
14
-$thumbnailIndicatorSize: 23px;
14
+$thumbnailToolbarHeight: 22px;
15 15
 $thumbnailIndicatorBorder: 0px;
16
+$thumbnailIndicatorSize: $thumbnailToolbarHeight;
16 17
 $thumbnailVideoMargin: 2px;
17
-$thumbnailToolbarHeight: 25px;
18 18
 
19 19
 /**
20 20
  * Color variables.
@@ -46,6 +46,7 @@ $thumbnailPictogramColor: #fff;
46 46
 $dominantSpeakerBg: #165ecc;
47 47
 $raiseHandBg: #D6D61E;
48 48
 $audioLevelBg: #44A5FF;
49
+$connectionIndicatorBg: #48CC8C;
49 50
 $audioLevelShadow: rgba(9, 36, 77, 0.9);
50 51
 $videoStateIndicatorColor: $defaultColor;
51 52
 $videoStateIndicatorBackground: $toolbarBackground;

+ 77
- 83
css/_videolayout_default.scss Visa fil

@@ -58,18 +58,25 @@
58 58
 /**
59 59
  * The toolbar of the video thumbnail.
60 60
  */
61
-.videocontainer__toolbar {
61
+.videocontainer__toolbar,
62
+.videocontainer__toptoolbar {
62 63
     position: absolute;
63
-    bottom: 0;
64 64
     left: 0;
65 65
     z-index: 1;
66 66
     width: 100%;
67 67
     box-sizing: border-box; // Includes the padding in the 100% width.
68 68
     height: $thumbnailToolbarHeight;
69
-    max-height: 100%;
70 69
     padding: 0 5px 0 5px;
71 70
 }
72 71
 
72
+.videocontainer__toolbar {
73
+    bottom: 0;
74
+}
75
+
76
+.videocontainer__toptoolbar {
77
+    top: 0;
78
+}
79
+
73 80
 #remoteVideos .videocontainer.videoContainerFocused,
74 81
 #remoteVideos .videocontainer:hover {
75 82
     cursor: hand;
@@ -201,72 +208,10 @@
201 208
     padding: 0;
202 209
 }
203 210
 
204
-.videocontainer>span.status {
205
-    display: inline-block;
206
-    position: absolute;
207
-    color: #FFFFFF;
208
-    background: rgba(0,0,0,.7);
209
-    text-align: center;
210
-    text-overflow: ellipsis;
211
-    width: 70%;
212
-    height: 15%;
213
-    left: 15%;
214
-    bottom: 2%;
215
-    padding: 5px;
216
-    font-size: 10pt;
217
-    overflow: hidden;
218
-    white-space: nowrap;
219
-    z-index: 2;
220
-    border-radius:3px;
221
-}
222
-
223
-.connectionindicator
224
-{
225
-    display: inline-block;
226
-    position: absolute;
227
-    top: 7px;
228
-    right: 0;
229
-    padding: 0px 5px;
230
-    z-index: 3;
231
-    width: 18px;
232
-    height: 13px;
233
-}
234
-
235
-.connection.connection_empty
236
-{
237
-    color: #8B8B8B;/*#FFFFFF*/
238
-    overflow: hidden;
239
-}
240
-
241
-.connection.connection_lost
242
-{
243
-    color: #8B8B8B;
244
-    overflow: visible;
245
-}
246
-
247
-.connection.connection_full
248
-{
249
-    color: #FFFFFF;/*#15A1ED*/
250
-    overflow: hidden;
251
-}
252
-
253
-.connection
254
-{
255
-    position: absolute;
256
-    left: 0px;
257
-    top: 0px;
258
-    font-size: 8pt;
259
-    border: 0px;
260
-    width: 18px;
261
-    height: 13px;
262
-}
263
-
264
-#localVideoContainer>span.status:hover,
265 211
 #localVideoContainer .displayname:hover {
266 212
     cursor: text;
267 213
 }
268 214
 
269
-.videocontainer>span.status,
270 215
 .videocontainer .displayname {
271 216
     pointer-events: none;
272 217
 }
@@ -279,7 +224,6 @@
279 224
     pointer-events: auto !important;
280 225
 }
281 226
 
282
-.videocontainer>a.status,
283 227
 .videocontainer>a.displayname {
284 228
     display: inline-block;
285 229
     position: absolute;
@@ -324,25 +268,81 @@
324 268
   margin: 0px 0px 0px 5px;
325 269
 }
326 270
 
327
-.videocontainer>span.indicator {
328
-    position: absolute;
329
-    top: 0px;
330
-    left: 0px;
271
+#raisehandindicator {
272
+  background: $raiseHandBg;
273
+}
274
+
275
+#connectionindicator {
276
+  background: $connectionIndicatorBg;
277
+}
278
+
279
+.videocontainer__toptoolbar span.indicator {
280
+    font-size: 8pt;
281
+    text-align: center;
282
+    line-height: $thumbnailToolbarHeight;
283
+    padding: 0;
284
+    margin-right: 5px;
285
+    float: left;
331 286
     @include circle($thumbnailIndicatorSize);
332 287
     box-sizing: border-box;
333
-    line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
334 288
     z-index: 3;
335
-    text-align: center;
336 289
     background: $dominantSpeakerBg;
337
-    margin: 7px;
338
-    display: inline-block;
339 290
     color: $thumbnailPictogramColor;
340
-    font-size: 8pt;
341 291
     border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor;
292
+
293
+    .indicatoricon {
294
+        width: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
295
+        height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
296
+        line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
297
+        margin-left: 5px; // TOP toolbar padding;
298
+    }
299
+
300
+    .connection.connection_empty
301
+    {
302
+        color: #8B8B8B;/*#FFFFFF*/
303
+        overflow: hidden;
304
+    }
305
+
306
+    .connection.connection_lost
307
+    {
308
+        color: #8B8B8B;
309
+        overflow: visible;
310
+    }
311
+
312
+    .connection.connection_full
313
+    {
314
+        color: #FFFFFF;/*#15A1ED*/
315
+        overflow: hidden;
316
+    }
317
+
318
+    .connection,
319
+    .icon-connection,
320
+    .icon-connection-lost {
321
+        font-size: 6pt;
322
+        line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
323
+    }
324
+
325
+    .connection
326
+    {
327
+        position: absolute;
328
+        left: 0px;
329
+        top: 0px;
330
+        border: 0px;
331
+    }
342 332
 }
343 333
 
344
-.videocontainer>#raisehandindicator {
345
-    background: $raiseHandBg;
334
+.remotevideomenu
335
+{
336
+    display: inline-block;
337
+    position: absolute;
338
+    top: 0px;
339
+    right: 0;
340
+    margin: 7px;
341
+    z-index: 3;
342
+    width: 18px;
343
+    height: 13px;
344
+    color: #FFF;
345
+    font-size: 8pt;
346 346
 }
347 347
 
348 348
 /**
@@ -385,12 +385,6 @@
385 385
     }
386 386
 }
387 387
 
388
-#indicatoricon {
389
-    width: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
390
-    height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
391
-    line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
392
-}
393
-
394 388
 #reloadPresentation {
395 389
     display: none;
396 390
     position: absolute;

+ 1
- 0
index.html Visa fil

@@ -254,6 +254,7 @@
254 254
                     </span>
255 255
                     <audio id="localAudio" autoplay muted></audio>
256 256
                     <div class="videocontainer__toolbar"></div>
257
+                    <div class="videocontainer__toptoolbar"></div>
257 258
                 </span>
258 259
                 <audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
259 260
                 <audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>

+ 0
- 4
modules/UI/UI.js Visa fil

@@ -609,10 +609,6 @@ UI.removeUser = function (id, displayName) {
609 609
     VideoLayout.removeParticipantContainer(id);
610 610
 };
611 611
 
612
-UI.updateUserStatus = function (id, status) {
613
-    VideoLayout.setPresenceStatus(id, status);
614
-};
615
-
616 612
 /**
617 613
  * Update videotype for specified user.
618 614
  * @param {string} id user id

+ 40
- 1
modules/UI/util/UIUtil.js Visa fil

@@ -136,7 +136,7 @@ const TOOLTIP_POSITIONS = {
136 136
             element.setAttribute('data-i18n', '[content]' + key);
137 137
 
138 138
             APP.translation.translateElement($(element));
139
-        }      
139
+        }
140 140
     },
141 141
 
142 142
     /**
@@ -388,6 +388,45 @@ const TOOLTIP_POSITIONS = {
388 388
                 "cursor": "default"
389 389
             });
390 390
         }
391
+    },
392
+
393
+    /**
394
+     * Gets an "indicator" span for a video thumbnail.
395
+     * If element doesn't exist then creates it and appends
396
+     * video span container.
397
+     *
398
+     * @param {object} opts
399
+     * @param opts.indicatorId {String} - identificator of indicator
400
+     * @param opts.videoSpanId {String} - identificator of video span
401
+     * @param opts.content {String} HTML content of indicator
402
+     * @param opts.tooltip {String} - tooltip key for translation
403
+     *
404
+     * @returns {HTMLSpanElement} indicatorSpan
405
+     */
406
+    getVideoThumbnailIndicatorSpan(opts = {}) {
407
+        let indicatorId = opts.indicatorId;
408
+        let videoSpanId = opts.videoSpanId;
409
+        let indicators = $(`#${videoSpanId} #${indicatorId}]`);
410
+        let indicatorSpan;
411
+
412
+        if (indicators.length <= 0) {
413
+            indicatorSpan = document.createElement('span');
414
+            indicatorSpan.className = 'indicator';
415
+            indicatorSpan.id = indicatorId;
416
+
417
+            indicatorSpan.innerHTML = opts.content;
418
+
419
+            this.setTooltip(indicatorSpan, opts.tooltip, "top");
420
+            APP.translation.translateElement($(indicatorSpan));
421
+
422
+            document.getElementById(videoSpanId)
423
+                .querySelector('.videocontainer__toptoolbar')
424
+                .appendChild(indicatorSpan);
425
+        } else {
426
+            indicatorSpan = indicators[0];
427
+        }
428
+
429
+        return indicatorSpan;
391 430
     }
392 431
 };
393 432
 

+ 21
- 14
modules/UI/videolayout/ConnectionIndicator.js Visa fil

@@ -2,13 +2,15 @@
2 2
 /* jshint -W101 */
3 3
 import JitsiPopover from "../util/JitsiPopover";
4 4
 import VideoLayout from "./VideoLayout";
5
+import UIUtil from "../util/UIUtil";
5 6
 
6 7
 /**
7 8
  * Constructs new connection indicator.
8 9
  * @param videoContainer the video container associated with the indicator.
10
+ * @param videoId the identifier of the video
9 11
  * @constructor
10 12
  */
11
-function ConnectionIndicator(videoContainer, id) {
13
+function ConnectionIndicator(videoContainer, videoId) {
12 14
     this.videoContainer = videoContainer;
13 15
     this.bandwidth = null;
14 16
     this.packetLoss = null;
@@ -18,7 +20,7 @@ function ConnectionIndicator(videoContainer, id) {
18 20
     this.isResolutionHD = null;
19 21
     this.transport = [];
20 22
     this.popover = null;
21
-    this.id = id;
23
+    this.id = videoId;
22 24
     this.create();
23 25
 }
24 26
 
@@ -247,6 +249,7 @@ ConnectionIndicator.prototype.showMore = function () {
247 249
 
248 250
 function createIcon(classes, iconClass) {
249 251
     var icon = document.createElement("span");
252
+    icon.classList.add("indicatoricon");
250 253
     for(var i in classes) {
251 254
         icon.classList.add(classes[i]);
252 255
     }
@@ -259,18 +262,22 @@ function createIcon(classes, iconClass) {
259 262
  * Creates the indicator
260 263
  */
261 264
 ConnectionIndicator.prototype.create = function () {
262
-    this.connectionIndicatorContainer = document.createElement("div");
263
-    this.connectionIndicatorContainer.className = "connectionindicator";
264
-    this.connectionIndicatorContainer.style.display = "none";
265
-    this.videoContainer.container.appendChild(
266
-        this.connectionIndicatorContainer);
267
-    this.popover = new JitsiPopover(
268
-        $("#" + this.videoContainer.videoSpanId + " > .connectionindicator"), {
269
-            content: "<div class=\"connection-info\" " +
270
-                        "data-i18n='connectionindicator.na'></div>",
271
-            skin: "black",
272
-            onBeforePosition: el => APP.translation.translateElement(el)
273
-        });
265
+    let indicatorId = 'connectionindicator';
266
+    let element = UIUtil.getVideoThumbnailIndicatorSpan({
267
+        videoSpanId: this.videoContainer.videoSpanId,
268
+        indicatorId
269
+    });
270
+    element.classList.add('hide');
271
+    this.connectionIndicatorContainer = element;
272
+
273
+    let popoverContent = (
274
+        `<div class="connection-info" data-i18n="${indicatorId}.na"></div>`
275
+    );
276
+    this.popover = new JitsiPopover(element, {
277
+        content: popoverContent,
278
+        skin: "black",
279
+        onBeforePosition: el => APP.translation.translateElement(el)
280
+    });
274 281
 
275 282
     // override popover show method to make sure we will update the content
276 283
     // before showing the popover

+ 6
- 4
modules/UI/videolayout/RemoteVideo.js Visa fil

@@ -233,11 +233,9 @@ if (!interfaceConfig.filmStripOnly) {
233 233
     RemoteVideo.prototype.addRemoteVideoMenu = function () {
234 234
 
235 235
         var spanElement = document.createElement('span');
236
-        spanElement.className = 'remotevideomenu toolbar-icon right';
236
+        spanElement.className = 'remotevideomenu';
237 237
 
238
-        this.container
239
-            .querySelector('.videocontainer__toolbar')
240
-            .appendChild(spanElement);
238
+        this.container.appendChild(spanElement);
241 239
 
242 240
         var menuElement = document.createElement('i');
243 241
         menuElement.className = 'icon-menu-up';
@@ -569,6 +567,10 @@ RemoteVideo.createContainer = function (spanId) {
569 567
     container.id = spanId;
570 568
     container.className = 'videocontainer';
571 569
 
570
+    let indicatorBar = document.createElement('div');
571
+    indicatorBar.className = "videocontainer__toptoolbar";
572
+    container.appendChild(indicatorBar);
573
+
572 574
     let toolbar = document.createElement('div');
573 575
     toolbar.className = "videocontainer__toolbar";
574 576
     container.appendChild(toolbar);

+ 17
- 66
modules/UI/videolayout/SmallVideo.js Visa fil

@@ -126,37 +126,6 @@ SmallVideo.prototype.getVideoType = function () {
126 126
     return this.videoType;
127 127
 };
128 128
 
129
-/**
130
- * Shows the presence status message for the given video.
131
- */
132
-SmallVideo.prototype.setPresenceStatus = function (statusMsg) {
133
-    if (!this.container) {
134
-        // No container
135
-        return;
136
-    }
137
-
138
-    var statusSpan = $('#' + this.videoSpanId + '>span.status');
139
-    if (!statusSpan.length) {
140
-        //Add status span
141
-        statusSpan = document.createElement('span');
142
-        statusSpan.className = 'status';
143
-        statusSpan.id = this.videoSpanId + '_status';
144
-        $('#' + this.videoSpanId)[0].appendChild(statusSpan);
145
-
146
-        statusSpan = $('#' + this.videoSpanId + '>span.status');
147
-    }
148
-
149
-    // Display status
150
-    if (statusMsg && statusMsg.length) {
151
-        $('#' + this.videoSpanId + '_status').text(statusMsg);
152
-        statusSpan.get(0).setAttribute("style", "display:inline-block;");
153
-    }
154
-    else {
155
-        // Hide
156
-        statusSpan.get(0).setAttribute("style", "display:none;");
157
-    }
158
-};
159
-
160 129
 /**
161 130
  * Creates an audio or video element for a particular MediaStream.
162 131
  */
@@ -528,13 +497,19 @@ SmallVideo.prototype.showDominantSpeakerIndicator = function (show) {
528 497
         return;
529 498
     }
530 499
 
531
-    var indicatorSpan = this.getIndicatorSpan({
532
-        id: 'dominantspeakerindicator',
500
+    let indicatorSpanId = "dominantspeakerindicator";
501
+    let indicatorSpan = UIUtil.getVideoThumbnailIndicatorSpan({
502
+        videoSpanId: this.videoSpanId,
503
+        indicatorId: indicatorSpanId,
533 504
         content: '<i id="indicatoricon" class="fa fa-bullhorn"></i>',
534 505
         tooltip: 'speaker'
535 506
     });
536 507
 
537
-    indicatorSpan.style.display = show ? "" : "none";
508
+    if (show) {
509
+        indicatorSpan.classList.add('hide');
510
+    } else {
511
+        indicatorSpan.classList.remove('hide')
512
+    }
538 513
 };
539 514
 
540 515
 /**
@@ -548,43 +523,19 @@ SmallVideo.prototype.showRaisedHandIndicator = function (show) {
548 523
         return;
549 524
     }
550 525
 
551
-    var indicatorSpan = this.getIndicatorSpan({
552
-        id: 'raisehandindicator',
526
+    let indicatorSpanId = "raisehandindicator";
527
+    let indicatorSpan = UIUtil.getVideoThumbnailIndicatorSpan({
528
+        indicatorId: indicatorSpanId,
529
+        videoSpanId: this.videoSpanId,
553 530
         content: '<i id="indicatoricon" class="icon-raised-hand"></i>',
554 531
         tooltip: 'raisedHand'
555 532
     });
556 533
 
557
-    indicatorSpan.style.display = show ? "" : "none";
558
-};
559
-
560
-/**
561
- * Gets (creating if necessary) the "indicator" span for this SmallVideo.
562
- *
563
- * @param options.id {String} element ID
564
- * @param options.content {String} HTML content of the indicator
565
- * @param options.tooltip {String} The key that should be passed to tooltip
566
- *
567
- * @returns {HTMLElement} DOM represention of the indicator
568
- */
569
-SmallVideo.prototype.getIndicatorSpan = function(options) {
570
-    var indicator = this.container.querySelector('#' + options.id);
571
-
572
-    if (indicator) {
573
-        return indicator;
534
+    if (show) {
535
+        indicatorSpan.classList.add('hide');
536
+    } else {
537
+        indicatorSpan.classList.remove('hide')
574 538
     }
575
-
576
-    indicator = document.createElement('span');
577
-    indicator.className = 'indicator';
578
-    indicator.id = options.id;
579
-
580
-    indicator.innerHTML = options.content;
581
-
582
-    UIUtil.setTooltip(indicator, options.tooltip, "top");
583
-    APP.translation.translateElement($(indicator));
584
-
585
-    this.container.appendChild(indicator);
586
-
587
-    return indicator;
588 539
 };
589 540
 
590 541
 /**

+ 0
- 9
modules/UI/videolayout/VideoLayout.js Visa fil

@@ -449,15 +449,6 @@ var VideoLayout = {
449 449
         }
450 450
     },
451 451
 
452
-    /**
453
-     * Shows the presence status message for the given video.
454
-     */
455
-    setPresenceStatus (id, statusMsg) {
456
-        let remoteVideo = remoteVideos[id];
457
-        if (remoteVideo)
458
-            remoteVideo.setPresenceStatus(statusMsg);
459
-    },
460
-
461 452
     /**
462 453
      * Shows a visual indicator for the moderator of the conference.
463 454
      * On local or remote participants.

Laddar…
Avbryt
Spara