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 {
|
||||
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;
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue