feat(small-video): use AtlasKit tooltip

This commit is contained in:
Leonard Kim 2017-08-15 15:14:49 -07:00 committed by yanas
parent 2356238887
commit 38e2443ab7
12 changed files with 208 additions and 118 deletions

View File

@ -11,13 +11,13 @@
right: 0;
padding: 10px 5px;
@extend %align-right;
z-index: $filmstripVideosZ;
&__toolbar {
@include flex();
flex-direction: column-reverse;
flex-wrap: nowrap;
position: relative;
z-index: $zindex1; // Set z-index to make element visible.
width: $filmstripToggleButtonWidth;
button {
@ -53,7 +53,6 @@
/* The filmstrip should not be covered by the left toolbar. */
bottom: 0;
width:auto;
z-index: $filmstripVideosZ;
transition: bottom 2s;
overflow: visible !important;
/*!!! Removes the gap between the local video container and the remote

View File

@ -112,7 +112,7 @@
&__toolbar {
text-align: right;
.toolbar-icon {
.right {
float: none;
margin: auto;
}
@ -193,9 +193,28 @@
*/
.connection-indicator,
.remote-video-menu-trigger,
.videocontainer__toolbar,
.raisehandindicator,
#dominantspeakerindicator {
.indicator-icon-container {
transform: translate3d(0, 0, 0);
}
.indicator-container {
float: none;
}
/**
* FIXME: disable pointer to allow any elements moved below to still be
* clickable. The real fix would to make sure those moved elements are
* actually part of the toolbar instead of positioning being faked.
*/
.videocontainer__toolbar {
pointer-events: none;
> div {
pointer-events: none;
}
.toolbar-icon {
pointer-events: all;
}
}
}

View File

@ -41,9 +41,30 @@
&__toptoolbar {
position: absolute;
left: 0;
z-index: $zindex3;
pointer-events: none;
z-index: $zindex10;
width: 100%;
box-sizing: border-box; // Includes the padding in the 100% width.
/**
* FIXME (lenny): Disabling pointer-events is a pretty big sin that
* sidesteps the problems. There are z-index wars occurring within
* videocontainer and AtlasKit Tooltips rely on their parent z-indexe
* being higher than whatever they need to appear over. So set a higher
* z-index for the tooltip containers but make any empty space not block
* mouse overs for various mouseover triggers.
*/
pointer-events: none;
* {
pointer-events: auto;
}
.indicator-container {
display: inline-block;
float: left;
pointer-events: all;
}
}
&__toolbar {
@ -69,24 +90,21 @@
margin-top: $toolbarIconMargin;
}
.indicator:nth-child(1) {
.indicator-container:nth-child(1) .indicator {
margin-left: $toolbarIconMargin;
}
.connection-indicator,
span.indicator {
margin-right: em(5, 8);
div.indicator-container,
{
margin-right: 4px;
}
span.indicator {
display: none;
&:last-child {
margin-right: 0;
}
div.indicator:last-child {
margin-right: 0;
}
.connection-indicator-container {
.indicator-container {
display: inline-block;
vertical-align: top;
@ -96,7 +114,7 @@
}
.connection-indicator,
span.indicator {
.indicator {
position: relative;
font-size: 8px;
text-align: center;
@ -307,7 +325,6 @@
padding: 0;
border: 0;
margin: 0px 5px 0px 0px;
float: left;
}
/**
@ -320,9 +337,17 @@
/**
* Toolbar icons positioned on the right.
*/
.toolbar-icon.right {
float: right;
margin: 0px 0px 0px 5px;
.moderator-icon {
display: inline-block;
&.right {
float: right;
margin: 0px 0px 0px 5px;
}
.toolbar-icon {
margin: 0;
}
}
.raisehandindicator {
@ -340,7 +365,7 @@
position: absolute;
top: 0px;
right: 0;
z-index: $zindex3;
z-index: $zindex2;
width: 18px;
height: 13px;
color: #FFF;

View File

@ -168,9 +168,8 @@
},
"videothumbnail":
{
"editnickname": "Click to edit your<br/>display name",
"moderator": "The owner of<br/>this conference",
"videomute": "Participant has<br/>stopped the camera",
"moderator": "Moderator",
"videomute": "Participant has stopped the camera",
"mute": "Participant is muted",
"kick": "Kick out",
"muted": "Muted",

View File

@ -316,16 +316,27 @@ SmallVideo.prototype.setVideoMutedView = function(isMuted) {
SmallVideo.prototype.updateStatusBar = function () {
const statusBarContainer
= this.container.querySelector('.videocontainer__toolbar');
const tooltipPosition = interfaceConfig.VERTICAL_FILMSTRIP ? 'left' : 'top';
/* jshint ignore:start */
ReactDOM.render(
<div>
{ this.isAudioMuted ? <AudioMutedIndicator /> : null }
{ this.isVideoMuted ? <VideoMutedIndicator /> : null }
{ this._isModerator
&& !interfaceConfig.DISABLE_FOCUS_INDICATOR
? <ModeratorIndicator /> : null }
</div>,
<I18nextProvider i18n = { i18next }>
<div>
{ this.isAudioMuted
? <AudioMutedIndicator
tooltipPosition = { tooltipPosition } />
: null }
{ this.isVideoMuted
? <VideoMutedIndicator
tooltipPosition = { tooltipPosition } />
: null }
{ this._isModerator
&& !interfaceConfig.DISABLE_FOCUS_INDICATOR
? <ModeratorIndicator
tooltipPosition = { tooltipPosition } />
: null }
</div>
</I18nextProvider>,
statusBarContainer);
/* jshint ignore:end */
};
@ -744,6 +755,7 @@ SmallVideo.prototype.updateIndicators = function () {
= this.container.querySelector('.videocontainer__toptoolbar');
const iconSize = UIUtil.getIndicatorFontSize();
const tooltipPosition = interfaceConfig.VERTICAL_FILMSTRIP ? 'left' : 'top';
/* jshint ignore:start */
ReactDOM.render(
@ -758,10 +770,14 @@ SmallVideo.prototype.updateIndicators = function () {
userID = { this.id } />
: null }
{ this._showRaisedHand
? <RaisedHandIndicator iconSize = { iconSize } />
? <RaisedHandIndicator
iconSize = { iconSize }
tooltipPosition = { tooltipPosition } />
: null }
{ this._showDominantSpeaker
? <DominantSpeakerIndicator iconSize = { iconSize } />
? <DominantSpeakerIndicator
iconSize = { iconSize }
tooltipPosition = { tooltipPosition } />
: null }
</div>
</I18nextProvider>,

View File

@ -175,7 +175,7 @@ class ConnectionIndicator extends Component {
*/
render() {
return (
<div className = 'connection-indicator-container'>
<div className = 'indicator-container'>
<AKInlineDialog
content = { this._renderStatisticsTable() }
isOpen = { this.state.showStats }

View File

@ -8,6 +8,18 @@ import BaseIndicator from './BaseIndicator';
* @extends Component
*/
class AudioMutedIndicator extends Component {
/**
* {@code AudioMutedIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: React.PropTypes.string
};
/**
* Implements React's {@link Component#render()}.
*
@ -19,7 +31,8 @@ class AudioMutedIndicator extends Component {
<BaseIndicator
className = 'audioMuted toolbar-icon'
iconClassName = 'icon-mic-disabled'
tooltipKey = 'videothumbnail.mute' />
tooltipKey = 'videothumbnail.mute'
tooltipPosition = { this.props.tooltipPosition } />
);
}
}

View File

@ -1,6 +1,7 @@
import React, { Component } from 'react';
import Tooltip from '@atlaskit/tooltip';
import { setTooltip } from '../../../../../modules/UI/util/Tooltip';
import { translate } from '../../../base/i18n';
/**
* React {@code Component} for showing an icon with a tooltip.
@ -8,16 +9,27 @@ import { setTooltip } from '../../../../../modules/UI/util/Tooltip';
* @extends Component
*/
class BaseIndicator extends Component {
/**
* Default values for {@code BaseIndicator} component's properties.
*
* @static
*/
static defaultProps = {
className: '',
iconClassName: '',
iconSize: 'auto',
id: ''
id: '',
tooltipPosition: 'top'
};
/**
* {@code BaseIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* The CSS class names to set on the root element of the component.
* Additional CSS class names to set on the icon container.
*/
className: React.PropTypes.string,
@ -36,44 +48,23 @@ class BaseIndicator extends Component {
*/
id: React.PropTypes.string,
/**
* Invoked to obtain translated strings.
*/
t: React.PropTypes.func,
/**
* The translation key to use for displaying a tooltip when hovering
* over the component.
*/
tooltipKey: React.PropTypes.string
};
/**
* 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);
tooltipKey: React.PropTypes.string,
/**
* 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}
* From which side of the indicator the tooltip should appear from.
* Defaults to "top".
*/
this._rootElement = null;
// 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();
}
tooltipPosition: React.PropTypes.string
};
/**
* Implements React's {@link Component#render()}.
@ -82,46 +73,34 @@ class BaseIndicator extends Component {
* @returns {ReactElement}
*/
render() {
const {
className,
iconClassName,
iconSize,
id,
t,
tooltipKey,
tooltipPosition
} = this.props;
const iconContainerClassName = `indicator-icon-container ${className}`;
return (
<span
className = { this.props.className }
id = { this.props.id }
ref = { this._setRootElementRef }>
<i
className = { this.props.iconClassName }
style = {{ fontSize: this.props.iconSize }} />
</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.
setTooltip(
this._rootElement,
this.props.tooltipKey,
'top'
<div className = 'indicator-container'>
<Tooltip
description = { t(tooltipKey) }
position = { tooltipPosition }>
<span
className = { iconContainerClassName }
id = { id }>
<i
className = { iconClassName }
style = {{ fontSize: iconSize }} />
</span>
</Tooltip>
</div>
);
}
}
export default BaseIndicator;
export default translate(BaseIndicator);

View File

@ -20,7 +20,12 @@ class DominantSpeakerIndicator extends Component {
*
* @type {number}
*/
iconSize: React.PropTypes.number
iconSize: React.PropTypes.number,
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: React.PropTypes.string
};
/**
@ -35,7 +40,8 @@ class DominantSpeakerIndicator extends Component {
iconClassName = 'indicatoricon fa fa-bullhorn'
iconSize = { `${this.props.iconSize}px` }
id = 'dominantspeakerindicator'
tooltipKey = 'speaker' />
tooltipKey = 'speaker'
tooltipPosition = { this.props.tooltipPosition } />
);
}
}

View File

@ -8,6 +8,18 @@ import BaseIndicator from './BaseIndicator';
* @extends Component
*/
class ModeratorIndicator extends Component {
/**
* {@code ModeratorIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: React.PropTypes.string
};
/**
* Implements React's {@link Component#render()}.
*
@ -16,10 +28,13 @@ class ModeratorIndicator extends Component {
*/
render() {
return (
<BaseIndicator
className = 'focusindicator toolbar-icon right'
iconClassName = 'icon-star'
tooltipKey = 'videothumbnail.moderator' />
<div className = 'moderator-icon right'>
<BaseIndicator
className = 'focusindicator toolbar-icon'
iconClassName = 'icon-star'
tooltipKey = 'videothumbnail.moderator'
tooltipPosition = { this.props.tooltipPosition } />
</div>
);
}
}

View File

@ -19,7 +19,12 @@ class RaisedHandIndicator extends Component {
*
* @type {number}
*/
iconSize: React.PropTypes.number
iconSize: React.PropTypes.number,
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: React.PropTypes.string
};
/**
@ -33,7 +38,8 @@ class RaisedHandIndicator extends Component {
className = 'raisehandindicator indicator show-inline'
iconClassName = 'icon-raised-hand indicatoricon'
iconSize = { `${this.props.iconSize}px` }
tooltipKey = 'raisedHand' />
tooltipKey = 'raisedHand'
tooltipPosition = { this.props.tooltipPosition } />
);
}
}

View File

@ -7,6 +7,18 @@ import BaseIndicator from './BaseIndicator';
* @extends Component
*/
class VideoMutedIndicator extends Component {
/**
* {@code VideoMutedIndicator} component's property types.
*
* @static
*/
static propTypes = {
/**
* From which side of the indicator the tooltip should appear from.
*/
tooltipPosition: React.PropTypes.string
};
/**
* Implements React's {@link Component#render()}.
*
@ -17,7 +29,8 @@ class VideoMutedIndicator extends Component {
<BaseIndicator
className = 'videoMuted toolbar-icon'
iconClassName = 'icon-camera-disabled'
tooltipKey = 'videothumbnail.videomute' />
tooltipKey = 'videothumbnail.videomute'
tooltipPosition = { this.props.tooltipPosition } />
);
}
}