ref(styles) Change some withStyles to makeStyles (#12373)
Convert PreMeetingScreen to TS and transform it to function component
This commit is contained in:
parent
1279c5b0da
commit
44c8b31187
|
@ -9,7 +9,6 @@
|
|||
font-size: 15px;
|
||||
margin-left: auto;
|
||||
margin-top: 16px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&-code {
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
/* eslint-disable react/jsx-no-bind */
|
||||
import { Theme } from '@mui/material';
|
||||
import { withStyles } from '@mui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import Icon from '../icons/components/Icon';
|
||||
import { IconCheck, IconCopy } from '../icons/svg';
|
||||
import { withPixelLineHeight } from '../styles/functions.web';
|
||||
import { copyText } from '../util/copyText.web';
|
||||
|
||||
const styles = (theme: Theme) => {
|
||||
const useStyles = makeStyles()((theme: Theme) => {
|
||||
return {
|
||||
copyButton: {
|
||||
...withPixelLineHeight(theme.typography.bodyLongRegular),
|
||||
|
@ -50,7 +49,7 @@ const styles = (theme: Theme) => {
|
|||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
let mounted: boolean;
|
||||
|
||||
|
@ -61,11 +60,6 @@ type Props = {
|
|||
*/
|
||||
className: string;
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: any;
|
||||
|
||||
/**
|
||||
* The displayed text.
|
||||
*/
|
||||
|
@ -97,7 +91,8 @@ type Props = {
|
|||
*
|
||||
* @returns {React$Element<any>}
|
||||
*/
|
||||
function CopyButton({ classes, className, displayedText, textToCopy, textOnHover, textOnCopySuccess, id }: Props) {
|
||||
function CopyButton({ className = '', displayedText, textToCopy, textOnHover, textOnCopySuccess, id }: Props) {
|
||||
const { classes, cx } = useStyles();
|
||||
const [ isClicked, setIsClicked ] = useState(false);
|
||||
const [ isHovered, setIsHovered ] = useState(false);
|
||||
|
||||
|
@ -174,7 +169,7 @@ function CopyButton({ classes, className, displayedText, textToCopy, textOnHover
|
|||
if (isClicked) {
|
||||
return (
|
||||
<>
|
||||
<div className = { clsx(classes.content, 'selected') }>
|
||||
<div className = { cx(classes.content, 'selected') }>
|
||||
<span role = { 'alert' }>{ textOnCopySuccess }</span>
|
||||
</div>
|
||||
<Icon src = { IconCheck } />
|
||||
|
@ -184,7 +179,7 @@ function CopyButton({ classes, className, displayedText, textToCopy, textOnHover
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className = { clsx(classes.content) }>
|
||||
<div className = { classes.content }>
|
||||
<span> { isHovered ? textOnHover : displayedText } </span>
|
||||
</div>
|
||||
<Icon src = { IconCopy } />
|
||||
|
@ -195,7 +190,7 @@ function CopyButton({ classes, className, displayedText, textToCopy, textOnHover
|
|||
return (
|
||||
<div
|
||||
aria-label = { textOnHover }
|
||||
className = { clsx(className, classes.copyButton, isClicked ? ' clicked' : '') }
|
||||
className = { cx(className, classes.copyButton, isClicked ? ' clicked' : '') }
|
||||
id = { id }
|
||||
onBlur = { onHoverOut }
|
||||
onClick = { onClick }
|
||||
|
@ -210,8 +205,4 @@ function CopyButton({ classes, className, displayedText, textToCopy, textOnHover
|
|||
);
|
||||
}
|
||||
|
||||
CopyButton.defaultProps = {
|
||||
className: ''
|
||||
};
|
||||
|
||||
export default withStyles(styles)(CopyButton);
|
||||
export default CopyButton;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Theme } from '@mui/material';
|
||||
import { withStyles } from '@mui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { ReactNode, useCallback } from 'react';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import { IconArrowDown } from '../../../icons/svg';
|
||||
|
@ -39,11 +38,6 @@ type Props = {
|
|||
*/
|
||||
className?: string;
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: any;
|
||||
|
||||
/**
|
||||
* If the button is disabled or not.
|
||||
*/
|
||||
|
@ -86,14 +80,7 @@ type Props = {
|
|||
type: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the styles for the component.
|
||||
*
|
||||
* @param {Object} theme - The current UI theme.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
const styles = (theme: Theme) => {
|
||||
const useStyles = makeStyles()((theme: Theme) => {
|
||||
return {
|
||||
actionButton: {
|
||||
...withPixelLineHeight(theme.typography.bodyLongBold),
|
||||
|
@ -174,7 +161,7 @@ const styles = (theme: Theme) => {
|
|||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Button used for pre meeting actions.
|
||||
|
@ -183,7 +170,6 @@ const styles = (theme: Theme) => {
|
|||
*/
|
||||
function ActionButton({
|
||||
children,
|
||||
classes,
|
||||
className = '',
|
||||
disabled,
|
||||
hasOptions,
|
||||
|
@ -198,6 +184,7 @@ function ActionButton({
|
|||
ariaLabel,
|
||||
ariaDropDownLabel
|
||||
}: Props) {
|
||||
const { classes, cx } = useStyles();
|
||||
|
||||
const onKeyPressHandler = useCallback(e => {
|
||||
if (onClick && !disabled && (e.key === ' ' || e.key === 'Enter')) {
|
||||
|
@ -214,7 +201,7 @@ function ActionButton({
|
|||
}
|
||||
}, [ onOptionsClick, disabled ]);
|
||||
|
||||
const containerClasses = clsx(
|
||||
const containerClasses = cx(
|
||||
classes.actionButton,
|
||||
className && className,
|
||||
type,
|
||||
|
@ -233,25 +220,25 @@ function ActionButton({
|
|||
tabIndex = { 0 } >
|
||||
{children}
|
||||
{ hasOptions
|
||||
&& <div
|
||||
aria-disabled = { disabled }
|
||||
aria-haspopup = 'true'
|
||||
aria-label = { ariaDropDownLabel }
|
||||
aria-pressed = { ariaPressed }
|
||||
className = { classes.options }
|
||||
data-testid = 'prejoin.joinOptions'
|
||||
onClick = { disabled ? undefined : onOptionsClick }
|
||||
onKeyPress = { onOptionsKeyPressHandler }
|
||||
role = { role }
|
||||
tabIndex = { tabIndex }>
|
||||
<Icon
|
||||
className = 'icon'
|
||||
size = { 14 }
|
||||
src = { OptionsIcon } />
|
||||
</div>
|
||||
&& <div
|
||||
aria-disabled = { disabled }
|
||||
aria-haspopup = 'true'
|
||||
aria-label = { ariaDropDownLabel }
|
||||
aria-pressed = { ariaPressed }
|
||||
className = { classes.options }
|
||||
data-testid = 'prejoin.joinOptions'
|
||||
onClick = { disabled ? undefined : onOptionsClick }
|
||||
onKeyPress = { onOptionsKeyPressHandler }
|
||||
role = { role }
|
||||
tabIndex = { tabIndex }>
|
||||
<Icon
|
||||
className = 'icon'
|
||||
size = { 14 }
|
||||
src = { OptionsIcon } />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withStyles(styles)(ActionButton);
|
||||
export default ActionButton;
|
||||
|
|
|
@ -17,12 +17,12 @@ interface Props extends WithTranslation {
|
|||
/**
|
||||
* List of strings with details about the connection.
|
||||
*/
|
||||
connectionDetails: string[];
|
||||
connectionDetails?: string[];
|
||||
|
||||
/**
|
||||
* The type of the connection. Can be: 'none', 'poor', 'nonOptimal' or 'good'.
|
||||
*/
|
||||
connectionType: string;
|
||||
connectionType?: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles()((theme: Theme) => {
|
||||
|
@ -155,7 +155,7 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
|
|||
const arrowClassName = showDetails
|
||||
? 'con-status-arrow con-status-arrow--up'
|
||||
: 'con-status-arrow';
|
||||
const detailsText = connectionDetails.map(d => t(d)).join(' ');
|
||||
const detailsText = connectionDetails?.map(d => t(d)).join(' ');
|
||||
const detailsClassName = showDetails
|
||||
? 'con-status-details-visible'
|
||||
: 'con-status-details-hidden';
|
||||
|
@ -176,7 +176,7 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { connectionClass, icon, connectionText } = CONNECTION_TYPE_MAP[connectionType];
|
||||
const { connectionClass, icon, connectionText } = CONNECTION_TYPE_MAP[connectionType ?? ''];
|
||||
|
||||
return (
|
||||
<div className = { classes.connectionStatus }>
|
||||
|
|
|
@ -1,100 +1,91 @@
|
|||
// @flow
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { Theme } from '@mui/material';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import { withStyles } from '@mui/styles';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { IState } from '../../../../app/types';
|
||||
import DeviceStatus from '../../../../prejoin/components/preview/DeviceStatus';
|
||||
// @ts-ignore
|
||||
import { Toolbox } from '../../../../toolbox/components/web';
|
||||
import { getConferenceName } from '../../../conference/functions';
|
||||
import { PREMEETING_BUTTONS, THIRD_PARTY_PREJOIN_BUTTONS } from '../../../config/constants';
|
||||
import { getToolbarButtons, isToolbarButtonEnabled } from '../../../config/functions.web';
|
||||
import { connect } from '../../../redux/functions';
|
||||
import { withPixelLineHeight } from '../../../styles/functions.web';
|
||||
|
||||
import ConnectionStatus from './ConnectionStatus';
|
||||
// @ts-ignore
|
||||
import Preview from './Preview';
|
||||
|
||||
type Props = {
|
||||
interface Props {
|
||||
|
||||
/**
|
||||
* The list of toolbar buttons to render.
|
||||
*/
|
||||
_buttons: Array<string>,
|
||||
_buttons: Array<string>;
|
||||
|
||||
/**
|
||||
* The branding background of the premeeting screen(lobby/prejoin).
|
||||
*/
|
||||
_premeetingBackground: string,
|
||||
_premeetingBackground: string;
|
||||
|
||||
/**
|
||||
* The name of the meeting that is about to be joined.
|
||||
*/
|
||||
_roomName: string,
|
||||
_roomName: string;
|
||||
|
||||
/**
|
||||
* Children component(s) to be rendered on the screen.
|
||||
*/
|
||||
children?: React$Node,
|
||||
|
||||
/**
|
||||
* Classes prop injected by withStyles.
|
||||
*/
|
||||
classes: Object,
|
||||
children?: ReactNode;
|
||||
|
||||
/**
|
||||
* Additional CSS class names to set on the icon container.
|
||||
*/
|
||||
className?: string,
|
||||
className?: string;
|
||||
|
||||
/**
|
||||
* The name of the participant.
|
||||
*/
|
||||
name?: string,
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Indicates whether the copy url button should be shown.
|
||||
*/
|
||||
showCopyUrlButton: boolean,
|
||||
showCopyUrlButton: boolean;
|
||||
|
||||
/**
|
||||
* Indicates whether the device status should be shown.
|
||||
*/
|
||||
showDeviceStatus: boolean,
|
||||
showDeviceStatus: boolean;
|
||||
|
||||
/**
|
||||
* The 'Skip prejoin' button to be rendered (if any).
|
||||
*/
|
||||
skipPrejoinButton?: React$Node,
|
||||
|
||||
/**
|
||||
* Title of the screen.
|
||||
*/
|
||||
title?: string,
|
||||
skipPrejoinButton?: ReactNode;
|
||||
|
||||
/**
|
||||
* Whether it's used in the 3rdParty prejoin screen or not.
|
||||
*/
|
||||
thirdParty?: boolean,
|
||||
thirdParty?: boolean;
|
||||
|
||||
/**
|
||||
* Title of the screen.
|
||||
*/
|
||||
title?: string;
|
||||
|
||||
/**
|
||||
* True if the preview overlay should be muted, false otherwise.
|
||||
*/
|
||||
videoMuted?: boolean,
|
||||
videoMuted?: boolean;
|
||||
|
||||
/**
|
||||
* The video track to render as preview (if omitted, the default local track will be rendered).
|
||||
*/
|
||||
videoTrack?: Object
|
||||
videoTrack?: Object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the styles for the component.
|
||||
*
|
||||
* @param {Object} theme - The current UI theme.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
const styles = theme => {
|
||||
const useStyles = makeStyles()((theme: Theme) => {
|
||||
return {
|
||||
subtitle: {
|
||||
...withPixelLineHeight(theme.typography.heading5),
|
||||
|
@ -107,79 +98,56 @@ const styles = theme => {
|
|||
width: '100%'
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Implements a pre-meeting screen that can be used at various pre-meeting phases, for example
|
||||
* on the prejoin screen (pre-connection) or lobby (post-connection).
|
||||
*/
|
||||
class PreMeetingScreen extends PureComponent<Props> {
|
||||
/**
|
||||
* Default values for {@code Prejoin} component's properties.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static defaultProps = {
|
||||
showCopyUrlButton: true,
|
||||
showToolbox: true
|
||||
};
|
||||
const PreMeetingScreen = ({
|
||||
_buttons,
|
||||
_premeetingBackground,
|
||||
_roomName,
|
||||
children,
|
||||
className,
|
||||
showDeviceStatus,
|
||||
skipPrejoinButton,
|
||||
title,
|
||||
videoMuted,
|
||||
videoTrack
|
||||
}: Props) => {
|
||||
const { classes } = useStyles();
|
||||
const containerClassName = `premeeting-screen ${className ? className : ''}`;
|
||||
const style = _premeetingBackground ? {
|
||||
background: _premeetingBackground,
|
||||
backgroundPosition: 'center',
|
||||
backgroundSize: 'cover'
|
||||
} : {};
|
||||
|
||||
/**
|
||||
* Implements {@code PureComponent#render}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const {
|
||||
_buttons,
|
||||
_premeetingBackground,
|
||||
_roomName,
|
||||
children,
|
||||
classes,
|
||||
className,
|
||||
showDeviceStatus,
|
||||
skipPrejoinButton,
|
||||
title,
|
||||
videoMuted,
|
||||
videoTrack
|
||||
} = this.props;
|
||||
return (
|
||||
<div className = { containerClassName }>
|
||||
<div style = { style }>
|
||||
<div className = 'content'>
|
||||
<ConnectionStatus />
|
||||
|
||||
const containerClassName = `premeeting-screen ${className ? className : ''}`;
|
||||
const style = _premeetingBackground ? {
|
||||
background: _premeetingBackground,
|
||||
backgroundPosition: 'center',
|
||||
backgroundSize: 'cover'
|
||||
} : {};
|
||||
|
||||
return (
|
||||
<div className = { containerClassName }>
|
||||
<div style = { style }>
|
||||
<div className = 'content'>
|
||||
<ConnectionStatus />
|
||||
|
||||
<div className = 'content-controls'>
|
||||
<h1 className = 'title'>
|
||||
{ title }
|
||||
</h1>
|
||||
{ _roomName && (
|
||||
<span className = { classes.subtitle }>
|
||||
{_roomName}
|
||||
</span>
|
||||
)}
|
||||
{ children }
|
||||
{ _buttons.length && <Toolbox toolbarButtons = { _buttons } /> }
|
||||
{ skipPrejoinButton }
|
||||
{ showDeviceStatus && <DeviceStatus /> }
|
||||
</div>
|
||||
<div className = 'content-controls'>
|
||||
<h1 className = 'title'>
|
||||
{title}
|
||||
</h1>
|
||||
{_roomName && (
|
||||
<span className = { classes.subtitle }>
|
||||
{_roomName}
|
||||
</span>
|
||||
)}
|
||||
{children}
|
||||
{_buttons.length && <Toolbox toolbarButtons = { _buttons } />}
|
||||
{skipPrejoinButton}
|
||||
{showDeviceStatus && <DeviceStatus />}
|
||||
</div>
|
||||
</div>
|
||||
<Preview
|
||||
videoMuted = { videoMuted }
|
||||
videoTrack = { videoTrack } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
<Preview
|
||||
videoMuted = { videoMuted }
|
||||
videoTrack = { videoTrack } />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -189,12 +157,12 @@ class PreMeetingScreen extends PureComponent<Props> {
|
|||
* @param {Object} ownProps - The props passed to the component.
|
||||
* @returns {Object}
|
||||
*/
|
||||
function mapStateToProps(state, ownProps): Object {
|
||||
function mapStateToProps(state: IState, ownProps: Partial<Props>) {
|
||||
const { hiddenPremeetingButtons, hideConferenceSubject } = state['features/base/config'];
|
||||
const toolbarButtons = getToolbarButtons(state);
|
||||
const premeetingButtons = (ownProps.thirdParty
|
||||
? THIRD_PARTY_PREJOIN_BUTTONS
|
||||
: PREMEETING_BUTTONS).filter(b => !(hiddenPremeetingButtons || []).includes(b));
|
||||
: PREMEETING_BUTTONS).filter((b: any) => !(hiddenPremeetingButtons || []).includes(b));
|
||||
|
||||
const { premeetingBackground } = state['features/dynamic-branding'];
|
||||
|
||||
|
@ -212,4 +180,4 @@ function mapStateToProps(state, ownProps): Object {
|
|||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(PreMeetingScreen));
|
||||
export default connect(mapStateToProps)(PreMeetingScreen);
|
|
@ -1,16 +1,11 @@
|
|||
import { Theme } from '@mui/material';
|
||||
import { withStyles } from '@mui/styles';
|
||||
import React from 'react';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import Icon from '../../base/icons/components/Icon';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The css classes generated from theme.
|
||||
*/
|
||||
classes: any;
|
||||
|
||||
/**
|
||||
* Attribute used in automated testing.
|
||||
*/
|
||||
|
@ -37,14 +32,8 @@ type Props = {
|
|||
onKeyPressed: (e?: React.KeyboardEvent) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the styles for the component.
|
||||
*
|
||||
* @param {Object} theme - The current UI theme.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
const styles = (theme: Theme) => {
|
||||
|
||||
const useStyles = makeStyles()((theme: Theme) => {
|
||||
return {
|
||||
prejoinPreviewDropdownBtn: {
|
||||
alignItems: 'center',
|
||||
|
@ -70,7 +59,7 @@ const styles = (theme: Theme) => {
|
|||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Buttons used for pre meeting actions.
|
||||
|
@ -78,26 +67,30 @@ const styles = (theme: Theme) => {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
const DropdownButton = ({
|
||||
classes,
|
||||
dataTestId,
|
||||
icon,
|
||||
onButtonClick,
|
||||
onKeyPressed,
|
||||
label
|
||||
}: Props) => (
|
||||
<div
|
||||
className = { classes.prejoinPreviewDropdownBtn }
|
||||
data-testid = { dataTestId }
|
||||
onClick = { onButtonClick }
|
||||
onKeyPress = { onKeyPressed }
|
||||
role = 'button'
|
||||
tabIndex = { 0 }>
|
||||
<Icon
|
||||
className = { classes.prejoinPreviewDropdownIcon }
|
||||
size = { 24 }
|
||||
src = { icon } />
|
||||
{label}
|
||||
</div>
|
||||
);
|
||||
}: Props) => {
|
||||
const { classes } = useStyles();
|
||||
|
||||
export default withStyles(styles)(DropdownButton);
|
||||
return (
|
||||
<div
|
||||
className = { classes.prejoinPreviewDropdownBtn }
|
||||
data-testid = { dataTestId }
|
||||
onClick = { onButtonClick }
|
||||
onKeyPress = { onKeyPressed }
|
||||
role = 'button'
|
||||
tabIndex = { 0 }>
|
||||
<Icon
|
||||
className = { classes.prejoinPreviewDropdownIcon }
|
||||
color = '#1C2025'
|
||||
size = { 24 }
|
||||
src = { icon } />
|
||||
{label}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DropdownButton;
|
||||
|
|
|
@ -18,13 +18,13 @@ export interface Props extends WithTranslation {
|
|||
/**
|
||||
* The text to be displayed in relation to the status of the audio/video devices.
|
||||
*/
|
||||
deviceStatusText: string;
|
||||
deviceStatusText?: string;
|
||||
|
||||
/**
|
||||
* The type of status for current devices, controlling the background color of the text.
|
||||
* Can be `ok` or `warning`.
|
||||
*/
|
||||
deviceStatusType: string;
|
||||
deviceStatusType?: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles()((theme: Theme) => {
|
||||
|
@ -97,7 +97,7 @@ function DeviceStatus({ deviceStatusType, deviceStatusText, t }: Props) {
|
|||
size = { 16 }
|
||||
src = { src } />
|
||||
<span role = 'heading'>
|
||||
{hasError ? t('prejoin.errorNoPermissions') : t(deviceStatusText)}
|
||||
{hasError ? t('prejoin.errorNoPermissions') : t(deviceStatusText ?? '')}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue