Skip to content

Layout changes accessibility #111

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

Merged
merged 32 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 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
361012c
+ Changing layout styles (using CSS grid)
Mar 12, 2019
723a49e
+ More style changes.
Mar 13, 2019
da64b38
Browser compatibility fixes
Mar 14, 2019
cf1ff2c
Accessibility improvements
Mar 14, 2019
89b5d16
Multiple layout/CSS fixes
Mar 15, 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
5 changes: 5 additions & 0 deletions src/index.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
body {
margin: 0px;
padding: 10px;
}

.container {
height: 100vh;
font-family: ReithSerif, Fallback, sans-serif;
Expand Down
158 changes: 91 additions & 67 deletions src/lib/TranscriptEditor/MediaPlayer/PlayerControls.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
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 @@ -14,7 +14,9 @@ import {
faPause,
faBackward,
faForward,
faUndo
faUndo,
faVolumeUp,
faVolumeOff
} from '@fortawesome/free-solid-svg-icons';

class PlayerControls extends React.Component {
Expand All @@ -23,14 +25,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 +45,98 @@ 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
value="seek backward by a set interval: alt r"
title="seek backward by a set interval: alt r"
className={ style.playerButton }
onClick={ this.props.rollback }>
<FontAwesomeIcon icon={ faUndo } />
</button>

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

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

<button
value="seek forward: alt l"
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 }
>
<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
value="Save"
title="Save"
className={ style.playerButton }
onClick={ this.props.handleSaveTranscript }>
<FontAwesomeIcon icon={ faSave } />
</button>

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

<button
value="Toggle Sound"
title="Toggle Sound"
className={ style.playerButton }
onClick={ this.props.handleMuteVolume }>
{ this.props.isMute ? <FontAwesomeIcon icon={ faVolumeOff } /> : <FontAwesomeIcon icon={ faVolumeUp } /> }
</button>
</div>
</div>
);
}
}

PlayerControls.propTypes = {

playMedia: PropTypes.func,
currentTime: PropTypes.string,
timecodeOffset: PropTypes.string,
Expand All @@ -123,12 +145,14 @@ PlayerControls.propTypes = {
handleMuteVolume: PropTypes.func,
duration: PropTypes.string,
isPlaying: PropTypes.bool,
isMute: PropTypes.bool,
skipBackward: PropTypes.func,
skipForward: PropTypes.func,
playbackRate: PropTypes.number,
playbackRateOptions: PropTypes.array,
setPlayBackRate: PropTypes.func,
pictureInPicture: PropTypes.func
pictureInPicture: PropTypes.func,
handleSaveTranscript: PropTypes.func
};

export default PlayerControls;
Loading