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.
pull/1719/head jitsi-meet_2207
Leonard Kim 8 years ago committed by yanas
parent 573aa168ea
commit 152427e01b
  1. 1
      css/_vertical_filmstrip_overrides.scss
  2. 8
      modules/UI/videolayout/RemoteVideo.js
  3. 125
      modules/UI/videolayout/SmallVideo.js
  4. 1
      react/features/filmstrip/components/_.web.js
  5. 2
      react/features/filmstrip/components/index.js
  6. 24
      react/features/filmstrip/components/web/AudioMutedIndicator.js
  7. 110
      react/features/filmstrip/components/web/BaseIndicator.js
  8. 24
      react/features/filmstrip/components/web/ModeratorIndicator.js
  9. 24
      react/features/filmstrip/components/web/VideoMutedIndicator.js
  10. 3
      react/features/filmstrip/components/web/index.js

@ -82,6 +82,7 @@
.toolbar-icon {
float: none;
margin: auto;
}
}
}

@ -2,6 +2,7 @@
/* eslint-disable no-unused-vars */
import React from 'react';
import ReactDOM from 'react-dom';
import {
MuteButton,
@ -515,6 +516,13 @@ RemoteVideo.prototype.remove = function () {
this.removeAudioLevelIndicator();
const toolbarContainer
= this.container.querySelector('.videocontainer__toolbar');
if (toolbarContainer) {
ReactDOM.unmountComponentAtNode(toolbarContainer);
}
this.removeConnectionIndicator();
this.removeDisplayName();

@ -16,7 +16,12 @@ import {
ConnectionIndicator
} from '../../../react/features/connection-indicator';
import { DisplayName } from '../../../react/features/display-name';
/* eslint-disable no-unused-vars */
import {
AudioMutedIndicator,
ModeratorIndicator,
VideoMutedIndicator
} from '../../../react/features/filmstrip';
/* eslint-enable no-unused-vars */
const logger = require("jitsi-meet-logger").getLogger(__filename);
@ -64,6 +69,7 @@ const DISPLAY_VIDEO_WITH_NAME = 3;
const DISPLAY_AVATAR_WITH_NAME = 4;
function SmallVideo(VideoLayout) {
this._isModerator = false;
this.isAudioMuted = false;
this.hasAvatar = false;
this.isVideoMuted = false;
@ -270,43 +276,8 @@ SmallVideo.prototype.updateConnectionStatus = function (connectionStatus) {
* or hidden
*/
SmallVideo.prototype.showAudioIndicator = function (isMuted) {
let mutedIndicator = this.getAudioMutedIndicator();
UIUtil.setVisible(mutedIndicator, isMuted);
this.isAudioMuted = isMuted;
};
/**
* Returns the audio muted indicator jquery object. If it doesn't exists -
* creates it.
*
* @returns {HTMLElement} the audio muted indicator
*/
SmallVideo.prototype.getAudioMutedIndicator = function () {
let selector = '#' + this.videoSpanId + ' .audioMuted';
let audioMutedSpan = document.querySelector(selector);
if (audioMutedSpan) {
return audioMutedSpan;
}
audioMutedSpan = document.createElement('span');
audioMutedSpan.className = 'audioMuted toolbar-icon';
UIUtil.setTooltip(audioMutedSpan,
"videothumbnail.mute",
"top");
let mutedIndicator = document.createElement('i');
mutedIndicator.className = 'icon-mic-disabled';
audioMutedSpan.appendChild(mutedIndicator);
this.container
.querySelector('.videocontainer__toolbar')
.appendChild(audioMutedSpan);
return audioMutedSpan;
this.updateStatusBar();
};
/**
@ -320,75 +291,38 @@ SmallVideo.prototype.setVideoMutedView = function(isMuted) {
this.isVideoMuted = isMuted;
this.updateView();
let element = this.getVideoMutedIndicator();
UIUtil.setVisible(element, isMuted);
this.updateStatusBar();
};
/**
* Returns the video muted indicator jquery object. If it doesn't exists -
* creates it.
* Create or updates the ReactElement for displaying status indicators about
* audio mute, video mute, and moderator status.
*
* @returns {jQuery|HTMLElement} the video muted indicator
* @returns {void}
*/
SmallVideo.prototype.getVideoMutedIndicator = function () {
var selector = '#' + this.videoSpanId + ' .videoMuted';
var videoMutedSpan = document.querySelector(selector);
if (videoMutedSpan) {
return videoMutedSpan;
}
videoMutedSpan = document.createElement('span');
videoMutedSpan.className = 'videoMuted toolbar-icon';
this.container
.querySelector('.videocontainer__toolbar')
.appendChild(videoMutedSpan);
var mutedIndicator = document.createElement('i');
mutedIndicator.className = 'icon-camera-disabled';
UIUtil.setTooltip(mutedIndicator,
"videothumbnail.videomute",
"top");
SmallVideo.prototype.updateStatusBar = function () {
const statusBarContainer
= this.container.querySelector('.videocontainer__toolbar');
videoMutedSpan.appendChild(mutedIndicator);
return videoMutedSpan;
/* jshint ignore:start */
ReactDOM.render(
<div>
{ this.isAudioMuted ? <AudioMutedIndicator /> : null }
{ this.isVideoMuted ? <VideoMutedIndicator /> : null }
{ this._isModerator
&& !interfaceConfig.DISABLE_FOCUS_INDICATOR
? <ModeratorIndicator /> : null }
</div>,
statusBarContainer);
/* jshint ignore:end */
};
/**
* Adds the element indicating the moderator(owner) of the conference.
*/
SmallVideo.prototype.addModeratorIndicator = function () {
// Don't create moderator indicator if DISABLE_FOCUS_INDICATOR is true
if (interfaceConfig.DISABLE_FOCUS_INDICATOR)
return false;
// Show moderator indicator
var indicatorSpan = $('#' + this.videoSpanId + ' .focusindicator');
if (indicatorSpan.length) {
return;
}
indicatorSpan = document.createElement('span');
indicatorSpan.className = 'focusindicator toolbar-icon right';
this.container
.querySelector('.videocontainer__toolbar')
.appendChild(indicatorSpan);
var moderatorIndicator = document.createElement('i');
moderatorIndicator.className = 'icon-star';
UIUtil.setTooltip(moderatorIndicator,
"videothumbnail.moderator",
"top-left");
indicatorSpan.appendChild(moderatorIndicator);
this._isModerator = true;
this.updateStatusBar();
};
/**
@ -456,7 +390,8 @@ SmallVideo.prototype._getAudioLevelContainer = function () {
* Removes the element indicating the moderator(owner) of the conference.
*/
SmallVideo.prototype.removeModeratorIndicator = function () {
$('#' + this.videoSpanId + ' .focusindicator').remove();
this._isModerator = false;
this.updateStatusBar();
};
/**

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

@ -0,0 +1,24 @@
import BaseIndicator from './BaseIndicator';
/**
* React {@code Component} for showing an audio muted icon with a tooltip.
*
* @extends BaseIndicator
*/
class AudioMutedIndicator extends BaseIndicator {
/**
* Initializes a new AudioMutedIcon instance.
*
* @param {Object} props - The read-only React Component props with which
* the new instance is to be initialized.
*/
constructor(props) {
super(props);
this._classNames = 'audioMuted toolbar-icon';
this._iconClass = 'icon-mic-disabled';
this._tooltipKey = 'videothumbnail.mute';
}
}
export default AudioMutedIndicator;

@ -0,0 +1,110 @@
import React, { Component } from 'react';
import UIUtil from '../../../../../modules/UI/util/UIUtil';
/**
* React {@code Component} for showing an icon with a tooltip.
*
* @extends Component
*/
class BaseIndicator extends Component {
/**
* Initializes a new {@code BaseIndicator} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
/**
* The CSS classes to apply to the root HTML element of the component.
*
* @type {string}
*/
this._classNames = '';
/**
* The CSS class which will display an icon.
*
* @type {string}
*/
this._iconClass = '';
/**
* An internal reference to the HTML element at the top of the
* component's DOM hierarchy. The reference is needed for attaching a
* tooltip.
*
* @type {HTMLElement}
*/
this._rootElement = null;
/**
* The translation key for the text to display in the tooltip.
*
* @type {string}
*/
this._tooltipKey = '';
// Bind event handler so it is only bound once for every instance.
this._setRootElementRef = this._setRootElementRef.bind(this);
}
/**
* Sets a tooltip which will display when hovering over the component.
*
* @inheritdoc
* @returns {void}
*/
componentDidMount() {
this._setTooltip();
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
return (
<span className = { this._classNames }>
<i
className = { this._iconClass }
ref = { this._setRootElementRef } />
</span>
);
}
/**
* Sets the internal reference to the root HTML element for the component.
*
* @param {HTMLIconElement} element - The root HTML element of the
* component.
* @private
* @returns {void}
*/
_setRootElementRef(element) {
this._rootElement = element;
}
/**
* Associate the component as a tooltip trigger so a tooltip may display on
* hover.
*
* @private
* @returns {void}
*/
_setTooltip() {
// TODO Replace UIUtil with an AtlasKit component when a suitable one
// becomes available for tooltips.
UIUtil.setTooltip(
this._rootElement,
this._tooltipKey,
'top'
);
}
}
export default BaseIndicator;

@ -0,0 +1,24 @@
import BaseIndicator from './BaseIndicator';
/**
* React {@code Component} for showing a moderator icon with a tooltip.
*
* @extends BaseIndicator
*/
class ModeratorIndicator extends BaseIndicator {
/**
* Initializes a new ModeratorIndicator instance.
*
* @param {Object} props - The read-only React Component props with which
* the new instance is to be initialized.
*/
constructor(props) {
super(props);
this._classNames = 'focusindicator toolbar-icon right';
this._iconClass = 'icon-star';
this._tooltipKey = 'videothumbnail.moderator';
}
}
export default ModeratorIndicator;

@ -0,0 +1,24 @@
import BaseIndicator from './BaseIndicator';
/**
* React {@code Component} for showing a video muted icon with a tooltip.
*
* @extends BaseIndicator
*/
class VideoMutedIndicator extends BaseIndicator {
/**
* Initializes a new VideoMutedIndicator instance.
*
* @param {Object} props - The read-only React Component props with which
* the new instance is to be initialized.
*/
constructor(props) {
super(props);
this._classNames = 'videoMuted toolbar-icon';
this._iconClass = 'icon-camera-disabled';
this._tooltipKey = 'videothumbnail.videomute';
}
}
export default VideoMutedIndicator;

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