ref(always-on-top): refactor to stop using old toolbar components

This commit is contained in:
Leonard Kim 2018-04-12 14:14:14 -07:00 committed by Saúl Ibarra Corretgé
parent be78ab5317
commit 5cf16a20d3
4 changed files with 215 additions and 108 deletions

View File

@ -440,6 +440,7 @@
}
}
.always-on-top-toolbox,
.filmstrip-toolbox {
background-color: $newToolbarBackgroundColor;
box-sizing: border-box;
@ -450,10 +451,6 @@
i {
cursor: pointer;
display: block;
font-size: 1.9em;
height: 37px;
line-height: 37px;
width: 37px;
}
i:hover {
@ -464,7 +461,7 @@
background: $newToolbarButtonToggleColor;
}
i.toggled:hover {
i.toggled:hover:not(.disabled) {
background-color: $newToolbarButtonHoverColor;
}
@ -479,6 +476,45 @@
}
border-radius: 3px;
}
.always-on-top-toolbox {
flex-direction: row;
left: 50%;
position: absolute;
top: 10px;
transform: translateX(-50%);
z-index: $toolbarZ;
i {
font-size: $alwaysOnTopToolbarFontSize;
height: $alwaysOnTopToolbarSize;
line-height: $alwaysOnTopToolbarSize;
width: $alwaysOnTopToolbarSize;
}
.disabled {
cursor: initial;
}
.toolbox-button:first-child i {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.toolbox-button:last-child i {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
}
.filmstrip-toolbox {
i {
font-size: 1.9em;
height: 37px;
line-height: 37px;
width: 37px;
}
.toolbox-button:first-child i {
border-top-left-radius: 3px;

View File

@ -2,54 +2,10 @@
import React, { Component } from 'react';
import StatelessToolbar from '../toolbox/components/StatelessToolbar';
import StatelessToolbarButton
from '../toolbox/components/StatelessToolbarButton';
import ToolboxAlwaysOnTop from './ToolboxAlwaysOnTop';
const { api } = window.alwaysOnTop;
/**
* Map with toolbar button descriptors.
*/
const TOOLBAR_BUTTONS = {
/**
* The descriptor of the camera toolbar button.
*/
camera: {
classNames: [ 'button', 'icon-camera' ],
enabled: true,
id: 'toolbar_button_camera',
onClick() {
api.executeCommand('toggleVideo');
}
},
/**
* The descriptor of the toolbar button which hangs up the call/conference.
*/
hangup: {
classNames: [ 'button', 'icon-hangup', 'button_hangup' ],
enabled: true,
id: 'toolbar_button_hangup',
onClick() {
api.executeCommand('hangup');
window.close();
}
},
/**
* The descriptor of the microphone toolbar button.
*/
microphone: {
classNames: [ 'button', 'icon-microphone' ],
enabled: true,
id: 'toolbar_button_mute',
onClick() {
api.executeCommand('toggleAudio');
}
}
};
/**
* The timeout in ms for hidding the toolbar.
*/
@ -385,62 +341,16 @@ export default class AlwaysOnTop extends Component<*, State> {
* @returns {ReactElement}
*/
render() {
const className
= `toolbar_primary always-on-top ${
this.state.visible ? 'fadeIn' : 'fadeOut'}`;
return (
<div id = 'alwaysOnTop'>
<StatelessToolbar
className = { className }
<ToolboxAlwaysOnTop
audioAvailable = { this.state.audioAvailable }
audioMuted = { this.state.audioMuted }
className = { this.state.visible ? 'fadeIn' : 'fadeOut' }
onMouseOut = { this._onMouseOut }
onMouseOver = { this._onMouseOver }>
{
Object.entries(TOOLBAR_BUTTONS).map(
([ key, button ]) => {
// XXX The following silences a couple of flow
// errors:
if (button === null
|| typeof button !== 'object') {
return null;
}
const { onClick } = button;
let enabled = false;
let toggled = false;
switch (key) {
case 'microphone':
enabled = this.state.audioAvailable;
toggled = enabled
? this.state.audioMuted : true;
break;
case 'camera':
enabled = this.state.videoAvailable;
toggled = enabled
? this.state.videoMuted : true;
break;
default: // hangup button
toggled = false;
enabled = true;
}
const updatedButton = {
...button,
enabled,
toggled
};
return (
<StatelessToolbarButton
button = { updatedButton }
key = { key }
onClick = { onClick } />
);
}
)
}
</StatelessToolbar>
onMouseOver = { this._onMouseOver }
videoAvailable = { this.state.videoAvailable }
videoMuted = { this.state.videoMuted } />
{
this._renderVideoNotAvailableScreen()
}

View File

@ -0,0 +1,159 @@
// @flow
import React, { Component } from 'react';
// FIXME: AlwaysOnTop imports the button directly in order to avoid bringing in
// other components that use lib-jitsi-meet, which always on top does not
// import.
import ToolbarButton from '../toolbox/components/ToolbarButton';
const { api } = window.alwaysOnTop;
/**
* The type of the React {@code Component} props of {@link ToolboxAlwaysOnTop}.
*/
type Props = {
/**
* Whether or not microphone access is available.
*/
audioAvailable: boolean,
/**
* Whether or not the user is currently audio muted.
*/
audioMuted: boolean,
/**
* Additional CSS class names to add to the root of the toolbar.
*/
className: string,
/**
* Callback invoked when no longer moused over the toolbar.
*/
onMouseOut: Function,
/**
* Callback invoked when the mouse has moved over the toolbar.
*/
onMouseOver: Function,
/**
* Whether or not camera access is available.
*/
videoAvailable: boolean,
/**
* Whether or not the user is currently video muted.
*/
videoMuted: boolean
};
/**
* Represents the toolbar in the Always On Top window.
*
* @extends Component
*/
export default class ToolboxAlwaysOnTop extends Component<Props> {
/**
* Initializes a new {@code ToolboxAlwaysOnTop} instance.
*
* @param {Props} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
// Bind event handlers so they are only bound once per instance.
this._onToolbarHangup = this._onToolbarHangup.bind(this);
this._onToolbarToggleAudio = this._onToolbarToggleAudio.bind(this);
this._onToolbarToggleVideo = this._onToolbarToggleVideo.bind(this);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const {
audioAvailable,
audioMuted,
className = '',
onMouseOut,
onMouseOver,
videoAvailable,
videoMuted
} = this.props;
const videoMuteIcon = `${videoMuted || !videoAvailable
? 'icon-camera-disabled toggled' : 'icon-camera'} ${
videoAvailable ? '' : 'disabled'}`;
const audioMuteIcon = `${audioMuted || !audioAvailable
? 'icon-mic-disabled toggled' : 'icon-microphone'} ${
audioAvailable ? '' : 'disabled'}`;
return (
<div
className = { `always-on-top-toolbox ${className}` }
onMouseOut = { onMouseOut }
onMouseOver = { onMouseOver }>
<ToolbarButton
accessibilityLabel = 'Video mute'
iconName = { videoMuteIcon }
onClick = { this._onToolbarToggleVideo } />
<ToolbarButton
accessibilityLabel = 'Hangup'
iconName = 'icon-hangup'
onClick = { this._onToolbarHangup } />
<ToolbarButton
accessibilityLabel = 'Audio mute'
iconName = { audioMuteIcon }
onClick = { this._onToolbarToggleAudio } />
</div>
);
}
_onToolbarHangup: () => void;
/**
* Ends the conference call and closes the always on top window.
*
* @private
* @returns {void}
*/
_onToolbarHangup() {
api.executeCommand('hangup');
window.close();
}
_onToolbarToggleAudio: () => void;
/**
* Toggles audio mute if audio is avaiable.
*
* @private
* @returns {void}
*/
_onToolbarToggleAudio() {
if (this.props.audioAvailable) {
api.executeCommand('toggleAudio');
}
}
_onToolbarToggleVideo: () => void;
/**
* Toggles video mute if video is avaiable.
*
* @private
* @returns {void}
*/
_onToolbarToggleVideo() {
if (this.props.videoAvailable) {
api.executeCommand('toggleVideo');
}
}
}

View File

@ -53,11 +53,13 @@ class ToolbarButton extends AbstractToolbarButton {
aria-label = { this.props.accessibilityLabel }
className = 'toolbox-button'
onClick = { this.props.onClick }>
<Tooltip
description = { this.props.tooltip }
position = { this.props.tooltipPosition }>
{ children }
</Tooltip>
{ this.props.tooltip
? <Tooltip
description = { this.props.tooltip }
position = { this.props.tooltipPosition }>
{ children }
</Tooltip>
: children }
</div>
);
}