Explorar el Código

feat(small-video): convert the "toolbar" to react

Move display of audio muted, video muted, and moderator icons,
which make up the elements of the small video toolbar, into React
Components.
master
Leonard Kim hace 8 años
padre
commit
152427e01b

+ 1
- 0
css/_vertical_filmstrip_overrides.scss Ver fichero

@@ -82,6 +82,7 @@
82 82
 
83 83
                 .toolbar-icon {
84 84
                     float: none;
85
+                    margin: auto;
85 86
                 }
86 87
             }
87 88
         }

+ 8
- 0
modules/UI/videolayout/RemoteVideo.js Ver fichero

@@ -2,6 +2,7 @@
2 2
 
3 3
 /* eslint-disable no-unused-vars */
4 4
 import React from 'react';
5
+import ReactDOM from 'react-dom';
5 6
 
6 7
 import {
7 8
     MuteButton,
@@ -515,6 +516,13 @@ RemoteVideo.prototype.remove = function () {
515 516
 
516 517
     this.removeAudioLevelIndicator();
517 518
 
519
+    const toolbarContainer
520
+        = this.container.querySelector('.videocontainer__toolbar');
521
+
522
+    if (toolbarContainer) {
523
+        ReactDOM.unmountComponentAtNode(toolbarContainer);
524
+    }
525
+
518 526
     this.removeConnectionIndicator();
519 527
 
520 528
     this.removeDisplayName();

+ 30
- 95
modules/UI/videolayout/SmallVideo.js Ver fichero

@@ -16,7 +16,12 @@ import {
16 16
     ConnectionIndicator
17 17
 } from '../../../react/features/connection-indicator';
18 18
 import { DisplayName } from '../../../react/features/display-name';
19
-/* eslint-disable no-unused-vars */
19
+import {
20
+    AudioMutedIndicator,
21
+    ModeratorIndicator,
22
+    VideoMutedIndicator
23
+} from '../../../react/features/filmstrip';
24
+/* eslint-enable no-unused-vars */
20 25
 
21 26
 const logger = require("jitsi-meet-logger").getLogger(__filename);
22 27
 
@@ -64,6 +69,7 @@ const DISPLAY_VIDEO_WITH_NAME = 3;
64 69
 const DISPLAY_AVATAR_WITH_NAME = 4;
65 70
 
66 71
 function SmallVideo(VideoLayout) {
72
+    this._isModerator = false;
67 73
     this.isAudioMuted = false;
68 74
     this.hasAvatar = false;
69 75
     this.isVideoMuted = false;
@@ -270,43 +276,8 @@ SmallVideo.prototype.updateConnectionStatus = function (connectionStatus) {
270 276
  * or hidden
271 277
  */
272 278
 SmallVideo.prototype.showAudioIndicator = function (isMuted) {
273
-    let mutedIndicator = this.getAudioMutedIndicator();
274
-
275
-    UIUtil.setVisible(mutedIndicator, isMuted);
276
-
277 279
     this.isAudioMuted = isMuted;
278
-};
279
-
280
-/**
281
- * Returns the audio muted indicator jquery object. If it doesn't exists -
282
- * creates it.
283
- *
284
- * @returns {HTMLElement} the audio muted indicator
285
- */
286
-SmallVideo.prototype.getAudioMutedIndicator = function () {
287
-    let selector = '#' + this.videoSpanId + ' .audioMuted';
288
-    let audioMutedSpan = document.querySelector(selector);
289
-
290
-    if (audioMutedSpan) {
291
-        return audioMutedSpan;
292
-    }
293
-
294
-    audioMutedSpan = document.createElement('span');
295
-    audioMutedSpan.className = 'audioMuted toolbar-icon';
296
-
297
-    UIUtil.setTooltip(audioMutedSpan,
298
-        "videothumbnail.mute",
299
-        "top");
300
-
301
-    let mutedIndicator = document.createElement('i');
302
-    mutedIndicator.className = 'icon-mic-disabled';
303
-    audioMutedSpan.appendChild(mutedIndicator);
304
-
305
-    this.container
306
-        .querySelector('.videocontainer__toolbar')
307
-        .appendChild(audioMutedSpan);
308
-
309
-    return audioMutedSpan;
280
+    this.updateStatusBar();
310 281
 };
311 282
 
312 283
 /**
@@ -320,75 +291,38 @@ SmallVideo.prototype.setVideoMutedView = function(isMuted) {
320 291
     this.isVideoMuted = isMuted;
321 292
     this.updateView();
322 293
 
323
-    let element = this.getVideoMutedIndicator();
324
-
325
-    UIUtil.setVisible(element, isMuted);
294
+    this.updateStatusBar();
326 295
 };
327 296
 
328 297
 /**
329
- * Returns the video muted indicator jquery object. If it doesn't exists -
330
- * creates it.
298
+ * Create or updates the ReactElement for displaying status indicators about
299
+ * audio mute, video mute, and moderator status.
331 300
  *
332
- * @returns {jQuery|HTMLElement} the video muted indicator
301
+ * @returns {void}
333 302
  */
334
-SmallVideo.prototype.getVideoMutedIndicator = function () {
335
-    var selector = '#' + this.videoSpanId + ' .videoMuted';
336
-    var videoMutedSpan = document.querySelector(selector);
337
-
338
-    if (videoMutedSpan) {
339
-        return videoMutedSpan;
340
-    }
341
-
342
-    videoMutedSpan = document.createElement('span');
343
-    videoMutedSpan.className = 'videoMuted toolbar-icon';
344
-
345
-    this.container
346
-        .querySelector('.videocontainer__toolbar')
347
-        .appendChild(videoMutedSpan);
348
-
349
-    var mutedIndicator = document.createElement('i');
350
-    mutedIndicator.className = 'icon-camera-disabled';
351
-
352
-    UIUtil.setTooltip(mutedIndicator,
353
-        "videothumbnail.videomute",
354
-        "top");
303
+SmallVideo.prototype.updateStatusBar = function () {
304
+    const statusBarContainer
305
+        = this.container.querySelector('.videocontainer__toolbar');
355 306
 
356
-    videoMutedSpan.appendChild(mutedIndicator);
357
-
358
-    return videoMutedSpan;
307
+    /* jshint ignore:start */
308
+    ReactDOM.render(
309
+        <div>
310
+            { this.isAudioMuted ? <AudioMutedIndicator /> : null }
311
+            { this.isVideoMuted ? <VideoMutedIndicator /> : null }
312
+            { this._isModerator
313
+                && !interfaceConfig.DISABLE_FOCUS_INDICATOR
314
+                    ? <ModeratorIndicator /> : null }
315
+        </div>,
316
+        statusBarContainer);
317
+    /* jshint ignore:end */
359 318
 };
360 319
 
361 320
 /**
362 321
  * Adds the element indicating the moderator(owner) of the conference.
363 322
  */
364 323
 SmallVideo.prototype.addModeratorIndicator = function () {
365
-
366
-    // Don't create moderator indicator if DISABLE_FOCUS_INDICATOR is true
367
-    if (interfaceConfig.DISABLE_FOCUS_INDICATOR)
368
-        return false;
369
-
370
-    // Show moderator indicator
371
-    var indicatorSpan = $('#' + this.videoSpanId + ' .focusindicator');
372
-
373
-    if (indicatorSpan.length) {
374
-        return;
375
-    }
376
-
377
-    indicatorSpan = document.createElement('span');
378
-    indicatorSpan.className = 'focusindicator toolbar-icon right';
379
-
380
-    this.container
381
-        .querySelector('.videocontainer__toolbar')
382
-        .appendChild(indicatorSpan);
383
-
384
-    var moderatorIndicator = document.createElement('i');
385
-    moderatorIndicator.className = 'icon-star';
386
-
387
-    UIUtil.setTooltip(moderatorIndicator,
388
-        "videothumbnail.moderator",
389
-        "top-left");
390
-
391
-    indicatorSpan.appendChild(moderatorIndicator);
324
+    this._isModerator = true;
325
+    this.updateStatusBar();
392 326
 };
393 327
 
394 328
 /**
@@ -456,7 +390,8 @@ SmallVideo.prototype._getAudioLevelContainer = function () {
456 390
  * Removes the element indicating the moderator(owner) of the conference.
457 391
  */
458 392
 SmallVideo.prototype.removeModeratorIndicator = function () {
459
-    $('#' + this.videoSpanId + ' .focusindicator').remove();
393
+    this._isModerator = false;
394
+    this.updateStatusBar();
460 395
 };
461 396
 
462 397
 /**

+ 1
- 0
react/features/filmstrip/components/_.web.js Ver fichero

@@ -0,0 +1 @@
1
+export * from './web';

+ 2
- 0
react/features/filmstrip/components/index.js Ver fichero

@@ -1 +1,3 @@
1
+export * from './_';
2
+
1 3
 export { default as Filmstrip } from './Filmstrip';

+ 24
- 0
react/features/filmstrip/components/web/AudioMutedIndicator.js Ver fichero

@@ -0,0 +1,24 @@
1
+import BaseIndicator from './BaseIndicator';
2
+
3
+/**
4
+ * React {@code Component} for showing an audio muted icon with a tooltip.
5
+ *
6
+ * @extends BaseIndicator
7
+ */
8
+class AudioMutedIndicator extends BaseIndicator {
9
+    /**
10
+     * Initializes a new AudioMutedIcon instance.
11
+     *
12
+     * @param {Object} props - The read-only React Component props with which
13
+     * the new instance is to be initialized.
14
+     */
15
+    constructor(props) {
16
+        super(props);
17
+
18
+        this._classNames = 'audioMuted toolbar-icon';
19
+        this._iconClass = 'icon-mic-disabled';
20
+        this._tooltipKey = 'videothumbnail.mute';
21
+    }
22
+}
23
+
24
+export default AudioMutedIndicator;

+ 110
- 0
react/features/filmstrip/components/web/BaseIndicator.js Ver fichero

@@ -0,0 +1,110 @@
1
+import React, { Component } from 'react';
2
+
3
+import UIUtil from '../../../../../modules/UI/util/UIUtil';
4
+
5
+/**
6
+ * React {@code Component} for showing an icon with a tooltip.
7
+ *
8
+ * @extends Component
9
+ */
10
+class BaseIndicator extends Component {
11
+    /**
12
+     * Initializes a new {@code BaseIndicator} instance.
13
+     *
14
+     * @param {Object} props - The read-only properties with which the new
15
+     * instance is to be initialized.
16
+     */
17
+    constructor(props) {
18
+        super(props);
19
+
20
+        /**
21
+         * The CSS classes to apply to the root HTML element of the component.
22
+         *
23
+         * @type {string}
24
+         */
25
+        this._classNames = '';
26
+
27
+        /**
28
+         * The CSS class which will display an icon.
29
+         *
30
+         * @type {string}
31
+         */
32
+        this._iconClass = '';
33
+
34
+        /**
35
+         * An internal reference to the HTML element at the top of the
36
+         * component's DOM hierarchy. The reference is needed for attaching a
37
+         * tooltip.
38
+         *
39
+         * @type {HTMLElement}
40
+         */
41
+        this._rootElement = null;
42
+
43
+        /**
44
+         * The translation key for the text to display in the tooltip.
45
+         *
46
+         * @type {string}
47
+         */
48
+        this._tooltipKey = '';
49
+
50
+        // Bind event handler so it is only bound once for every instance.
51
+        this._setRootElementRef = this._setRootElementRef.bind(this);
52
+    }
53
+
54
+    /**
55
+     * Sets a tooltip which will display when hovering over the component.
56
+     *
57
+     * @inheritdoc
58
+     * @returns {void}
59
+     */
60
+    componentDidMount() {
61
+        this._setTooltip();
62
+    }
63
+
64
+    /**
65
+     * Implements React's {@link Component#render()}.
66
+     *
67
+     * @inheritdoc
68
+     * @returns {ReactElement}
69
+     */
70
+    render() {
71
+        return (
72
+            <span className = { this._classNames }>
73
+                <i
74
+                    className = { this._iconClass }
75
+                    ref = { this._setRootElementRef } />
76
+            </span>
77
+        );
78
+    }
79
+
80
+    /**
81
+     * Sets the internal reference to the root HTML element for the component.
82
+     *
83
+     * @param {HTMLIconElement} element - The root HTML element of the
84
+     * component.
85
+     * @private
86
+     * @returns {void}
87
+     */
88
+    _setRootElementRef(element) {
89
+        this._rootElement = element;
90
+    }
91
+
92
+    /**
93
+     * Associate the component as a tooltip trigger so a tooltip may display on
94
+     * hover.
95
+     *
96
+     * @private
97
+     * @returns {void}
98
+     */
99
+    _setTooltip() {
100
+        // TODO Replace UIUtil with an AtlasKit component when a suitable one
101
+        // becomes available for tooltips.
102
+        UIUtil.setTooltip(
103
+            this._rootElement,
104
+            this._tooltipKey,
105
+            'top'
106
+        );
107
+    }
108
+}
109
+
110
+export default BaseIndicator;

+ 24
- 0
react/features/filmstrip/components/web/ModeratorIndicator.js Ver fichero

@@ -0,0 +1,24 @@
1
+import BaseIndicator from './BaseIndicator';
2
+
3
+/**
4
+ * React {@code Component} for showing a moderator icon with a tooltip.
5
+ *
6
+ * @extends BaseIndicator
7
+ */
8
+class ModeratorIndicator extends BaseIndicator {
9
+    /**
10
+     * Initializes a new ModeratorIndicator instance.
11
+     *
12
+     * @param {Object} props - The read-only React Component props with which
13
+     * the new instance is to be initialized.
14
+     */
15
+    constructor(props) {
16
+        super(props);
17
+
18
+        this._classNames = 'focusindicator toolbar-icon right';
19
+        this._iconClass = 'icon-star';
20
+        this._tooltipKey = 'videothumbnail.moderator';
21
+    }
22
+}
23
+
24
+export default ModeratorIndicator;

+ 24
- 0
react/features/filmstrip/components/web/VideoMutedIndicator.js Ver fichero

@@ -0,0 +1,24 @@
1
+import BaseIndicator from './BaseIndicator';
2
+
3
+/**
4
+ * React {@code Component} for showing a video muted icon with a tooltip.
5
+ *
6
+ * @extends BaseIndicator
7
+ */
8
+class VideoMutedIndicator extends BaseIndicator {
9
+    /**
10
+     * Initializes a new VideoMutedIndicator instance.
11
+     *
12
+     * @param {Object} props - The read-only React Component props with which
13
+     * the new instance is to be initialized.
14
+     */
15
+    constructor(props) {
16
+        super(props);
17
+
18
+        this._classNames = 'videoMuted toolbar-icon';
19
+        this._iconClass = 'icon-camera-disabled';
20
+        this._tooltipKey = 'videothumbnail.videomute';
21
+    }
22
+}
23
+
24
+export default VideoMutedIndicator;

+ 3
- 0
react/features/filmstrip/components/web/index.js Ver fichero

@@ -0,0 +1,3 @@
1
+export { default as AudioMutedIndicator } from './AudioMutedIndicator';
2
+export { default as ModeratorIndicator } from './ModeratorIndicator';
3
+export { default as VideoMutedIndicator } from './VideoMutedIndicator';

Loading…
Cancelar
Guardar