Skip to content

Layout change #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2fac517
moved ToolTip next to settings icon
Jan 3, 2019
8e365d1
layout change refactor
Jan 4, 2019
461d2bb
added option to hide and resize preview window in settings
Jan 4, 2019
cf9fbca
adjusted settings panel height
Jan 4, 2019
688cd28
initial setup for mobile responsive
Jan 4, 2019
9790671
Removed separate style file for video element
Jan 4, 2019
57458ec
made fast ward and rewind btn accessible with tab and enter
Jan 4, 2019
e9b3245
cleaned up some comments
Jan 4, 2019
69b1e24
reabsed with master
Feb 2, 2019
eb53feb
Merge branch 'help-box-spike' of github.com:bbc/react-transcript-edit…
Feb 2, 2019
89a06ad
Adding some css to player control
Feb 2, 2019
ee20146
adjusted Select
Feb 19, 2019
6e53d73
Merge branch 'master' into layout-change
pietrop Feb 19, 2019
2c6a9dd
UI Tweaks
Feb 19, 2019
4e10bbd
Merge branch 'layout-change' of github.com:bbc/react-transcript-edito…
Feb 19, 2019
9c05aae
Revert "UI Tweaks"
Feb 19, 2019
ccbe700
player control fix
Feb 19, 2019
8f45a2e
fixed unsuccesful merge
Feb 19, 2019
b4ab381
moved title outside of player control
Feb 19, 2019
37de921
Removed Volume
Feb 19, 2019
8af3b78
first pass at making it responsive
Feb 19, 2019
5233619
first pass at making speakers and timecodes responsive in Timed Text …
Feb 19, 2019
a4f0ee7
fixed CSS for ipad :crossed_fingers:
Feb 20, 2019
b42d1c2
responsive text in timed text editor for ipad and mobile view
Feb 20, 2019
9b1e659
cleared out filename title overlap + updated README
Feb 22, 2019
61f8d0c
mend
Feb 22, 2019
b37d1d5
various fixes
Mar 1, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -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" ],
Expand Down
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,18 @@ npm install @bbc/react-transcript-editor
```js
import { TranscriptEditor } from '@bbc/react-transcript-editor';

<TranscriptEditor
transcriptData=// Transcript json
mediaUrl=// string url to media file - audio or video
isEditable={true}// se to true if you want to be able to edit the text
sttJsonType={ 'bbckaldi' }// the type of STT Json transcript supported.
fileName={ this.state.fileName }// optional*
/>
<TranscriptEditor
transcriptData=// Transcript json
mediaUrl=// string url to media file - audio or video
isEditable={true}// se to true if you want to be able to edit the text
sttJsonType={ 'bbckaldi' }// the type of STT Json transcript supported.
handleAnalyticsEvents={ this.handleAnalyticsEvents } // optional - if you want to collect analytics events.
fileName=// optional - used for saving and retrieving local storage blob files
title=// optional - defaults to ''
ref= // optional - if you want to have access to internal functions such as retrieving content from the editor. eg to save to a server/db.
/>
```
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)_

