Coding style
This commit is contained in:
parent
9ca7ca9515
commit
a42496ba53
|
@ -7,12 +7,12 @@ import Toolbar from './Toolbar';
|
||||||
const { api } = window.alwaysOnTop;
|
const { api } = window.alwaysOnTop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The timeout in ms for hidding the toolbar.
|
* The timeout in ms for hiding the toolbar.
|
||||||
*/
|
*/
|
||||||
const TOOLBAR_TIMEOUT = 4000;
|
const TOOLBAR_TIMEOUT = 4000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} state of {@link FeedbackButton}.
|
* The type of the React {@code Component} state of {@link AlwaysOnTop}.
|
||||||
*/
|
*/
|
||||||
type State = {
|
type State = {
|
||||||
avatarURL: string,
|
avatarURL: string,
|
||||||
|
@ -40,18 +40,18 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
visible: true,
|
avatarURL: '',
|
||||||
displayName: '',
|
displayName: '',
|
||||||
isVideoDisplayed: true,
|
isVideoDisplayed: true,
|
||||||
avatarURL: ''
|
visible: true
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bind event handlers so they are only bound once per instance.
|
// Bind event handlers so they are only bound once per instance.
|
||||||
this._avatarChangedListener = this._avatarChangedListener.bind(this);
|
this._avatarChangedListener = this._avatarChangedListener.bind(this);
|
||||||
this._largeVideoChangedListener
|
|
||||||
= this._largeVideoChangedListener.bind(this);
|
|
||||||
this._displayNameChangedListener
|
this._displayNameChangedListener
|
||||||
= this._displayNameChangedListener.bind(this);
|
= this._displayNameChangedListener.bind(this);
|
||||||
|
this._largeVideoChangedListener
|
||||||
|
= this._largeVideoChangedListener.bind(this);
|
||||||
this._mouseMove = this._mouseMove.bind(this);
|
this._mouseMove = this._mouseMove.bind(this);
|
||||||
this._onMouseOut = this._onMouseOut.bind(this);
|
this._onMouseOut = this._onMouseOut.bind(this);
|
||||||
this._onMouseOver = this._onMouseOver.bind(this);
|
this._onMouseOver = this._onMouseOver.bind(this);
|
||||||
|
@ -65,11 +65,8 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_avatarChangedListener({ avatarURL, id }) {
|
_avatarChangedListener({ avatarURL, id }) {
|
||||||
if (api._getOnStageParticipant() !== id) {
|
if (api._getOnStageParticipant() === id
|
||||||
return;
|
&& avatarURL !== this.state.avatarURL) {
|
||||||
}
|
|
||||||
|
|
||||||
if (avatarURL !== this.state.avatarURL) {
|
|
||||||
this.setState({ avatarURL });
|
this.setState({ avatarURL });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,11 +79,8 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_displayNameChangedListener({ formattedDisplayName, id }) {
|
_displayNameChangedListener({ formattedDisplayName, id }) {
|
||||||
if (api._getOnStageParticipant() !== id) {
|
if (api._getOnStageParticipant() === id
|
||||||
return;
|
&& formattedDisplayName !== this.state.displayName) {
|
||||||
}
|
|
||||||
|
|
||||||
if (formattedDisplayName !== this.state.displayName) {
|
|
||||||
this.setState({ displayName: formattedDisplayName });
|
this.setState({ displayName: formattedDisplayName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,14 +91,15 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_hideToolbarAfterTimeout() {
|
_hideToolbarAfterTimeout() {
|
||||||
setTimeout(() => {
|
setTimeout(
|
||||||
|
() => {
|
||||||
if (this._hovered) {
|
if (this._hovered) {
|
||||||
this._hideToolbarAfterTimeout();
|
this._hideToolbarAfterTimeout();
|
||||||
|
} else {
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({ visible: false });
|
this.setState({ visible: false });
|
||||||
}, TOOLBAR_TIMEOUT);
|
}
|
||||||
|
},
|
||||||
|
TOOLBAR_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
_largeVideoChangedListener: () => void;
|
_largeVideoChangedListener: () => void;
|
||||||
|
@ -116,8 +111,8 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
*/
|
*/
|
||||||
_largeVideoChangedListener() {
|
_largeVideoChangedListener() {
|
||||||
const userID = api._getOnStageParticipant();
|
const userID = api._getOnStageParticipant();
|
||||||
const displayName = api._getFormattedDisplayName(userID);
|
|
||||||
const avatarURL = api.getAvatarURL(userID);
|
const avatarURL = api.getAvatarURL(userID);
|
||||||
|
const displayName = api._getFormattedDisplayName(userID);
|
||||||
const isVideoDisplayed = Boolean(api._getLargeVideo());
|
const isVideoDisplayed = Boolean(api._getLargeVideo());
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -135,9 +130,7 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_mouseMove() {
|
_mouseMove() {
|
||||||
if (!this.state.visible) {
|
this.state.visible || this.setState({ visible: true });
|
||||||
this.setState({ visible: true });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseOut: () => void;
|
_onMouseOut: () => void;
|
||||||
|
@ -201,9 +194,9 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
api.on('largeVideoChanged', this._largeVideoChangedListener);
|
|
||||||
api.on('displayNameChange', this._displayNameChangedListener);
|
|
||||||
api.on('avatarChanged', this._avatarChangedListener);
|
api.on('avatarChanged', this._avatarChangedListener);
|
||||||
|
api.on('displayNameChange', this._displayNameChangedListener);
|
||||||
|
api.on('largeVideoChanged', this._largeVideoChangedListener);
|
||||||
|
|
||||||
this._largeVideoChangedListener();
|
this._largeVideoChangedListener();
|
||||||
|
|
||||||
|
@ -219,11 +212,14 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
api.removeListener('largeVideoChanged',
|
|
||||||
this._largeVideoChangedListener);
|
|
||||||
api.removeListener('displayNameChange',
|
|
||||||
this._displayNameChangedListener);
|
|
||||||
api.removeListener('avatarChanged', this._avatarChangedListener);
|
api.removeListener('avatarChanged', this._avatarChangedListener);
|
||||||
|
api.removeListener(
|
||||||
|
'displayNameChange',
|
||||||
|
this._displayNameChangedListener);
|
||||||
|
api.removeListener(
|
||||||
|
'largeVideoChanged',
|
||||||
|
this._largeVideoChangedListener);
|
||||||
|
|
||||||
window.removeEventListener('mousemove', this._mouseMove);
|
window.removeEventListener('mousemove', this._mouseMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,9 +248,7 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||||
className = { this.state.visible ? 'fadeIn' : 'fadeOut' }
|
className = { this.state.visible ? 'fadeIn' : 'fadeOut' }
|
||||||
onMouseOut = { this._onMouseOut }
|
onMouseOut = { this._onMouseOut }
|
||||||
onMouseOver = { this._onMouseOver } />
|
onMouseOver = { this._onMouseOver } />
|
||||||
{
|
{ this._renderVideoNotAvailableScreen() }
|
||||||
this._renderVideoNotAvailableScreen()
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// XXX: AlwaysOnTop imports the button directly in order to avoid bringing in
|
// XXX Import the button directly in order to avoid bringing in other components
|
||||||
// other components that use lib-jitsi-meet, which always on top does not
|
// that use lib-jitsi-meet, which always-on-top does not import.
|
||||||
// import.
|
|
||||||
import AbstractAudioMuteButton
|
import AbstractAudioMuteButton
|
||||||
from '../toolbox/components/buttons/AbstractAudioMuteButton';
|
from '../toolbox/components/buttons/AbstractAudioMuteButton';
|
||||||
import type { Props } from '../toolbox/components/buttons/AbstractButton';
|
import type { Props } from '../toolbox/components/buttons/AbstractButton';
|
||||||
|
|
||||||
const { api } = window.alwaysOnTop;
|
const { api } = window.alwaysOnTop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} state of {@link AudioMuteButton}.
|
||||||
|
*/
|
||||||
type State = {
|
type State = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +25,7 @@ type State = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stateless hangup button for the Always-on-Top windows.
|
* Stateless "mute/unmute audio" button for the Always-on-Top windows.
|
||||||
*/
|
*/
|
||||||
export default class AudioMuteButton
|
export default class AudioMuteButton
|
||||||
extends AbstractAudioMuteButton<Props, State> {
|
extends AbstractAudioMuteButton<Props, State> {
|
||||||
|
@ -62,14 +64,11 @@ export default class AudioMuteButton
|
||||||
api.isAudioAvailable(),
|
api.isAudioAvailable(),
|
||||||
api.isAudioMuted()
|
api.isAudioMuted()
|
||||||
])
|
])
|
||||||
.then(values => {
|
.then(([ audioAvailable, audioMuted ]) =>
|
||||||
const [ audioAvailable, audioMuted ] = values;
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
audioAvailable,
|
audioAvailable,
|
||||||
audioMuted
|
audioMuted
|
||||||
});
|
}))
|
||||||
})
|
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,45 +79,14 @@ export default class AudioMuteButton
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
api.removeListener('audioAvailabilityChanged',
|
api.removeListener(
|
||||||
|
'audioAvailabilityChanged',
|
||||||
this._audioAvailabilityListener);
|
this._audioAvailabilityListener);
|
||||||
api.removeListener('audioMuteStatusChanged',
|
api.removeListener(
|
||||||
|
'audioMuteStatusChanged',
|
||||||
this._audioMutedListener);
|
this._audioMutedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this button is disabled or not.
|
|
||||||
*
|
|
||||||
* @override
|
|
||||||
* @private
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
_isDisabled() {
|
|
||||||
return !this.state.audioAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if audio is currently muted ot nor.
|
|
||||||
*
|
|
||||||
* @override
|
|
||||||
* @private
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
_isAudioMuted() {
|
|
||||||
return this.state.audioMuted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the muted state.
|
|
||||||
*
|
|
||||||
* @param {boolean} audioMuted - Whether audio should be muted or not.
|
|
||||||
* @private
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
_setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
|
|
||||||
this.state.audioAvailable && api.executeCommand('toggleAudio');
|
|
||||||
}
|
|
||||||
|
|
||||||
_audioAvailabilityListener: ({ available: boolean }) => void;
|
_audioAvailabilityListener: ({ available: boolean }) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,4 +110,37 @@ export default class AudioMuteButton
|
||||||
_audioMutedListener({ muted }) {
|
_audioMutedListener({ muted }) {
|
||||||
this.setState({ audioMuted: muted });
|
this.setState({ audioMuted: muted });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if audio is currently muted ot nor.
|
||||||
|
*
|
||||||
|
* @override
|
||||||
|
* @private
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
_isAudioMuted() {
|
||||||
|
return this.state.audioMuted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this button is disabled or not.
|
||||||
|
*
|
||||||
|
* @override
|
||||||
|
* @private
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
_isDisabled() {
|
||||||
|
return !this.state.audioAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the muted state.
|
||||||
|
*
|
||||||
|
* @param {boolean} audioMuted - Whether audio should be muted or not.
|
||||||
|
* @private
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
|
||||||
|
this.state.audioAvailable && api.executeCommand('toggleAudio');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// XXX: AlwaysOnTop imports the button directly in order to avoid bringing in
|
// XXX Import the button directly in order to avoid bringing in other components
|
||||||
// other components that use lib-jitsi-meet, which always on top does not
|
// that use lib-jitsi-meet, which always-on-top does not import.
|
||||||
// import.
|
|
||||||
import AbstractHangupButton
|
import AbstractHangupButton
|
||||||
from '../toolbox/components/buttons/AbstractHangupButton';
|
from '../toolbox/components/buttons/AbstractHangupButton';
|
||||||
import type { Props } from '../toolbox/components/buttons/AbstractButton';
|
import type { Props } from '../toolbox/components/buttons/AbstractButton';
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// XXX: AlwaysOnTop imports the button directly in order to avoid bringing in
|
// XXX Import the button directly in order to avoid bringing in other components
|
||||||
// other components that use lib-jitsi-meet, which always on top does not
|
// that use lib-jitsi-meet, which always-on-top does not import.
|
||||||
// import.
|
|
||||||
import AbstractVideoMuteButton
|
import AbstractVideoMuteButton
|
||||||
from '../toolbox/components/buttons/AbstractVideoMuteButton';
|
from '../toolbox/components/buttons/AbstractVideoMuteButton';
|
||||||
import type { Props } from '../toolbox/components/buttons/AbstractButton';
|
import type { Props } from '../toolbox/components/buttons/AbstractButton';
|
||||||
|
|
||||||
const { api } = window.alwaysOnTop;
|
const { api } = window.alwaysOnTop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} state of {@link VideoMuteButton}.
|
||||||
|
*/
|
||||||
type State = {
|
type State = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +25,7 @@ type State = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stateless hangup button for the Always-on-Top windows.
|
* Stateless "mute/unmute video" button for the Always-on-Top windows.
|
||||||
*/
|
*/
|
||||||
export default class VideoMuteButton
|
export default class VideoMuteButton
|
||||||
extends AbstractVideoMuteButton<Props, State> {
|
extends AbstractVideoMuteButton<Props, State> {
|
||||||
|
@ -62,14 +64,11 @@ export default class VideoMuteButton
|
||||||
api.isVideoAvailable(),
|
api.isVideoAvailable(),
|
||||||
api.isVideoMuted()
|
api.isVideoMuted()
|
||||||
])
|
])
|
||||||
.then(values => {
|
.then(([ videoAvailable, videoMuted ]) =>
|
||||||
const [ videoAvailable, videoMuted ] = values;
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
videoAvailable,
|
videoAvailable,
|
||||||
videoMuted
|
videoMuted
|
||||||
});
|
}))
|
||||||
})
|
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +79,11 @@ export default class VideoMuteButton
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
api.removeListener('videoAvailabilityChanged',
|
api.removeListener(
|
||||||
|
'videoAvailabilityChanged',
|
||||||
this._videoAvailabilityListener);
|
this._videoAvailabilityListener);
|
||||||
api.removeListener('videoMuteStatusChanged',
|
api.removeListener(
|
||||||
|
'videoMuteStatusChanged',
|
||||||
this._videoMutedListener);
|
this._videoMutedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import AlwaysOnTop from './AlwaysOnTop';
|
import AlwaysOnTop from './AlwaysOnTop';
|
||||||
|
|
||||||
// Render the main/root Component.
|
// Render the main/root Component.
|
||||||
ReactDOM.render(
|
// $FlowExpectedError
|
||||||
<AlwaysOnTop />,
|
ReactDOM.render(<AlwaysOnTop />, document.getElementById('react'));
|
||||||
document.getElementById('react')
|
|
||||||
);
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener(
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById('react'));
|
'beforeunload',
|
||||||
});
|
() => ReactDOM.unmountComponentAtNode(document.getElementById('react')));
|
||||||
|
|
|
@ -139,10 +139,13 @@ class Conference extends Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
VIDEO_QUALITY_LABEL_DISABLED,
|
VIDEO_QUALITY_LABEL_DISABLED,
|
||||||
filmStripOnly
|
|
||||||
|
// XXX The character casing of the name filmStripOnly utilized by
|
||||||
|
// interfaceConfig is obsolete but legacy support is required.
|
||||||
|
filmStripOnly: filmstripOnly
|
||||||
} = interfaceConfig;
|
} = interfaceConfig;
|
||||||
const hideVideoQualityLabel
|
const hideVideoQualityLabel
|
||||||
= filmStripOnly
|
= filmstripOnly
|
||||||
|| VIDEO_QUALITY_LABEL_DISABLED
|
|| VIDEO_QUALITY_LABEL_DISABLED
|
||||||
|| this.props._iAmRecorder;
|
|| this.props._iAmRecorder;
|
||||||
|
|
||||||
|
@ -153,11 +156,11 @@ class Conference extends Component<Props> {
|
||||||
<div id = 'videospace'>
|
<div id = 'videospace'>
|
||||||
<LargeVideo
|
<LargeVideo
|
||||||
hideVideoQualityLabel = { hideVideoQualityLabel } />
|
hideVideoQualityLabel = { hideVideoQualityLabel } />
|
||||||
<Filmstrip filmstripOnly = { filmStripOnly } />
|
<Filmstrip filmstripOnly = { filmstripOnly } />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ !filmStripOnly && <Toolbox /> }
|
{ filmstripOnly || <Toolbox /> }
|
||||||
{ !filmStripOnly && <SidePanel /> }
|
{ filmstripOnly || <SidePanel /> }
|
||||||
|
|
||||||
<DialogContainer />
|
<DialogContainer />
|
||||||
<NotificationsContainer />
|
<NotificationsContainer />
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { dockToolbox } from '../../toolbox';
|
||||||
|
|
||||||
import { setFilmstripHovered } from '../actions';
|
import { setFilmstripHovered } from '../actions';
|
||||||
import { shouldRemoteVideosBeVisible } from '../functions';
|
import { shouldRemoteVideosBeVisible } from '../functions';
|
||||||
|
|
||||||
import Toolbar from './Toolbar';
|
import Toolbar from './Toolbar';
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
declare var interfaceConfig: Object;
|
||||||
|
@ -36,9 +35,9 @@ class Filmstrip extends Component<*> {
|
||||||
*/
|
*/
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
/**
|
/**
|
||||||
* Whether or not the conference is in filmstripOnly mode.
|
* Whether the UI/UX is filmstrip-only.
|
||||||
*/
|
*/
|
||||||
_filmStripOnly: PropTypes.bool,
|
_filmstripOnly: PropTypes.bool,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not remote videos are currently being hovered over.
|
* Whether or not remote videos are currently being hovered over.
|
||||||
|
@ -58,7 +57,7 @@ class Filmstrip extends Component<*> {
|
||||||
_toolboxVisible: PropTypes.bool,
|
_toolboxVisible: PropTypes.bool,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the redux store with filmstrip hover changes.
|
* The redux {@code dispatch} function.
|
||||||
*/
|
*/
|
||||||
dispatch: PropTypes.func
|
dispatch: PropTypes.func
|
||||||
};
|
};
|
||||||
|
@ -85,8 +84,8 @@ class Filmstrip extends Component<*> {
|
||||||
this._isHovered = false;
|
this._isHovered = false;
|
||||||
|
|
||||||
// Bind event handlers so they are only bound once for every instance.
|
// Bind event handlers so they are only bound once for every instance.
|
||||||
this._onMouseOver = this._onMouseOver.bind(this);
|
|
||||||
this._onMouseOut = this._onMouseOut.bind(this);
|
this._onMouseOut = this._onMouseOut.bind(this);
|
||||||
|
this._onMouseOver = this._onMouseOver.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,27 +96,27 @@ class Filmstrip extends Component<*> {
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
_filmStripOnly,
|
_filmstripOnly,
|
||||||
_remoteVideosVisible,
|
_remoteVideosVisible,
|
||||||
_toolboxVisible
|
_toolboxVisible
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
/**
|
// Note: Appending of {@code RemoteVideo} views is handled through
|
||||||
* Note: Appending of {@code RemoteVideo} views is handled through
|
// VideoLayout. The views do not get blown away on render() because
|
||||||
* VideoLayout. The views do not get blown away on render() because
|
// ReactDOMComponent is only aware of the given JSX and not new appended
|
||||||
* ReactDOMComponent is only aware of the given JSX and not new appended
|
// DOM. As such, when updateDOMProperties gets called, only attributes
|
||||||
* DOM. As such, when updateDOMProperties gets called, only attributes
|
// will get updated without replacing the DOM. If the known DOM gets
|
||||||
* will get updated without replacing the DOM. If the known DOM gets
|
// modified, then the views will get blown away.
|
||||||
* modified, then the views will get blown away.
|
|
||||||
*/
|
|
||||||
const reduceHeight
|
const reduceHeight
|
||||||
= _toolboxVisible && interfaceConfig.TOOLBAR_BUTTONS.length;
|
= _toolboxVisible && interfaceConfig.TOOLBAR_BUTTONS.length;
|
||||||
const filmstripClassNames = `filmstrip ${_remoteVideosVisible
|
const classNames
|
||||||
? '' : 'hide-videos'} ${reduceHeight ? 'reduce-height' : ''}`;
|
= `filmstrip ${
|
||||||
|
_remoteVideosVisible ? '' : 'hide-videos'} ${
|
||||||
|
reduceHeight ? 'reduce-height' : ''}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className = { filmstripClassNames }>
|
<div className = { classNames }>
|
||||||
{ _filmStripOnly && <Toolbar /> }
|
{ _filmstripOnly && <Toolbar /> }
|
||||||
<div
|
<div
|
||||||
className = 'filmstrip__videos'
|
className = 'filmstrip__videos'
|
||||||
id = 'remoteVideos'>
|
id = 'remoteVideos'>
|
||||||
|
@ -131,9 +130,9 @@ class Filmstrip extends Component<*> {
|
||||||
<div
|
<div
|
||||||
className = 'filmstrip__videos'
|
className = 'filmstrip__videos'
|
||||||
id = 'filmstripRemoteVideos'>
|
id = 'filmstripRemoteVideos'>
|
||||||
{/**
|
{/*
|
||||||
* This extra video container is needed for scrolling
|
* XXX This extra video container is needed for
|
||||||
* thumbnails in Firefox; otherwise, the flex
|
* scrolling thumbnails in Firefox; otherwise, the flex
|
||||||
* thumbnails resize instead of causing overflow.
|
* thumbnails resize instead of causing overflow.
|
||||||
*/}
|
*/}
|
||||||
<div
|
<div
|
||||||
|
@ -192,7 +191,7 @@ class Filmstrip extends Component<*> {
|
||||||
* @param {Object} state - The Redux state.
|
* @param {Object} state - The Redux state.
|
||||||
* @private
|
* @private
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* _filmStripOnly: boolean,
|
* _filmstripOnly: boolean,
|
||||||
* _hovered: boolean,
|
* _hovered: boolean,
|
||||||
* _remoteVideosVisible: boolean,
|
* _remoteVideosVisible: boolean,
|
||||||
* _toolboxVisible: boolean
|
* _toolboxVisible: boolean
|
||||||
|
@ -202,7 +201,7 @@ function _mapStateToProps(state) {
|
||||||
const { hovered } = state['features/filmstrip'];
|
const { hovered } = state['features/filmstrip'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_filmStripOnly: Boolean(interfaceConfig.filmStripOnly),
|
_filmstripOnly: Boolean(interfaceConfig.filmStripOnly),
|
||||||
_hovered: hovered,
|
_hovered: hovered,
|
||||||
_remoteVideosVisible: shouldRemoteVideosBeVisible(state),
|
_remoteVideosVisible: shouldRemoteVideosBeVisible(state),
|
||||||
_toolboxVisible: state['features/toolbox'].visible
|
_toolboxVisible: state['features/toolbox'].visible
|
||||||
|
|
|
@ -12,16 +12,19 @@ import {
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
declare var interfaceConfig: Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} props of {@link Toolbar}.
|
||||||
|
*/
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of buttons which should be visible in this toolbar.
|
* The set of buttons which should be visible in this {@code Toolbar}.
|
||||||
*/
|
*/
|
||||||
_visibleButtons: Set<string>
|
_visibleButtons: Set<string>
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the conference toolbar on React/Web for filmstrip only mode.
|
* Implements the conference toolbar on React/Web for filmstrip-only mode.
|
||||||
*
|
*
|
||||||
* @extends Component
|
* @extends Component
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,7 +17,7 @@ type Props = AbstractButtonProps & {
|
||||||
/**
|
/**
|
||||||
* Whether we are in filmstrip only mode or not.
|
* Whether we are in filmstrip only mode or not.
|
||||||
*/
|
*/
|
||||||
_filmStripOnly: boolean,
|
_filmstripOnly: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array containing the enabled settings sections.
|
* Array containing the enabled settings sections.
|
||||||
|
@ -46,10 +46,10 @@ class SettingsButton extends AbstractButton<Props, *> {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_handleClick() {
|
_handleClick() {
|
||||||
const { _filmStripOnly, _sections, dispatch } = this.props;
|
const { _filmstripOnly, _sections, dispatch } = this.props;
|
||||||
|
|
||||||
sendAnalytics(createToolbarEvent('settings'));
|
sendAnalytics(createToolbarEvent('settings'));
|
||||||
if (_filmStripOnly
|
if (_filmstripOnly
|
||||||
|| (_sections.length === 1 && _sections.includes('devices'))) {
|
|| (_sections.length === 1 && _sections.includes('devices'))) {
|
||||||
dispatch(openDeviceSelectionDialog());
|
dispatch(openDeviceSelectionDialog());
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,7 +76,7 @@ class SettingsButton extends AbstractButton<Props, *> {
|
||||||
* @param {Object} state - The Redux state.
|
* @param {Object} state - The Redux state.
|
||||||
* @private
|
* @private
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* _filmStripOnly: boolean
|
* _filmstripOnly: boolean
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state): Object { // eslint-disable-line no-unused-vars
|
function _mapStateToProps(state): Object { // eslint-disable-line no-unused-vars
|
||||||
|
@ -84,7 +84,7 @@ function _mapStateToProps(state): Object { // eslint-disable-line no-unused-vars
|
||||||
// interfaceConfig is part of redux we will.
|
// interfaceConfig is part of redux we will.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_filmStripOnly: Boolean(interfaceConfig.filmStripOnly),
|
_filmstripOnly: Boolean(interfaceConfig.filmStripOnly),
|
||||||
_sections: interfaceConfig.SETTINGS_SECTIONS || []
|
_sections: interfaceConfig.SETTINGS_SECTIONS || []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue