@bbc/react-transcript-editor
Version:
A React component to make transcribing audio and video easier and faster.
286 lines (255 loc) • 9.51 kB
JavaScript
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCog, faKeyboard } from '@fortawesome/free-solid-svg-icons';
import TimedTextEditor from './TimedTextEditor';
import MediaPlayer from './MediaPlayer';
import Settings from './Settings';
import Shortcuts from './Settings/Shortcuts';
import { secondsToTimecode } from '../Util/timecode-converter/index';
import style from './index.module.css';
class TranscriptEditor extends React.Component {
constructor(props) {
super(props);
_defineProperty(this, "handleWordClick", startTime => {
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'doubleClickOnWord',
name: 'startTime',
value: secondsToTimecode(startTime)
});
}
this.setCurrentTime(startTime);
});
_defineProperty(this, "handleTimeUpdate", currentTime => {
this.setState({
currentTime
});
});
_defineProperty(this, "handlePlayMedia", bool => {
this.playMedia(bool);
});
_defineProperty(this, "handleIsPlaying", () => {
return this.isPlaying();
});
_defineProperty(this, "handleIsScrollIntoViewChange", e => {
const isChecked = e.target.checked;
this.setState({
isScrollIntoViewOn: isChecked
});
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handleIsScrollIntoViewChange',
name: 'isScrollIntoViewOn',
value: isChecked
});
}
});
_defineProperty(this, "handlePauseWhileTyping", e => {
const isChecked = e.target.checked;
this.setState({
isPauseWhileTypingOn: isChecked
});
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handlePauseWhileTyping',
name: 'isPauseWhileTypingOn',
value: isChecked
});
}
});
_defineProperty(this, "handleRollBackValueInSeconds", e => {
const rollBackValue = e.target.value;
this.setState({
rollBackValueInSeconds: rollBackValue
});
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handleRollBackValueInSeconds',
name: 'rollBackValueInSeconds',
value: rollBackValue
});
}
});
_defineProperty(this, "handleSetTimecodeOffset", timecodeOffset => {
this.setState({
timecodeOffset: timecodeOffset
}, () => {
// eslint-disable-next-line react/no-string-refs
this.refs.timedTextEditor.forceUpdate();
});
});
_defineProperty(this, "handleShowTimecodes", e => {
const isChecked = e.target.checked;
this.setState({
showTimecodes: isChecked
});
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handleShowTimecodes',
name: 'showTimecodes',
value: isChecked
});
}
});
_defineProperty(this, "handleShowSpeakers", e => {
const isChecked = e.target.checked;
this.setState({
showSpeakers: isChecked
});
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handleShowSpeakers',
name: 'showSpeakers',
value: isChecked
});
}
});
_defineProperty(this, "handleSettingsToggle", () => {
this.setState(prevState => ({
showSettings: !prevState.showSettings
}));
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handleSettingsToggle',
name: 'showSettings',
value: !this.state.showSettings
});
}
});
_defineProperty(this, "handleShortcutsToggle", () => {
this.setState(prevState => ({
showShortcuts: !prevState.showShortcuts
}));
if (this.props.handleAnalyticsEvents !== undefined) {
this.props.handleAnalyticsEvents({
category: 'TranscriptEditor',
action: 'handleShortcutsToggle',
name: 'showShortcuts',
value: !this.state.showShortcuts
});
}
});
_defineProperty(this, "getEditorContent", exportFormat => {
return this.refs.timedTextEditor.getEditorContent(exportFormat);
});
this.state = {
currentTime: 0,
lastLocalSavedTime: '',
transcriptData: null,
isScrollIntoViewOn: false,
showSettings: false,
showShortcuts: false,
isPauseWhileTypingOn: true,
rollBackValueInSeconds: 15,
timecodeOffset: 0,
showTimecodes: true,
showSpeakers: true
};
}
static getDerivedStateFromProps(nextProps) {
if (nextProps.transcriptData !== null) {
return {
transcriptData: nextProps.transcriptData
};
}
return null;
}
componentDidUpdate(prevProps, prevState) {
if (prevState.transcriptData !== this.state.transcriptData) {
if (this.refs.timedTextEditor.isPresentInLocalStorage(this.props.mediaUrl)) {
console.log('was already present in local storage');
this.refs.timedTextEditor.loadLocalSavedData(this.props.mediaUrl);
} else {
console.log('not present in local storage');
}
}
} // eslint-disable-next-line class-methods-use-this
render() {
const mediaPlayer = React.createElement(MediaPlayer, {
fileName: this.props.fileName,
hookSeek: foo => this.setCurrentTime = foo,
hookPlayMedia: foo => this.playMedia = foo,
hookIsPlaying: foo => this.isPlaying = foo,
rollBackValueInSeconds: this.state.rollBackValueInSeconds,
timecodeOffset: this.state.timecodeOffset,
hookOnTimeUpdate: this.handleTimeUpdate,
mediaUrl: this.props.mediaUrl // ref={ 'MediaPlayer' }
,
handleAnalyticsEvents: this.props.handleAnalyticsEvents
});
const settings = React.createElement(Settings, {
handleSettingsToggle: this.handleSettingsToggle,
defaultValuePauseWhileTyping: this.state.isPauseWhileTypingOn,
defaultValueScrollSync: this.state.isScrollIntoViewOn,
defaultRollBackValueInSeconds: this.state.rollBackValueInSeconds,
timecodeOffset: this.state.timecodeOffset,
showTimecodes: this.state.showTimecodes,
showSpeakers: this.state.showSpeakers,
handlePauseWhileTyping: this.handlePauseWhileTyping,
handleIsScrollIntoViewChange: this.handleIsScrollIntoViewChange,
handleRollBackValueInSeconds: this.handleRollBackValueInSeconds,
handleSetTimecodeOffset: this.handleSetTimecodeOffset,
handleShowTimecodes: this.handleShowTimecodes,
handleShowSpeakers: this.handleShowSpeakers,
handleAnalyticsEvents: this.props.handleAnalyticsEvents
});
const shortcuts = React.createElement(Shortcuts, {
handleShortcutsToggle: this.handleShortcutsToggle
});
return React.createElement("div", {
className: style.container
}, React.createElement("header", {
className: style.header
}, this.state.showSettings ? settings : null, this.state.showShortcuts ? shortcuts : null), React.createElement("aside", {
className: style.aside
}, this.props.mediaUrl ? mediaPlayer : null), React.createElement("div", {
className: style.settingsContainer
}, React.createElement("button", {
className: style.settingsButton,
onClick: this.handleSettingsToggle
}, React.createElement(FontAwesomeIcon, {
icon: faCog
})), React.createElement("button", {
className: style.settingsButton,
onClick: this.handleShortcutsToggle
}, React.createElement(FontAwesomeIcon, {
icon: faKeyboard
}))), React.createElement("main", {
className: style.main
}, React.createElement(TimedTextEditor, {
fileName: this.props.fileName,
transcriptData: this.state.transcriptData,
timecodeOffset: this.state.timecodeOffset,
onWordClick: this.handleWordClick,
playMedia: this.handlePlayMedia,
isPlaying: this.handleIsPlaying,
currentTime: this.state.currentTime,
isEditable: this.props.isEditable,
sttJsonType: this.props.sttJsonType,
mediaUrl: this.props.mediaUrl,
isScrollIntoViewOn: this.state.isScrollIntoViewOn,
isPauseWhileTypingOn: this.state.isPauseWhileTypingOn,
showTimecodes: this.state.showTimecodes,
showSpeakers: this.state.showSpeakers,
ref: 'timedTextEditor',
handleAnalyticsEvents: this.props.handleAnalyticsEvents
})));
}
}
TranscriptEditor.propTypes = {
mediaUrl: PropTypes.string,
isEditable: PropTypes.bool,
sttJsonType: PropTypes.string,
handleAnalyticsEvents: PropTypes.func,
fileName: PropTypes.string
};
export default TranscriptEditor;