feat(title-bar) Update design (#12851)

Convert some files to TS
Move some styles from SCSS to JSS
Update design
This commit is contained in:
Robert Pintilii 2023-02-03 13:31:00 +02:00 committed by GitHub
parent a594aac078
commit 09e4696c60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 307 additions and 440 deletions

View File

@ -12,7 +12,6 @@
&#autoHide.with-always-on { &#autoHide.with-always-on {
overflow: hidden; overflow: hidden;
animation: hideSubject forwards .6s ease-out; animation: hideSubject forwards .6s ease-out;
margin-left: 4px;
& > .subject-info-container { & > .subject-info-container {
justify-content: flex-start; justify-content: flex-start;
@ -43,43 +42,6 @@
height: 28px; height: 28px;
} }
.subject-text {
background: rgba(0, 0, 0, 0.6);
border-radius: 3px 0px 0px 3px;
box-sizing: border-box;
font-size: 14px;
line-height: 28px;
padding: 0 16px;
height: 28px;
max-width: 324px;
@media (max-width: 300px) {
display: none;
}
&--content {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.subject-timer {
background: rgba(0, 0, 0, 0.8);
border-radius: 0px 3px 3px 0px;
box-sizing: border-box;
font-size: 12px;
line-height: 28px;
min-width: 34px;
padding: 0 8px;
height: 28px;
font-variant-numeric: tabular-nums;
@media (max-width: 300px) {
display: none;
}
}
.details-container { .details-container {
width: 100%; width: 100%;
display: flex; display: flex;

View File

@ -103,10 +103,6 @@
padding: 11px 16px; padding: 11px 16px;
} }
} }
input::placeholder {
color: #040404;
}
} }
#preview { #preview {

View File

@ -50,10 +50,10 @@ const useStyles = makeStyles()(theme => {
...withPixelLineHeight(theme.typography.labelRegular), ...withPixelLineHeight(theme.typography.labelRegular),
alignItems: 'center', alignItems: 'center',
background: theme.palette.ui04, background: theme.palette.ui04,
borderRadius: Number(theme.shape.borderRadius) / 2, borderRadius: '4px',
color: theme.palette.text01, color: theme.palette.text01,
display: 'flex', display: 'flex',
margin: '0 0 4px 4px', margin: '0 2px',
padding: '6px', padding: '6px',
height: 28, height: 28,
boxSizing: 'border-box' boxSizing: 'border-box'

View File

@ -1,7 +1,6 @@
// @flow import React, { PureComponent } from 'react';
import { PureComponent } from 'react';
import { IReduxState } from '../../app/types';
import isInsecureRoomName from '../../base/util/isInsecureRoomName'; import isInsecureRoomName from '../../base/util/isInsecureRoomName';
type Props = { type Props = {
@ -14,11 +13,11 @@ type Props = {
/** /**
* Function to be used to translate i18n labels. * Function to be used to translate i18n labels.
*/ */
t: Function t: Function;
} };
/** /**
* Abstrsact class for the {@Code InsecureRoomNameLabel} component. * Abstract class for the {@Code InsecureRoomNameLabel} component.
*/ */
export default class AbstractInsecureRoomNameLabel extends PureComponent<Props> { export default class AbstractInsecureRoomNameLabel extends PureComponent<Props> {
/** /**
@ -39,7 +38,9 @@ export default class AbstractInsecureRoomNameLabel extends PureComponent<Props>
* *
* @returns {ReactElement} * @returns {ReactElement}
*/ */
_render: () => Object; _render() {
return <></>;
}
} }
/** /**
@ -48,14 +49,14 @@ export default class AbstractInsecureRoomNameLabel extends PureComponent<Props>
* @param {Object} state - The Redux state. * @param {Object} state - The Redux state.
* @returns {Props} * @returns {Props}
*/ */
export function _mapStateToProps(state: Object): $Shape<Props> { export function _mapStateToProps(state: IReduxState) {
const { locked, room } = state['features/base/conference']; const { locked, room } = state['features/base/conference'];
const { lobbyEnabled } = state['features/lobby']; const { lobbyEnabled } = state['features/lobby'];
const { enableInsecureRoomNameWarning = false } = state['features/base/config']; const { enableInsecureRoomNameWarning = false } = state['features/base/config'];
return { return {
_visible: enableInsecureRoomNameWarning _visible: Boolean(enableInsecureRoomNameWarning
&& room && isInsecureRoomName(room) && room && isInsecureRoomName(room)
&& !(lobbyEnabled || Boolean(locked)) && !(lobbyEnabled || Boolean(locked)))
}; };
} }

View File

@ -1,180 +0,0 @@
// @flow
import { Component } from 'react';
import { renderConferenceTimer } from '../';
import { getConferenceTimestamp } from '../../base/conference/functions';
import { getLocalizedDurationFormatter } from '../../base/i18n';
import { connect } from '../../base/redux';
/**
* The type of the React {@code Component} props of {@link ConferenceTimer}.
*/
type Props = {
/**
* The UTC timestamp representing the time when first participant joined.
*/
_startTimestamp: ?number,
/**
* Style to be applied to the rendered text.
*/
textStyle: ?Object,
/**
* The redux {@code dispatch} function.
*/
dispatch: Function
};
/**
* The type of the React {@code Component} state of {@link ConferenceTimer}.
*/
type State = {
/**
* Value of current conference time.
*/
timerValue: string
};
/**
* ConferenceTimer react component.
*
* @class ConferenceTimer
* @augments Component
*/
class ConferenceTimer extends Component<Props, State> {
/**
* Handle for setInterval timer.
*/
_interval;
/**
* Initializes a new {@code ConferenceTimer} instance.
*
* @param {Props} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
this.state = {
timerValue: getLocalizedDurationFormatter(0)
};
}
/**
* Starts the conference timer when component will be
* mounted.
*
* @inheritdoc
*/
componentDidMount() {
this._startTimer();
}
/**
* Stops the conference timer when component will be
* unmounted.
*
* @inheritdoc
*/
componentWillUnmount() {
this._stopTimer();
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { timerValue } = this.state;
const { _startTimestamp, textStyle } = this.props;
if (!_startTimestamp) {
return null;
}
return renderConferenceTimer(timerValue, textStyle);
}
/**
* Sets the current state values that will be used to render the timer.
*
* @param {number} refValueUTC - The initial UTC timestamp value.
* @param {number} currentValueUTC - The current UTC timestamp value.
*
* @returns {void}
*/
_setStateFromUTC(refValueUTC, currentValueUTC) {
if (!refValueUTC || !currentValueUTC) {
return;
}
if (currentValueUTC < refValueUTC) {
return;
}
const timerMsValue = currentValueUTC - refValueUTC;
const localizedTime = getLocalizedDurationFormatter(timerMsValue);
this.setState({
timerValue: localizedTime
});
}
/**
* Start conference timer.
*
* @returns {void}
*/
_startTimer() {
if (!this._interval) {
this._setStateFromUTC(this.props._startTimestamp, new Date().getTime());
this._interval = setInterval(() => {
this._setStateFromUTC(this.props._startTimestamp, new Date().getTime());
}, 1000);
}
}
/**
* Stop conference timer.
*
* @returns {void}
*/
_stopTimer() {
if (this._interval) {
clearInterval(this._interval);
}
this.setState({
timerValue: getLocalizedDurationFormatter(0)
});
}
}
/**
* Maps (parts of) the Redux state to the associated
* {@code ConferenceTimer}'s props.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _startTimestamp: number
* }}
*/
export function _mapStateToProps(state: Object) {
return {
_startTimestamp: getConferenceTimestamp(state)
};
}
export default connect(_mapStateToProps)(ConferenceTimer);

View File

@ -0,0 +1,106 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
// @ts-ignore
import { ConferenceTimerDisplay } from '..';
import { getConferenceTimestamp } from '../../base/conference/functions';
import { getLocalizedDurationFormatter } from '../../base/i18n/dateUtil';
/**
* The type of the React {@code Component} props of {@link ConferenceTimer}.
*/
interface IProps {
/**
* Style to be applied to the rendered text.
*/
textStyle?: Object;
}
export interface IDisplayProps {
/**
* Style to be applied to text (native only).
*/
textStyle: Object;
/**
* String to display as time.
*/
timerValue: string;
}
const ConferenceTimer = ({ textStyle }: IProps) => {
const startTimestamp = useSelector(getConferenceTimestamp);
const [ timerValue, setTimerValue ] = useState(getLocalizedDurationFormatter(0));
const interval = useRef<number>();
/**
* Sets the current state values that will be used to render the timer.
*
* @param {number} refValueUTC - The initial UTC timestamp value.
* @param {number} currentValueUTC - The current UTC timestamp value.
*
* @returns {void}
*/
const setStateFromUTC = useCallback((refValueUTC, currentValueUTC) => {
if (!refValueUTC || !currentValueUTC) {
return;
}
if (currentValueUTC < refValueUTC) {
return;
}
const timerMsValue = currentValueUTC - refValueUTC;
const localizedTime = getLocalizedDurationFormatter(timerMsValue);
setTimerValue(localizedTime);
}, []);
/**
* Start conference timer.
*
* @returns {void}
*/
const startTimer = useCallback(() => {
if (!interval.current && startTimestamp) {
setStateFromUTC(startTimestamp, new Date().getTime());
interval.current = window.setInterval(() => {
setStateFromUTC(startTimestamp, new Date().getTime());
}, 1000);
}
}, [ startTimestamp, interval ]);
/**
* Stop conference timer.
*
* @returns {void}
*/
const stopTimer = useCallback(() => {
if (interval.current) {
clearInterval(interval.current);
}
setTimerValue(getLocalizedDurationFormatter(0));
}, [ interval ]);
useEffect(() => {
startTimer();
return () => stopTimer();
}, [ startTimestamp ]);
if (!startTimestamp) {
return null;
}
return (<ConferenceTimerDisplay
textStyle = { textStyle }
timerValue = { timerValue } />);
};
export default ConferenceTimer;

View File

@ -1,5 +1,5 @@
export const CONFERENCE_INFO = { export const CONFERENCE_INFO = {
alwaysVisible: [ 'recording', 'raised-hands-count' ], alwaysVisible: [ 'raised-hands-count', 'recording' ],
autoHide: [ autoHide: [
'highlight-moment', 'highlight-moment',
'subject', 'subject',

View File

@ -1,17 +1,16 @@
// @flow
import React from 'react'; import React from 'react';
import { Text } from 'react-native'; import { Text } from 'react-native';
import { IDisplayProps } from '../ConferenceTimer';
/** /**
* Returns native element to be rendered. * Returns native element to be rendered.
* *
* @param {string} timerValue - String to display as time. * @param {Object} props - Component props.
* @param {Object} textStyle - Style to be applied to the text.
* *
* @returns {ReactElement} * @returns {ReactElement}
*/ */
export default function renderConferenceTimer(timerValue: string, textStyle: Object) { export default function ConferenceTimerDisplay({ timerValue, textStyle }: IDisplayProps) {
return ( return (
<Text <Text
numberOfLines = { 1 } numberOfLines = { 1 }

View File

@ -1,5 +1,5 @@
// @flow // @flow
export { default as Conference } from './Conference'; export { default as Conference } from './Conference';
export { default as renderConferenceTimer } from './ConferenceTimerDisplay'; export { default as ConferenceTimerDisplay } from './ConferenceTimerDisplay';
export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel'; export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';

View File

@ -6,12 +6,12 @@ import React, { Component } from 'react';
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet'; import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
import { E2EELabel } from '../../../e2ee'; import E2EELabel from '../../../e2ee/components/E2EELabel';
import { RecordingLabel } from '../../../recording';
import HighlightButton from '../../../recording/components/Recording/web/HighlightButton'; import HighlightButton from '../../../recording/components/Recording/web/HighlightButton';
import RecordingLabel from '../../../recording/components/web/RecordingLabel';
import { isToolboxVisible } from '../../../toolbox/functions.web'; import { isToolboxVisible } from '../../../toolbox/functions.web';
import { TranscribingLabel } from '../../../transcribing'; import TranscribingLabel from '../../../transcribing/components/TranscribingLabel.web';
import { VideoQualityLabel } from '../../../video-quality'; import VideoQualityLabel from '../../../video-quality/components/VideoQualityLabel.web';
import ConferenceTimer from '../ConferenceTimer'; import ConferenceTimer from '../ConferenceTimer';
import { getConferenceInfo } from '../functions'; import { getConferenceInfo } from '../functions';

View File

@ -1,19 +0,0 @@
// @flow
/* eslint-disable no-unused-vars */
import React from 'react';
/**
* Returns web element to be rendered.
*
* @param {string} timerValue - String to display as time.
* @param {Object} textStyle - Unused on web.
*
* @returns {ReactElement}
*/
export default function renderConferenceTimer(timerValue: string, textStyle: Object) {
return (
<span className = 'subject-timer'>{ timerValue }</span>
);
}

View File

@ -0,0 +1,37 @@
import React from 'react';
import { makeStyles } from 'tss-react/mui';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
import { IDisplayProps } from '../ConferenceTimer';
const useStyles = makeStyles()(theme => {
return {
timer: {
...withPixelLineHeight(theme.typography.labelRegular),
color: theme.palette.text01,
padding: '6px 8px',
backgroundColor: 'rgba(0, 0, 0, 0.8)',
boxSizing: 'border-box',
height: '28px',
borderRadius: `0 ${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0`,
marginRight: '2px',
'@media (max-width: 300px)': {
display: 'none'
}
}
};
});
/**
* Returns web element to be rendered.
*
* @returns {ReactElement}
*/
export default function ConferenceTimerDisplay({ timerValue, textStyle: _textStyle }: IDisplayProps) {
const { classes } = useStyles();
return (
<span className = { classes.timer }>{ timerValue }</span>
);
}

View File

@ -1,13 +1,11 @@
// @flow
import Tooltip from '@atlaskit/tooltip'; import Tooltip from '@atlaskit/tooltip';
import React from 'react'; import React from 'react';
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n'; import { translate } from '../../../base/i18n/functions';
import { IconExclamationTriangle } from '../../../base/icons/svg'; import { IconExclamationTriangle } from '../../../base/icons/svg';
import { Label } from '../../../base/label'; import Label from '../../../base/label/components/web/Label';
import { COLORS } from '../../../base/label/constants'; import { COLORS } from '../../../base/label/constants';
import { connect } from '../../../base/redux';
import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel'; import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
/** /**

View File

@ -15,8 +15,7 @@ const useStyles = makeStyles()(theme => {
return { return {
label: { label: {
backgroundColor: theme.palette.warning02, backgroundColor: theme.palette.warning02,
color: theme.palette.uiBackground, color: theme.palette.uiBackground
marginRight: theme.spacing(1)
} }
}; };
}); });

View File

@ -1,50 +0,0 @@
/* @flow */
import React from 'react';
import { getConferenceName } from '../../../base/conference/functions';
import { connect } from '../../../base/redux';
import { Tooltip } from '../../../base/tooltip';
type Props = {
/**
* The conference display name.
*/
_subject: string
}
/**
* Label for the conference name.
*
* @param {Props} props - The props of the component.
* @returns {ReactElement}
*/
const SubjectText = ({ _subject }: Props) => (
<div className = 'subject-text'>
<Tooltip
content = { _subject }
position = 'bottom'>
<div className = 'subject-text--content'>{ _subject }</div>
</Tooltip>
</div>
);
/**
* Maps (parts of) the Redux state to the associated
* {@code Subject}'s props.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _subject: string,
* }}
*/
function _mapStateToProps(state) {
return {
_subject: getConferenceName(state)
};
}
export default connect(_mapStateToProps)(SubjectText);

View File

@ -0,0 +1,57 @@
import clsx from 'clsx';
import React from 'react';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { getConferenceName } from '../../../base/conference/functions';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { Tooltip } from '../../../base/tooltip';
const useStyles = makeStyles()(theme => {
return {
container: {
...withPixelLineHeight(theme.typography.bodyLongRegular),
color: theme.palette.text01,
padding: '2px 16px',
backgroundColor: 'rgba(0, 0, 0, 0.6)',
maxWidth: '324px',
boxSizing: 'border-box',
height: '28px',
borderRadius: `${theme.shape.borderRadius}px 0 0 ${theme.shape.borderRadius}px`,
marginLeft: '2px',
'@media (max-width: 300px)': {
display: 'none'
}
},
content: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}
};
});
/**
* Label for the conference name.
*
* @returns {ReactElement}
*/
const SubjectText = () => {
const subject = useSelector(getConferenceName);
const { classes } = useStyles();
return (
<div className = { classes.container }>
<Tooltip
content = { subject }
position = 'bottom'>
<div className = { clsx('subject-text--content', classes.content) }>{subject}</div>
</Tooltip>
</div>
);
};
export default SubjectText;

View File

@ -1,7 +1,7 @@
// @flow // @flow
export { default as Conference } from './Conference'; export { default as Conference } from './Conference';
export { default as renderConferenceTimer } from './ConferenceTimerDisplay'; export { default as ConferenceTimerDisplay } from './ConferenceTimerDisplay';
export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel'; export { default as InsecureRoomNameLabel } from './InsecureRoomNameLabel';
export { default as ConferenceInfo } from './ConferenceInfo'; export { default as ConferenceInfo } from './ConferenceInfo';
export { default as SubjectText } from './SubjectText'; export { default as SubjectText } from './SubjectText';

View File

@ -1,32 +1,28 @@
// @flow import { WithTranslation } from 'react-i18next';
import { IReduxState } from '../../app/types';
export type Props = { export interface IProps extends WithTranslation {
/** /**
* Custom e2ee labels. * Custom e2ee labels.
*/ */
_e2eeLabels?: Object; _e2eeLabels?: any;
/** /**
* True if the label needs to be rendered, false otherwise. * True if the label needs to be rendered, false otherwise.
*/ */
_showLabel: boolean, _showLabel?: boolean;
}
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/** /**
* Maps (parts of) the redux state to the associated props of this {@code Component}. * Maps (parts of) the redux state to the associated props of this {@code Component}.
* *
* @param {Object} state - The redux state. * @param {Object} state - The redux state.
* @private * @private
* @returns {Props} * @returns {IProps}
*/ */
export function _mapStateToProps(state: Object) { export function _mapStateToProps(state: IReduxState) {
const { e2ee = {} } = state['features/base/config']; const { e2ee = {} } = state['features/base/config'];
return { return {

View File

@ -1,47 +0,0 @@
// @flow
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
import { IconE2EE } from '../../base/icons';
import { Label } from '../../base/label';
import { COLORS } from '../../base/label/constants';
import { connect } from '../../base/redux';
import { Tooltip } from '../../base/tooltip';
import { type Props, _mapStateToProps } from './AbstractE2EELabel';
/**
* React {@code Component} for displaying a label when everyone has E2EE enabled in a conference.
*
* @augments Component
*/
class E2EELabel extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
if (!this.props._showLabel) {
return null;
}
const { _e2eeLabels, t } = this.props;
const content = _e2eeLabels?.labelToolTip || t('e2ee.labelToolTip');
return (
<Tooltip
content = { content }
position = { 'bottom' }>
<Label
color = { COLORS.green }
icon = { IconE2EE } />
</Tooltip>
);
}
}
export default translate(connect(_mapStateToProps)(E2EELabel));

View File

@ -0,0 +1,32 @@
import React from 'react';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n/functions';
import { IconE2EE } from '../../base/icons/svg';
import Label from '../../base/label/components/web/Label';
import { COLORS } from '../../base/label/constants';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { Tooltip } from '../../base/tooltip';
import { IProps, _mapStateToProps } from './AbstractE2EELabel';
const E2EELabel = ({ _e2eeLabels, _showLabel, t }: IProps) => {
if (!_showLabel) {
return null;
}
const content = _e2eeLabels?.labelToolTip || t('e2ee.labelToolTip');
return (
<Tooltip
content = { content }
position = { 'bottom' }>
<Label
color = { COLORS.green }
icon = { IconE2EE } />
</Tooltip>
);
};
export default translate(connect(_mapStateToProps)(E2EELabel));

View File

@ -60,12 +60,10 @@ const styles = (theme: Theme) => {
position: 'relative' position: 'relative'
}, },
disabled: { disabled: {
background: theme.palette.text02, background: theme.palette.text02
margin: '0 4px 4px 4px'
}, },
regular: { // @ts-ignore regular: { // @ts-ignore
background: theme.palette.field02, background: theme.palette.field02
margin: '0 4px 4px 4px'
}, },
highlightNotification: { // @ts-ignore highlightNotification: { // @ts-ignore
backgroundColor: theme.palette.field02, backgroundColor: theme.palette.field02,
@ -197,7 +195,6 @@ export class HighlightButton extends AbstractHighlightButton<Props, IState> {
// @ts-ignore // @ts-ignore
} = this.props; } = this.props;
if (!_visible) { if (!_visible) {
return null; return null;
} }

View File

@ -3,6 +3,7 @@ import { withStyles } from '@mui/styles';
import React from 'react'; import React from 'react';
import { translate } from '../../../base/i18n/functions'; import { translate } from '../../../base/i18n/functions';
import { IconRecord, IconSites } from '../../../base/icons/svg';
import Label from '../../../base/label/components/web/Label'; import Label from '../../../base/label/components/web/Label';
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet'; import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
import { connect } from '../../../base/redux/functions'; import { connect } from '../../../base/redux/functions';
@ -22,10 +23,10 @@ import AbstractRecordingLabel, {
const styles = (theme: Theme) => { const styles = (theme: Theme) => {
return { return {
[JitsiRecordingConstants.mode.STREAM]: { [JitsiRecordingConstants.mode.STREAM]: {
background: theme.palette.ui03 background: theme.palette.support07
}, },
[JitsiRecordingConstants.mode.FILE]: { [JitsiRecordingConstants.mode.FILE]: {
background: theme.palette.iconError background: theme.palette.actionDanger
} }
}; };
}; };
@ -51,15 +52,13 @@ class RecordingLabel extends AbstractRecordingLabel {
} }
// @ts-ignore // @ts-ignore
const { classes, mode, t } = this.props; const { classes, mode } = this.props;
return ( return (
<div> <div>
<Label <Label
className = { classes?.[mode] } className = { classes?.[mode] }
icon = { mode === JitsiRecordingConstants.mode.FILE ? IconRecord : IconSites } />
// @ts-ignore
text = { t(this._getLabelKey()) } />
</div> </div>
); );
} }

View File

@ -1,4 +1,4 @@
// @flow import { IReduxState } from '../../app/types';
/** /**
* The type of the React {@code Component} props of {@link TranscribingLabel}. * The type of the React {@code Component} props of {@link TranscribingLabel}.
@ -8,12 +8,12 @@ export type Props = {
/** /**
* True if the label needs to be rendered, false otherwise. * True if the label needs to be rendered, false otherwise.
*/ */
_showLabel: boolean, _showLabel: boolean;
/** /**
* Invoked to obtain translated strings. * Invoked to obtain translated strings.
*/ */
t: Function t: Function;
}; };
/** /**
@ -26,7 +26,7 @@ export type Props = {
* _showLabel: boolean * _showLabel: boolean
* }} * }}
*/ */
export function _mapStateToProps(state: Object) { export function _mapStateToProps(state: IReduxState) {
return { return {
_showLabel: state['features/transcribing'].isTranscribing _showLabel: state['features/transcribing'].isTranscribing
}; };

View File

@ -1,44 +0,0 @@
// @flow
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
import { Label } from '../../base/label';
import { connect } from '../../base/redux';
import { Tooltip } from '../../base/tooltip';
import { type Props, _mapStateToProps } from './AbstractTranscribingLabel';
/**
* React {@code Component} for displaying a label when a transcriber is in the
* conference.
*
* @augments Component
*/
class TranscribingLabel extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
if (!this.props._showLabel) {
return null;
}
return (
<Tooltip
content = { this.props.t('transcribing.labelToolTip') }
position = { 'left' }>
<Label
className = 'recording-label'
text = { this.props.t('transcribing.tr') } />
</Tooltip>
);
}
}
export default translate(connect(_mapStateToProps)(TranscribingLabel));

View File

@ -0,0 +1,28 @@
import React from 'react';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n/functions';
import Label from '../../base/label/components/web/Label';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { Tooltip } from '../../base/tooltip';
import { Props, _mapStateToProps } from './AbstractTranscribingLabel';
const TranscribingLabel = ({ _showLabel, t }: Props) => {
if (!_showLabel) {
return null;
}
return (
<Tooltip
content = { t('transcribing.labelToolTip') }
position = { 'left' }>
<Label
className = 'recording-label'
text = { t('transcribing.tr') } />
</Tooltip>
);
};
export default translate(connect(_mapStateToProps)(TranscribingLabel));