2019-05-17 04:11:10 +08:00
|
|
|
|
import React from 'react';
|
|
|
|
|
import PropTypes from 'prop-types';
|
2019-05-21 00:43:31 +08:00
|
|
|
|
import CaptionsService from './service';
|
2019-05-17 04:11:10 +08:00
|
|
|
|
|
|
|
|
|
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 = '';
|
2019-05-21 00:43:31 +08:00
|
|
|
|
this.timer = null;
|
|
|
|
|
this.settings = CaptionsService.getCaptionsSettings();
|
2019-05-17 04:11:10 +08:00
|
|
|
|
|
|
|
|
|
this.updateText = this.updateText.bind(this);
|
2019-05-21 00:43:31 +08:00
|
|
|
|
this.resetTimer = this.resetTimer.bind(this);
|
2019-05-17 04:11:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
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 {
|
|
|
|
|
padId,
|
|
|
|
|
revs,
|
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
|
|
if (padId === nextProps.padId) {
|
|
|
|
|
if (revs === nextProps.revs && !nextState.clear) return false;
|
2019-05-17 04:11:10 +08:00
|
|
|
|
}
|
|
|
|
|
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 you’ll 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();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 04:11:10 +08:00
|
|
|
|
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 = '';
|
2019-05-21 00:43:31 +08:00
|
|
|
|
} else {
|
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;
|
|
|
|
|
}
|
2019-05-17 04:11:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2019-05-17 04:11:10 +08:00
|
|
|
|
const {
|
|
|
|
|
fontFamily,
|
|
|
|
|
fontSize,
|
|
|
|
|
fontColor,
|
|
|
|
|
backgroundColor,
|
2019-05-21 00:43:31 +08:00
|
|
|
|
} = this.settings;
|
2019-05-17 04:11:10 +08:00
|
|
|
|
|
2019-05-23 22:51:01 +08:00
|
|
|
|
if (!initial) {
|
2019-05-21 00:43:31 +08:00
|
|
|
|
this.updateText(data);
|
2019-05-17 04:11:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const captionStyles = {
|
|
|
|
|
whiteSpace: 'pre-wrap',
|
|
|
|
|
wordWrap: 'break-word',
|
|
|
|
|
fontFamily,
|
|
|
|
|
fontSize,
|
|
|
|
|
background: backgroundColor,
|
|
|
|
|
color: fontColor,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<span
|
|
|
|
|
style={captionStyles}
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: this.text }}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default Captions;
|
|
|
|
|
|
|
|
|
|
Captions.propTypes = {
|
2019-05-21 00:43:31 +08:00
|
|
|
|
padId: PropTypes.string.isRequired,
|
|
|
|
|
revs: PropTypes.number.isRequired,
|
|
|
|
|
data: PropTypes.string.isRequired,
|
2019-05-17 04:11:10 +08:00
|
|
|
|
};
|