bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/captions/component.jsx

131 lines
2.8 KiB
React
Raw Normal View History

import React from 'react';
import PropTypes from 'prop-types';
2019-05-21 00:43:31 +08:00
import CaptionsService from './service';
const CAPTIONS_CONFIG = Meteor.settings.public.captions;
class Captions extends React.Component {
constructor(props) {
super(props);
2019-05-18 04:53:59 +08:00
this.state = { initial: true };
2019-05-29 22:31:27 +08:00
this.text = '';
this.ariaText = '';
2019-05-21 00:43:31 +08:00
this.timer = null;
this.settings = CaptionsService.getCaptionsSettings();
this.updateText = this.updateText.bind(this);
2019-05-21 00:43:31 +08:00
this.resetTimer = this.resetTimer.bind(this);
}
2019-05-23 22:51:01 +08:00
componentDidMount() {
this.setState({ initial: false });
}
2019-05-18 04:53:59 +08:00
shouldComponentUpdate(nextProps, nextState) {
2019-05-21 00:43:31 +08:00
const {
locale,
2019-05-21 00:43:31 +08:00
revs,
} = this.props;
if (locale === nextProps.locale) {
2019-05-21 00:43:31 +08:00
if (revs === nextProps.revs && !nextState.clear) return false;
}
return true;
}
2019-05-29 22:31:27 +08:00
componentDidUpdate() {
/* https://reactjs.org/docs/react-component.html#componentdidupdate
You may call setState() immediately in componentDidUpdate()
but note that it must be wrapped in a condition (...),
or youll cause an infinite loop. */
2019-05-23 22:51:01 +08:00
const { clear } = this.state;
if (clear) {
2019-05-21 00:43:31 +08:00
this.setState({ clear: false });
} else {
this.resetTimer();
this.timer = setTimeout(() => { this.setState({ clear: true }); }, CAPTIONS_CONFIG.time);
}
}
2019-05-23 22:51:01 +08:00
componentWillUnmount() {
this.resetTimer();
}
updateText(data) {
2019-05-23 22:51:01 +08:00
const { clear } = this.state;
if (clear) {
2019-05-29 22:31:27 +08:00
this.text = '';
this.ariaText = '';
2019-05-21 00:43:31 +08:00
} else {
this.ariaText = CaptionsService.formatCaptionsText(data);
2019-05-21 01:39:04 +08:00
const text = this.text + data;
this.text = CaptionsService.formatCaptionsText(text);
2019-05-21 00:43:31 +08:00
}
}
resetTimer() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
render() {
2019-05-21 00:43:31 +08:00
const { data } = this.props;
2019-05-23 22:51:01 +08:00
const { initial } = this.state;
const {
fontFamily,
fontSize,
fontColor,
backgroundColor,
2019-05-21 00:43:31 +08:00
} = this.settings;
2019-05-23 22:51:01 +08:00
if (!initial) {
2019-05-21 00:43:31 +08:00
this.updateText(data);
}
const captionStyles = {
whiteSpace: 'pre-wrap',
wordWrap: 'break-word',
fontFamily,
fontSize,
background: backgroundColor,
color: fontColor,
};
const visuallyHidden = {
position: 'absolute',
overflow: 'hidden',
clip: 'rect(0 0 0 0)',
height: '1px',
width: '1px',
margin: '-1px',
padding: '0',
border: '0',
};
return (
<div>
<div style={captionStyles}>
{this.text}
</div>
<div
style={visuallyHidden}
aria-atomic
aria-live="polite"
>
{this.ariaText}
</div>
</div>
);
}
}
export default Captions;
Captions.propTypes = {
locale: PropTypes.string.isRequired,
2019-05-21 00:43:31 +08:00
revs: PropTypes.number.isRequired,
data: PropTypes.string.isRequired,
};