ref(always-on-top): refactor to stop using old toolbar components
This commit is contained in:
parent
be78ab5317
commit
5cf16a20d3
|
@ -440,6 +440,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.always-on-top-toolbox,
|
||||||
.filmstrip-toolbox {
|
.filmstrip-toolbox {
|
||||||
background-color: $newToolbarBackgroundColor;
|
background-color: $newToolbarBackgroundColor;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -450,10 +451,6 @@
|
||||||
i {
|
i {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 1.9em;
|
|
||||||
height: 37px;
|
|
||||||
line-height: 37px;
|
|
||||||
width: 37px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i:hover {
|
i:hover {
|
||||||
|
@ -464,7 +461,7 @@
|
||||||
background: $newToolbarButtonToggleColor;
|
background: $newToolbarButtonToggleColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
i.toggled:hover {
|
i.toggled:hover:not(.disabled) {
|
||||||
background-color: $newToolbarButtonHoverColor;
|
background-color: $newToolbarButtonHoverColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,6 +476,45 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
border-radius: 3px;
|
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 {
|
.toolbox-button:first-child i {
|
||||||
border-top-left-radius: 3px;
|
border-top-left-radius: 3px;
|
||||||
|
|
|
@ -2,54 +2,10 @@
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import StatelessToolbar from '../toolbox/components/StatelessToolbar';
|
import ToolboxAlwaysOnTop from './ToolboxAlwaysOnTop';
|
||||||
import StatelessToolbarButton
|
|
||||||
from '../toolbox/components/StatelessToolbarButton';
|
|
||||||
|
|
||||||
const { api } = window.alwaysOnTop;
|
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.
|
* The timeout in ms for hidding the toolbar.
|
||||||
*/
|
*/
|
||||||
|
@ -385,62 +341,16 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const className
|
|
||||||
= `toolbar_primary always-on-top ${
|
|
||||||
this.state.visible ? 'fadeIn' : 'fadeOut'}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id = 'alwaysOnTop'>
|
<div id = 'alwaysOnTop'>
|
||||||
<StatelessToolbar
|
<ToolboxAlwaysOnTop
|
||||||
className = { className }
|
audioAvailable = { this.state.audioAvailable }
|
||||||
|
audioMuted = { this.state.audioMuted }
|
||||||
|
className = { this.state.visible ? 'fadeIn' : 'fadeOut' }
|
||||||
onMouseOut = { this._onMouseOut }
|
onMouseOut = { this._onMouseOut }
|
||||||
onMouseOver = { this._onMouseOver }>
|
onMouseOver = { this._onMouseOver }
|
||||||
{
|
videoAvailable = { this.state.videoAvailable }
|
||||||
Object.entries(TOOLBAR_BUTTONS).map(
|
videoMuted = { this.state.videoMuted } />
|
||||||
([ 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>
|
|
||||||
{
|
{
|
||||||
this._renderVideoNotAvailableScreen()
|
this._renderVideoNotAvailableScreen()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,11 +53,13 @@ class ToolbarButton extends AbstractToolbarButton {
|
||||||
aria-label = { this.props.accessibilityLabel }
|
aria-label = { this.props.accessibilityLabel }
|
||||||
className = 'toolbox-button'
|
className = 'toolbox-button'
|
||||||
onClick = { this.props.onClick }>
|
onClick = { this.props.onClick }>
|
||||||
<Tooltip
|
{ this.props.tooltip
|
||||||
|
? <Tooltip
|
||||||
description = { this.props.tooltip }
|
description = { this.props.tooltip }
|
||||||
position = { this.props.tooltipPosition }>
|
position = { this.props.tooltipPosition }>
|
||||||
{ children }
|
{ children }
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
: children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue