ref(AOT) Change buttons to not use abstract classes (#11302)
This reduces the bundle size by about 100KB It also decouples the AOT buttons from the classes that are used to implement other features
This commit is contained in:
parent
3443d256f2
commit
c2399deb55
|
@ -1,10 +1,14 @@
|
|||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
|
||||
import AbstractAudioMuteButton from '../base/toolbox/components/AbstractAudioMuteButton';
|
||||
import { IconMicrophoneEmpty, IconMicrophoneEmptySlash } from '../base/icons';
|
||||
import type { Props } from '../base/toolbox/components/AbstractButton';
|
||||
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
const { api } = window.alwaysOnTop;
|
||||
|
||||
/**
|
||||
|
@ -26,9 +30,9 @@ type State = {
|
|||
/**
|
||||
* Stateless "mute/unmute audio" button for the Always-on-Top windows.
|
||||
*/
|
||||
export default class AudioMuteButton
|
||||
extends AbstractAudioMuteButton<Props, State> {
|
||||
|
||||
export default class AudioMuteButton extends Component<Props, State> {
|
||||
icon = IconMicrophoneEmpty;
|
||||
toggledIcon = IconMicrophoneEmptySlash;
|
||||
accessibilityLabel = 'Audio mute';
|
||||
|
||||
/**
|
||||
|
@ -49,6 +53,7 @@ export default class AudioMuteButton
|
|||
this._audioAvailabilityListener
|
||||
= this._audioAvailabilityListener.bind(this);
|
||||
this._audioMutedListener = this._audioMutedListener.bind(this);
|
||||
this._onClick = this._onClick.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,4 +150,33 @@ export default class AudioMuteButton
|
|||
_setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
|
||||
this.state.audioAvailable && api.executeCommand('toggleAudio');
|
||||
}
|
||||
|
||||
_onClick: () => {};
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and toggles the audio mute state
|
||||
* accordingly.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClick() {
|
||||
this._setAudioMuted(!this._isAudioMuted());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const toggled = this._isAudioMuted();
|
||||
|
||||
return (<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { this._isDisabled() }
|
||||
icon = { toggled ? this.toggledIcon : this.icon }
|
||||
onClick = { this._onClick }
|
||||
toggled = { toggled } />);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,59 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
|
||||
import { IconHangup } from '../base/icons';
|
||||
import type { Props } from '../base/toolbox/components/AbstractButton';
|
||||
import AbstractHangupButton from '../base/toolbox/components/AbstractHangupButton';
|
||||
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
const { api } = window.alwaysOnTop;
|
||||
|
||||
/**
|
||||
* Stateless hangup button for the Always-on-Top windows.
|
||||
*/
|
||||
export default class HangupButton extends AbstractHangupButton<Props, *> {
|
||||
export default class HangupButton extends Component<Props, *> {
|
||||
|
||||
accessibilityLabel = 'Hangup';
|
||||
icon = IconHangup;
|
||||
|
||||
/**
|
||||
* Helper function to perform the actual hangup action.
|
||||
* Initializes a new {@code HangupButton} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* the new {@code HangupButton} instance with.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onClick = this._onClick.bind(this);
|
||||
}
|
||||
|
||||
_onClick: () => {};
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and disconnects the conference.
|
||||
*
|
||||
* @override
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_doHangup() {
|
||||
_onClick() {
|
||||
api.executeCommand('hangup');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
return (<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
customClass = 'hangup-button'
|
||||
icon = { this.icon }
|
||||
onClick = { this._onClick } />);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import React, { useCallback } from 'react';
|
||||
|
||||
import { Icon } from '../base/icons';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Accessibility label for button.
|
||||
*/
|
||||
accessibilityLabel: string,
|
||||
|
||||
/**
|
||||
* An extra class name to be added at the end of the element's class name
|
||||
* in order to enable custom styling.
|
||||
*/
|
||||
customClass?: string,
|
||||
|
||||
/**
|
||||
* Whether or not the button is disabled.
|
||||
*/
|
||||
disabled?: boolean,
|
||||
|
||||
/**
|
||||
* Click handler.
|
||||
*/
|
||||
onClick: Function,
|
||||
|
||||
/**
|
||||
* Button icon.
|
||||
*/
|
||||
icon: Object,
|
||||
|
||||
/**
|
||||
* Whether or not the button is toggled.
|
||||
*/
|
||||
toggled?: boolean
|
||||
}
|
||||
|
||||
const ToolbarButton = ({
|
||||
accessibilityLabel,
|
||||
customClass,
|
||||
disabled = false,
|
||||
onClick,
|
||||
icon,
|
||||
toggled = false
|
||||
}: Props) => {
|
||||
const onKeyPress = useCallback(event => {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
onClick();
|
||||
}
|
||||
}, [ onClick ]);
|
||||
|
||||
return (<div
|
||||
aria-disabled = { disabled }
|
||||
aria-label = { accessibilityLabel }
|
||||
aria-pressed = { toggled }
|
||||
className = { `toolbox-button ${disabled ? ' disabled' : ''}` }
|
||||
onClick = { disabled ? undefined : onClick }
|
||||
onKeyPress = { disabled ? undefined : onKeyPress }
|
||||
role = 'button'
|
||||
tabIndex = { 0 }>
|
||||
<div className = { `toolbox-icon ${disabled ? 'disabled' : ''} ${customClass ?? ''}` }>
|
||||
<Icon src = { icon } />
|
||||
</div>
|
||||
</div>);
|
||||
};
|
||||
|
||||
export default ToolbarButton;
|
|
@ -1,9 +1,12 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
|
||||
import { IconCameraEmpty, IconCameraEmptyDisabled } from '../base/icons';
|
||||
import type { Props } from '../base/toolbox/components/AbstractButton';
|
||||
import AbstractVideoMuteButton from '../base/toolbox/components/AbstractVideoMuteButton';
|
||||
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
const { api } = window.alwaysOnTop;
|
||||
|
||||
|
@ -26,9 +29,10 @@ type State = {
|
|||
/**
|
||||
* Stateless "mute/unmute video" button for the Always-on-Top windows.
|
||||
*/
|
||||
export default class VideoMuteButton
|
||||
extends AbstractVideoMuteButton<Props, State> {
|
||||
export default class VideoMuteButton extends Component<Props, State> {
|
||||
|
||||
icon = IconCameraEmpty;
|
||||
toggledIcon = IconCameraEmptyDisabled;
|
||||
accessibilityLabel = 'Video mute';
|
||||
|
||||
/**
|
||||
|
@ -49,6 +53,7 @@ export default class VideoMuteButton
|
|||
this._videoAvailabilityListener
|
||||
= this._videoAvailabilityListener.bind(this);
|
||||
this._videoMutedListener = this._videoMutedListener.bind(this);
|
||||
this._onClick = this._onClick.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,4 +150,34 @@ export default class VideoMuteButton
|
|||
_videoMutedListener({ muted }) {
|
||||
this.setState({ videoMuted: muted });
|
||||
}
|
||||
|
||||
_onClick: () => {};
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and toggles the video mute state
|
||||
* accordingly.
|
||||
*
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClick() {
|
||||
this._setVideoMuted(!this._isVideoMuted());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const toggled = this._isVideoMuted();
|
||||
|
||||
return (<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { this._isDisabled() }
|
||||
icon = { toggled ? this.toggledIcon : this.icon }
|
||||
onClick = { this._onClick }
|
||||
toggled = { toggled } />);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue