810deb907b
Move all Etherpad's access control from Meteor to a separated [Node application](https://github.com/bigbluebutton/bbb-pads). This new app uses [Etherpad's API](https://etherpad.org/doc/v1.8.4/#index_overview) to create groups and manage session tokens for users to access them. Each group represents one distinct pad at the html5 client. - Removed locked users' access to pads: replaced readOnly pad's access with a new pad's content sharing routine - Pad's access is now controlled by [Etherpad's API](https://etherpad.org/doc/v1.8.4/#index_overview) - Closed captions edited content now reflects at it's live feedback - Improved closed caption's dictation mode live feedback - Moved all Etherpad's API control from Meteor to a separated [app](https://github.com/bigbluebutton/bbb-pads) - Included access control both in akka-apps and bbb-pads
94 lines
1.9 KiB
JavaScript
94 lines
1.9 KiB
JavaScript
import React, { PureComponent } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import Service from '/imports/ui/components/captions/service';
|
|
|
|
const CAPTIONS_CONFIG = Meteor.settings.public.captions;
|
|
|
|
class LiveCaptions extends PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.state = { clear: true };
|
|
this.timer = null;
|
|
this.settings = Service.getCaptionsSettings();
|
|
}
|
|
|
|
componentDidUpdate(prevProps) {
|
|
const { clear } = this.state;
|
|
|
|
if (clear) {
|
|
const { data } = this.props;
|
|
if (prevProps.data !== data) {
|
|
// eslint-disable-next-line react/no-did-update-set-state
|
|
this.setState({ clear: false });
|
|
}
|
|
} else {
|
|
this.resetTimer();
|
|
this.timer = setTimeout(() => this.setState({ clear: true }), CAPTIONS_CONFIG.time);
|
|
}
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.resetTimer();
|
|
}
|
|
|
|
resetTimer() {
|
|
if (this.timer) {
|
|
clearTimeout(this.timer);
|
|
this.timer = null;
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const { data } = this.props;
|
|
const { clear } = this.state;
|
|
const {
|
|
fontFamily,
|
|
fontSize,
|
|
fontColor,
|
|
backgroundColor,
|
|
} = this.settings;
|
|
|
|
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}>
|
|
{clear ? '' : data}
|
|
</div>
|
|
<div
|
|
style={visuallyHidden}
|
|
aria-atomic
|
|
aria-live="polite"
|
|
>
|
|
{clear ? '' : data}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
LiveCaptions.propTypes = {
|
|
data: PropTypes.string.isRequired,
|
|
};
|
|
|
|
export default LiveCaptions;
|