Expand Down
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 16 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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 (
<div className={ style.container }>
<span className={ style.title }>
Expand Down Expand Up @@ -184,13 +192,14 @@ class App extends React.Component {
/>
<span className={ style.slider }></span>
</label>
<br />
<label>Transcript Name</label>
<br/>
<label>Optional Transcript Name</label>
<input
type="text"
onChange={ e => this.handleChangeTranscriptName(e.target.value) }
value={ this.state.fileName }
value={ this.state.title }
onChange={ e => this.handleChangeTranscriptTitle(e.target.value) }
/>

<br />
<button onClick={ () => this.clearLocalStorage() }>Clear Local Storage</button>
<hr/>
Expand All @@ -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 }
/>
<hr/>
Expand Down
4 changes: 4 additions & 0 deletions src/index.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
body {
margin: 0px;
}

.container {
height: 100vh;
font-family: ReithSerif, Fallback, sans-serif;
Expand Down
139 changes: 73 additions & 66 deletions src/lib/TranscriptEditor/MediaPlayer/PlayerControls.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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);
Expand All @@ -43,78 +42,85 @@ class PlayerControls extends React.Component {
render() {
return (
<div className={ style.playerControls }>
<button
title="Rollback"
className={ style.playerButton }
onClick={ this.props.rollback }>
<FontAwesomeIcon icon={ faUndo } />
</button>

<button
title="Rewind"
className={ style.playerButton }
onMouseDown={ this.setIntervalHelperBackward }
onMouseUp={ this.clearIntervalHelper }>
<FontAwesomeIcon icon={ faBackward } />

</button>

<button
title="Play"
className={ style.playerButton }
onClick={ this.props.playMedia }>
{this.props.isPlaying ? <FontAwesomeIcon icon={ faPause } /> : <FontAwesomeIcon icon={ faPlay } />}
</button>

<button
title="Forward"
className={ style.playerButton }
onMouseDown={ this.setIntervalHelperForward }
onMouseUp={ this.clearIntervalHelper }>
<FontAwesomeIcon icon={ faForward } />
</button>

<span className={ style.playBackRate }>
<Select
title="Playback rate"
options={ this.props.playbackRateOptions }
currentValue={ this.props.playbackRate.toString() }
name={ 'playbackRate' }
handleChange={ this.props.setPlayBackRate } />
</span>

<div className={ style.timeBox }>
<span title="Current time" className={ style.currentTime }
onClick={ this.props.promptSetCurrentTime }
>{ this.props.currentTime }</span>
<span
title="Current time: alt t"
className={ style.currentTime }
onClick={ this.props.promptSetCurrentTime }>
{ this.props.currentTime }</span>
<span className={ style.separator }>|</span>
<span title="Clip duration" className={ style.duration }>{this.props.duration}</span>
<span
title="Clip duration"
className={ style.duration }>
{this.props.duration}</span>
</div>

<div className={ style.btnsGroup }>
<button
title="seek backward by a set interval: alt r"
className={ style.playerButton }
onClick={ this.props.rollback }>
<FontAwesomeIcon icon={ faUndo } />
</button>

<button
title="seek backward: alt j"
className={ style.playerButton }
onMouseDown={ this.setIntervalHelperBackward }
onMouseUp={ this.clearIntervalHelper }
onClick={ () => {this.props.skipBackward(); } }>
<FontAwesomeIcon icon={ faBackward } />
</button>

<button
title="Play/Pause: alt k"
className={ style.playerButton }
onClick={ this.props.playMedia }>
{this.props.isPlaying ? <FontAwesomeIcon icon={ faPause } /> : <FontAwesomeIcon icon={ faPlay } />}
</button>

<button
title="seek forward: alt l"
className={ style.playerButton }
onMouseDown={ this.setIntervalHelperForward }
onMouseUp={ this.clearIntervalHelper }
onClick={ () => {this.props.skipForward(); } }>
<FontAwesomeIcon icon={ faForward } />
</button>
</div>

<button
title="Save"
className={ style.playerButton }
onClick={ this.props.handleSaveTranscript }>
<FontAwesomeIcon icon={ faSave } />
</button>

<button
title="Picture-in-picture"
className={ style.playerButton }
onClick={ this.props.pictureInPicture }
>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatting for closing elements > on the last line of a property / new line seems to change a lot

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, preference? should it just be up on the previous line?

<FontAwesomeIcon icon={ faTv } />
</button>

<VolumeControl
handleMuteVolume={ this.props.handleMuteVolume }
/>
<div className={ style.btnsGroup }>
<span className={ style.playBackRate }
title="Playback rate: alt - & alt + ">
<Select
options={ this.props.playbackRateOptions }
currentValue={ this.props.playbackRate.toString() }
name={ 'playbackRate' }
handleChange={ this.props.setPlayBackRate } />
</span>

<button
title="Save"
className={ style.playerButton }
onClick={ this.props.handleSaveTranscript }>
<FontAwesomeIcon icon={ faSave } />
</button>

<button
title="Picture-in-picture"
className={ style.playerButton }
onClick={ this.props.pictureInPicture }>
<FontAwesomeIcon icon={ faTv } />
</button>

</div>
</div>
);
}
}

PlayerControls.propTypes = {

playMedia: PropTypes.func,
currentTime: PropTypes.string,
timecodeOffset: PropTypes.string,
Expand All @@ -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;
17 changes: 11 additions & 6 deletions src/lib/TranscriptEditor/MediaPlayer/PlayerControls.module.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
@value color-darkest-grey, color-light-grey, color-labs-red from '../colours.module.css';

.playerControls {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section needs rethinking. The player controls and the grouped buttons within could probably be centred and responsive to narrow screens with flexbox and + wrap? Not sure how fiddly that'll be.

I find here the Timebox is too far away from the player + progress bar. Also the huge grid of buttons is overwhelming. An alternative for mobile could be player controls + timebox stuck to the bottom of the screen?

Probably needs more UX input rather than winging it. We're undoing a lot of stuff from the first round of UX in this PR so let's not get carried away 😛

screen shot 2019-02-21 at 14 36 16

Also, any idea why the MediaPlayer size doesn't update properly a lot of the time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we can rethink it, I reckon we can just do a first pass in this PR and then optimise later. Not good to try and do everything at once.

margin: 1em;
display: flex;
margin-left: 1em;
}

.playerControls > * {
Expand All @@ -11,7 +10,6 @@

.playerControls > *:not(:last-child) {
margin-right: 0.5em;
background: color-darkest-grey;
}

.playerButton {
Expand All @@ -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 {
Expand All @@ -47,13 +49,16 @@
outline: none;
width: auto;
width: 100%;
color:white;
background-color: color-darkest-grey;
}

.timeBox {
display: inline-block;
text-align: center;
line-height: 48px;
padding: 0 1em;
background-color: color-darkest-grey;
}

.currentTime {
Expand Down
6 changes: 3 additions & 3 deletions src/lib/TranscriptEditor/MediaPlayer/Select.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading