Unverified Commit fec148ac authored by Sarah Otts's avatar Sarah Otts Committed by GitHub

Merge pull request #4682 from LLK/annual-report-video-spinner

Add loading spinner in Annual Report
parents b08ea58f 246798b6
......@@ -3,6 +3,8 @@ const PropTypes = require('prop-types');
const React = require('react');
const Video = require('../video/video.jsx');
const Spinner = require('../spinner/spinner.jsx');
const classNames = require('classnames');
require('./video-preview.scss');
......@@ -10,16 +12,25 @@ class VideoPreview extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
'handleShowVideo'
'handleShowVideo',
'handleVideoLoaded'
]);
this.state = {
videoOpen: false
videoOpen: false,
spinnerVisible: false
};
}
handleShowVideo () {
this.setState({videoOpen: true});
this.setState({
videoOpen: true,
spinnerVisible: true
});
}
handleVideoLoaded () {
this.setState({spinnerVisible: false});
}
render () {
......@@ -27,17 +38,26 @@ class VideoPreview extends React.Component {
<div className="video-preview">
{this.state.videoOpen ?
(
<Video
className="video"
height={this.props.videoHeight}
videoId={this.props.videoId}
width={this.props.videoWidth}
/>
<div className="spinner-video-container">
{this.state.spinnerVisible ? <Spinner className="loading-spinner" /> : null}
<Video
className="video"
height={this.props.videoHeight}
videoId={this.props.videoId}
width={this.props.videoWidth}
onVideoStart={this.handleVideoLoaded}
/>
</div>
) : (
<div
className="video-thumbnail"
onClick={this.handleShowVideo}
>
{/* Load an invisible spinner so that the image has a chance to load before it's needed */}
<img
className={classNames('loading-spinner', 'hidden-spinner')}
src="/svgs/modal/spinner-white.svg"
/>
<img
src={this.props.thumbnail}
style={{
......
......@@ -24,3 +24,32 @@
margin-top: 20px;
}
}
.loading-spinner {
margin: auto;
width: 5rem;
height: 5rem;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.hidden-spinner {
visibility: hidden;
}
.spinner-video-container {
width: 100%;
height: 100%;
position: relative;
}
.iframe-video-not-started {
visibility: hidden;
}
.iframe-video-started {
visibility: visible;
}
......@@ -4,25 +4,65 @@ const classNames = require('classnames');
require('./video.scss');
const Video = props => (
<div className={classNames('video-player', props.className)}>
<iframe
allowFullScreen
// allowFullScreen is legacy, can we start using allow='fullscreen'?
// allow="fullscreen"
frameBorder="0" // deprecated attribute
height={props.height}
scrolling="no" // deprecated attribute
src={`https://fast.wistia.net/embed/iframe/${props.videoId}?seo=false&videoFoam=true`}
title={props.title}
width={props.width}
/>
<script
async
src="https://fast.wistia.net/assets/external/E-v1.js"
/>
</div>
);
class Video extends React.Component {
constructor (props) {
super(props);
this.state = {
videoStarted: false
};
}
componentDidMount () {
/**
uses code snippets from
https://github.com/mrdavidjcole/wistia-player-react/blob/master/src/components/wistia_embed.js
**/
if (!document.getElementById('wistia_script')) {
const wistiaScript = document.createElement('script');
wistiaScript.id = 'wistia_script';
wistiaScript.type = 'text/javascript';
wistiaScript.src = 'https://fast.wistia.com/assets/external/E-v1.js';
wistiaScript.async = false;
document.body.appendChild(wistiaScript);
}
window._wq = window._wq || [];
// Use onReady in combination with the Wistia 'play' event handler so that onVideoStart()
// isn't called until the video actually starts. onReady fires before the video player is visible.
window._wq.push({
id: this.props.videoId,
onReady: video => {
video.bind('play', () => {
this.setState({videoStarted: true});
this.props.onVideoStart();
return video.unbind;
});
}
});
}
render () {
// Provide CSS classes for anything using the video component to configure what happens before and after
// the video has played for the first time. See VideoPreview for an example.
const videoStartedClass = this.state.videoStarted ? 'iframe-video-started' : 'iframe-video-not-started';
return (
<div className={classNames('video-player', this.props.className)}>
<iframe
allowFullScreen
className={classNames('wistia_embed', `wistia_async_${this.props.videoId}`, videoStartedClass)}
frameBorder="0" // deprecated attribute
height={this.props.height}
scrolling="no" // deprecated attribute
src={`https://fast.wistia.net/embed/iframe/${this.props.videoId}?seo=false&videoFoam=true`}
title={this.props.title}
width={this.props.width}
/>
</div>
);
}
}
Video.defaultProps = {
height: '225',
title: '',
......@@ -32,6 +72,7 @@ Video.defaultProps = {
Video.propTypes = {
className: PropTypes.string,
height: PropTypes.string.isRequired,
onVideoStart: PropTypes.func,
title: PropTypes.string.isRequired,
videoId: PropTypes.string.isRequired,
width: PropTypes.string.isRequired
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment