ref(styles) Change some withStyles to makeStyles (#12373)

Convert PreMeetingScreen to TS and transform it to function component
This commit is contained in:
Robert Pintilii 2022-10-17 12:28:04 +03:00 committed by GitHub
parent 1279c5b0da
commit 44c8b31187
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 199 deletions

View File

@ -9,7 +9,6 @@
font-size: 15px;
margin-left: auto;
margin-top: 16px;
width: auto;
}
&-code {

View File

@ -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;

View File

@ -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;

View File

@ -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 }>

View File

@ -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);

View File

@ -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;

View File

@ -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>
);