diff --git a/.eslintrc b/.eslintrc index 8e1d97d3..fc128474 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,7 +11,10 @@ "jest": true }, "rules": { + "no-unused-expressions": "error", "no-trailing-spaces": "error", + "no-nested-ternary": "error", + "space-infix-ops": "error", "indent": ["warn", 2], "arrow-spacing": ["error", { "before": true, "after": true }], "space-in-parens": [ 0, "never" ], diff --git a/README.md b/README.md index 9ce746f2..7ab27559 100644 --- a/README.md +++ b/README.md @@ -61,14 +61,18 @@ npm install @bbc/react-transcript-editor ```js import { TranscriptEditor } from '@bbc/react-transcript-editor'; - + ``` +See [`./src/index.js` demo](./src/index.js) as a more detailed example usage of the component. _Note: `fileName` it is optional but it's needed if working with user uploaded local media in the browser, to be able to save and retrieve from local storage. For instance if you are passing a blob url to `mediaUrl` using `createObjectURL` this url is randomly re-generated on every page refresh so you wouldn't be able to restore a session, as `mediaUrl` is used as the local storage key. See demo app for more detail example of this[`./src/index.js`](./src/index.js)_ diff --git a/package-lock.json b/package-lock.json index 6af22584..52fd4ac2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@bbc/react-transcript-editor", - "version": "0.2.9", + "version": "0.2.11", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -9199,7 +9199,8 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true }, "lodash.escape": { "version": "4.0.1", diff --git a/src/index.js b/src/index.js index 616d6638..681db3b2 100644 --- a/src/index.js +++ b/src/index.js @@ -19,7 +19,8 @@ class App extends React.Component { isTextEditable: true, sttType: 'bbckaldi', analyticsEvents: [], - fileName: 'Kate Darling Ted Talk' + title: 'Ted Talk Kate Kate Darling', + fileName: '' }; this.transcriptEditorRef = React.createRef(); @@ -67,7 +68,7 @@ class App extends React.Component { handleChangeLoadTranscriptJson(files) { const file = files[0]; - if (file.type ==='application/json') { + if (file.type === 'application/json') { const fr = new FileReader(); fr.onload = (evt) => { @@ -125,11 +126,18 @@ class App extends React.Component { this.setState({ analyticsEvents: [ ...this.state.analyticsEvents, event ] }); } + handleChangeTranscriptTitle = (newTitle) => { + this.setState({ + title: newTitle + }); + } + handleChangeTranscriptName = (value) => { this.setState({ fileName: value }); } render() { + return (
@@ -184,13 +192,14 @@ class App extends React.Component { /> -
- +
+ this.handleChangeTranscriptName(e.target.value) } - value={ this.state.fileName } + value={ this.state.title } + onChange={ e => this.handleChangeTranscriptTitle(e.target.value) } /> +

@@ -202,6 +211,7 @@ class App extends React.Component { isEditable={ this.state.isTextEditable } sttJsonType={ this.state.sttType } handleAnalyticsEvents={ this.handleAnalyticsEvents } + title={ this.state.title } ref={ this.transcriptEditorRef } />
diff --git a/src/index.module.css b/src/index.module.css index a2383559..030473a5 100644 --- a/src/index.module.css +++ b/src/index.module.css @@ -1,3 +1,7 @@ +body { + margin: 0px; +} + .container { height: 100vh; font-family: ReithSerif, Fallback, sans-serif; diff --git a/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.js b/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.js index abdff384..061550ed 100644 --- a/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.js +++ b/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.js @@ -1,6 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import VolumeControl from './VolumeControl'; import Select from './Select'; import style from './PlayerControls.module.css'; @@ -23,14 +22,14 @@ class PlayerControls extends React.Component { // backward or forward function // on mouseUp the interval is cleared setIntervalHelperBackward = () => { - this.props.skipBackward(); + // this.props.skipBackward(); this.interval = setInterval(() => { this.props.skipBackward(); }, 300); } setIntervalHelperForward = () => { - this.props.skipForward(); + // this.props.skipForward(); this.interval = setInterval(() => { this.props.skipForward(); }, 300); @@ -43,78 +42,85 @@ class PlayerControls extends React.Component { render() { return (
- - - - - - - - - - + + + + + + +
); } } PlayerControls.propTypes = { + playMedia: PropTypes.func, currentTime: PropTypes.string, timecodeOffset: PropTypes.string, @@ -128,7 +134,8 @@ PlayerControls.propTypes = { playbackRate: PropTypes.number, playbackRateOptions: PropTypes.array, setPlayBackRate: PropTypes.func, - pictureInPicture: PropTypes.func + pictureInPicture: PropTypes.func, + handleSaveTranscript: PropTypes.func }; export default PlayerControls; diff --git a/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.module.css b/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.module.css index c151a5ca..8f1b1af1 100644 --- a/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.module.css +++ b/src/lib/TranscriptEditor/MediaPlayer/PlayerControls.module.css @@ -1,8 +1,7 @@ @value color-darkest-grey, color-light-grey, color-labs-red from '../colours.module.css'; .playerControls { - margin: 1em; - display: flex; + margin-left: 1em; } .playerControls > * { @@ -11,7 +10,6 @@ .playerControls > *:not(:last-child) { margin-right: 0.5em; - background: color-darkest-grey; } .playerButton { @@ -20,24 +18,28 @@ padding: 0.5em; border: 0; color: white; + background: color-darkest-grey; font-size: 1em; cursor: pointer; + margin-right: 0.3rem; + margin-top: 0.3rem; } .playBackRate{ + width: 70px; border: 0; color: white; font-size: 1em; cursor: pointer; position: relative; - padding-left: 0.8em; + margin-right: 0.3rem; } .playBackRate::before{ content: '×'; position: absolute; - bottom: 11px; - left: 12px; + bottom: -2px; + left: 21px; } .playBackRate > select { @@ -47,6 +49,8 @@ outline: none; width: auto; width: 100%; + color:white; + background-color: color-darkest-grey; } .timeBox { @@ -54,6 +58,7 @@ text-align: center; line-height: 48px; padding: 0 1em; + background-color: color-darkest-grey; } .currentTime { diff --git a/src/lib/TranscriptEditor/MediaPlayer/Select.module.css b/src/lib/TranscriptEditor/MediaPlayer/Select.module.css index 049660c6..fb57f9fc 100644 --- a/src/lib/TranscriptEditor/MediaPlayer/Select.module.css +++ b/src/lib/TranscriptEditor/MediaPlayer/Select.module.css @@ -3,10 +3,10 @@ -webkit-appearance: none; -moz-appearance: none; appearance: none; - height: 20px; - width: 60px; + height: 48px!important; + width: 97px!important; border-radius: 0; - padding-left: 8px; + padding: 32px;/*<-- */ background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTguMS4xLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDEyNS4zMDQgMTI1LjMwNCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTI1LjMwNCAxMjUuMzA0OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCI+CjxnPgoJPGc+CgkJPHBvbHlnb24gcG9pbnRzPSI2Mi42NTIsMTAzLjg5NSAwLDIxLjQwOSAxMjUuMzA0LDIxLjQwOSAgICIgZmlsbD0iI0ZGRkZGRiIvPgoJPC9nPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+Cjwvc3ZnPgo=); background-repeat: no-repeat; background-position: 85% center; diff --git a/src/lib/TranscriptEditor/MediaPlayer/VideoPlayer.js b/src/lib/TranscriptEditor/MediaPlayer/VideoPlayer.js index 53680d58..e7fe4e19 100644 --- a/src/lib/TranscriptEditor/MediaPlayer/VideoPlayer.js +++ b/src/lib/TranscriptEditor/MediaPlayer/VideoPlayer.js @@ -1,8 +1,17 @@ import React from 'react'; import PropTypes from 'prop-types'; +import styles from './VideoPlayer.module.css'; class VideoPlayer extends React.Component { + + handlePlayMedia = () => { + if (this.props.videoRef.current !== null) { + return this.props.videoRef.current.paused ? this.props.videoRef.current.play() : this.props.videoRef.current.pause(); + } + }; render() { + const isDisplayed = this.props.previewIsDisplayed ? 'inline' : 'none'; + return (